The apiserver is micro-service framework for python.
It is designed for:
Publishable interface types:
Supported external resources:
Apiserver works on following environment:
Service Name:
<service-name>
MUST use chain-case (separated with hyphen “-”).example-v2
. If it is first release, major version suffix MUST NOT append.URL of JSON-RPC service:
http://<service-name>.internal.yuuki0xff.jp/<scope>/json-rpc/v2.0
(Recommended)http://<service-name>.internal.yuuki0xff.jp/json-rpc/v2.0
https://<service-name>.yuuki0xff.jp/<scope>/json-rpc/v2.0
(Experimental)URL of gRPC service:
<service-name>_grpc.internal.yuuki0xff.jp:5250
(Experimental)<service-name>_grpc.yuuki0xff.jp:5250
(Experimental)TODO: システムがHTTP/2に対応したら、ポート番号を443に変更。
SQLITE_DB
- Path to sqlite database file.MYSQL_SERVER
- (optional) Host name of MySQL server (default: mysql-server).MYSQL_PORT
- (optional) Port number of MySQL server (default: 3306).MYSQL_USER_PASSWD_FILE
- specify the docker secret file path. If you didn’t want to use docker secret, you MUST specify the MYSQL_USER
and MYSQL_PASSWD
.MYSQL_DB
- Database name.MYSQL_NO_SSL
- If you didn’t want to use SSL, you MUST specify the non-empty value.MYSQL_SSL_CA_FILE
- CA public key file path.MYSQL_SSL_KEY_FILE
- (optional) Private key file path (for client authentication).MYSQL_SSL_CERT_FILE
- (optional) Cert file path (for client authentication).api.Rpc(app_name: str)
- Returns RPC server object.api.Rpc.__call__(func: Callable)
- Define a remote callable function.api.rpc.<app_name>
- Get rpc client for app_name
.api.rpc.<app_name>.<function_name>()
- Invoke the remote function.api.rpc.<app_name>.<scope_name>.<function_name>()
- Invoke the remote function with specified scope.# RPC Server
import api
app = api.Rpc('example-app')
groups = {'foo', 'bar', 'baz'}
@app
def get_groups():
return list(groups)
@app
def create_group(group: str):
return groups.add(group)
# RPC Client
import api
with api.RetryPolicy.disable:
groups = api.rpc.example_app.get_groups()
print(groups)
api.rest
- Default RESTful API client.api.Rest.endpoint(url)
- Creates new client for the specified url.api.Rest.service(name)
- Creates new client for the specified service.api.Rest.add(headers, cookies)
api.Rest.remove(headers, cookies)
api.Rest.get(path, params)
api.Rest.post(path, params, json)
api.Rest.put(path, params, json)
api.Rest.delete(path, params)
api.Rest.head(path, params)
api.Rest.options(path, params)
api.rdb
- Default RDB configuration.api.Rdb.session()
- Create new session. (SHOULD NOT USE)api.Rdb.__entry__()
- Create new session and bind it. (recommended)api.rdbs
- Context-local RDB session. (recommended)api.RdbSession.query(select, args)
- Run the select query, and returns result set.api.RdbSession.execute(query, args)
- Run the query.api.RdbSession.executemany(query, args)
- Merge multiple queries to a query if possible, and run it.api.RdbSession.commit()
api.RdbSession.rollback()
api.RdbSession.__entry__()
- Create new context and bind it.import api
# Use context-local session.
users = api.rdbs.query('SELECT user_id FROM users')
api.rdbs.execute('UPDATE users SET disabled=1')
api.rdbs.commit()
# Use new session with context-manager.
with api.rdb as s:
users = s.query('SELECT user_id FROM users')
s.execute('UPDATE users SET disabled=1')
s.commit()
api._local
- ContextLocal object.api._context.Context.__enter__()
- Enter new context.api._context.ContextLocal
- Manage the context frame stack.api._context.ContextLocal.frame
- Current context. If context is not set, it returns default context frame.api._context.ContextLocal.push()
- Push the current context frame onto the stack.api._context.ContextLocal.pop()
- Pop the previous context frame from the stack.api._context.ContextFrame
import api
from api._context import Context
print(api._local.frame.name) # global
with Context(name='inside'):
print(api._local.frame.name) # inside
print(api._local.frame.name) # global
api.AC(default)
- Create role-based access controller.api.AC.allow(role)
api.AC.deny(role)
api.BasicAuth(user, password, domain)
# Server
import api
app = api.Rpc('example')
ac = api.AC(default='deny')
@app
@ac.allow(role='admin')
def register_user(name): pass
# Client
import api
with api.BasicAuth('god', 'password', domain='*.yuuki0xff.jp'):
api.rpc.example.register_user('bob')
api.retry_policy.run(resource_type: str, func: Callable)
- Run an function with current retry policy.api.RetryPolicy(resource_type='all', times=0, wait=0)
- Define an retry policy.api.RetryPolicy.__entry__()
- Enable new context and enable this policy.api.RetryPolicy.run(resource_type: str, func: Callable)
- Run the retriable function.api.RetryPolicy.disable
- Disable all retry policy. It’s a special retry policy.api.RetryPolicy.disable.__enter__()
- Enter new context and disable all policies.import api
def job(): pass
api.retry_policies.run('foo', job) # Use default policy.
with api.RetryPolicy(times=20, wait=3): # Policy A
with api.RetryPolicy(resource_type='foo', times=5, wait=1): # Policy B
api.retry_policies.run('foo', job) # Use the Policy B.
with api.RetryPolicy.disable:
api.retry_policies.run(job) # Run once. Never try again.
api.retry_policies.run('foo', job) # Use the Policy A.