pyantz.api package#
Subpackages#
Submodules#
pyantz.api.auth module#
Optional token authentication of the api.
- require_token(authorization: str | None = None)[source]#
Reject requests without
Authorization: Bearer <token>, if a token is set.The token is read from PYANTZ_API_TOKEN on each request. Without one, every request is let through (the servers only listen on localhost in that case).
- Parameters:
authorization (
str|None) – the request’sAuthorizationheader, if any.- Return type:
None- Returns:
None.
- Raises:
HTTPException – 401 if a token is set and the header doesn’t carry it.
Example
import os from fastapi import HTTPException from pyantz.api.auth import require_token os.environ["PYANTZ_API_TOKEN"] = "secret" try: require_token("Bearer secret") # accepted require_token("Bearer guess") except HTTPException as exc: print(exc.status_code) finally: del os.environ["PYANTZ_API_TOKEN"]
401
pyantz.api.backend module#
Where the application is defined.
app is the api application, served by pyantz-prod (and, reloading on
changes, pyantz-dev).
- app = <fastapi.applications.FastAPI object>#
The api application, configured from the environment when imported.
- Parameters:
scope (MutableMapping[str, Any])
receive (Callable[[], Awaitable[MutableMapping[str, Any]]])
send (Callable[[MutableMapping[str, Any]], Awaitable[None]])
- Return type:
None
- create_app(frontend_dir: Path | None = None)[source]#
Create the application, reading its settings from the environment.
The cors origins are read from PYANTZ_CORS_ORIGINS, and the built web ui is served at
/if PYANTZ_FRONTEND_DIR names it.- Parameters:
frontend_dir (
Path|None) – the built web ui to serve at/, instead of the one which PYANTZ_FRONTEND_DIR names- Returns:
the application, with every endpoint under
/api/v1.0requiring the token (if one is set).- Return type:
FastAPI- Raises:
ValueError – if PYANTZ_FRONTEND_DIR is not a directory with an index.html
Example
from pyantz.api.backend import create_app paths = create_app().openapi()["paths"] print("/api/v1.0/jobs/get_all_jobs" in paths)
True
pyantz.api.dev_server module#
Primary server to run.
pyantz.api.dump_schemas module#
Dump the description and parameter schema of every job as json.
The frontend tests use the dump as a fixture, so they see the schemas as the
api serves them. Run python -m pyantz.api.dump_schemas [FILE] (standard output
without a file) to regenerate it.
- dump_schemas()[source]#
Get the description and schema of each job, by job name and sorted by it.
- Parameters:
None.
- Returns:
for each registered job, its
descriptionand thejson_schemaof its parameters.- Return type:
dict[str,dict[str,object]]- Raises:
fastapi.HTTPException – if a registered job has no parameters model.
Example
from pyantz.api.dump_schemas import dump_schemas copy = dump_schemas()["pyantz.jobs.files.simple.copy"] print(copy["description"], sorted(copy["json_schema"]["properties"]))
Copy from src to destination. ['dst', 'src']
pyantz.api.frontend_server module#
Serve the api and the built web ui from one server (pyantz-frontend).
- NOT_INSTALLED = "The web ui is not installed: install it with `pip install 'pyantz[frontend]'`"#
Error message when the
frontendfeature isn’t installed.
- get_bundled_frontend_dir()[source]#
Get the directory with the web ui which comes with
pyantz[frontend].- Parameters:
None.
- Returns:
the directory of the built web ui.
- Return type:
Path- Raises:
ValueError – if the frontend feature is not installed, or its ui is not built
- start_frontend_server()[source]#
Start the api and serve the web ui at
/.The ui is the one installed with
pyantz[frontend], unless PYANTZ_FRONTEND_DIR names another build. Entry point ofpyantz-frontend.- Parameters:
None.
- Return type:
None- Returns:
None.
- Raises:
SystemExit – if the settings are invalid or the web ui isn’t available.
pyantz.api.settings module#
Settings of the api servers, read from the environment when a server starts.
- API_TOKEN_VARIABLE = 'PYANTZ_API_TOKEN'#
Environment variable with the token clients must send, if any.
- CORS_ORIGINS_VARIABLE = 'PYANTZ_CORS_ORIGINS'#
Environment variable with the comma separated origins allowed by CORS.
- DEFAULT_HOST = '127.0.0.1'#
Address the server listens on by default (only this machine).
- DEFAULT_PORT = 8000#
Port the server listens on by default.
- FRONTEND_DIR_VARIABLE = 'PYANTZ_FRONTEND_DIR'#
Environment variable with the directory of a built web ui to serve.
- HOST_VARIABLE = 'PYANTZ_HOST'#
Environment variable with the address the api server listens on.
- LOCAL_HOSTS = frozenset({'127.0.0.1', '::1', 'localhost'})#
Addresses which only this machine can reach.
- MAX_PORT = 65535#
Largest valid port.
- PORT_VARIABLE = 'PYANTZ_PORT'#
Environment variable with the port the api server listens on.
- RUNS_DIR_VARIABLE = 'PYANTZ_RUNS_DIR'#
Environment variable with the directory holding the runs’ directories.
- class Settings(*, host: str = '127.0.0.1', port: int = 8000)[source]#
Bases:
BaseModelWhere the api server listens.
- Parameters:
host (str)
port (int)
- _abc_impl = <_abc._abc_data object>#
- host: str#
Address to listen on.
- port: int#
Port to listen on.
- check_safe_to_bind(settings: Settings)[source]#
Refuse to listen on a non-local address when no token protects the api.
- Parameters:
settings (
Settings) – where the server is to listen.- Return type:
None- Returns:
None.
- Raises:
ValueError – if the host is reachable from other machines and there is no PYANTZ_API_TOKEN
Example
from pyantz.api.settings import Settings, check_safe_to_bind check_safe_to_bind(Settings(host="localhost")) # fine try: check_safe_to_bind(Settings(host="0.0.0.0")) except ValueError: print("refused")
refused
- get_api_token()[source]#
Get the token which clients must send, if PYANTZ_API_TOKEN is set.
- Parameters:
None.
- Returns:
the token, or None if the variable isn’t set or is empty.
- Return type:
str|None- Raises:
None. –
- get_cors_origins()[source]#
Get the origins allowed to call the api from PYANTZ_CORS_ORIGINS.
The variable holds comma separated origins, e.g.
http://localhost:5173.- Parameters:
None.
- Returns:
the origins; empty if the variable isn’t set.
- Return type:
list[str]- Raises:
None. –
Example
import os from pyantz.api.settings import get_cors_origins os.environ["PYANTZ_CORS_ORIGINS"] = "http://localhost:5173, ,http://a.b" try: print(get_cors_origins()) finally: del os.environ["PYANTZ_CORS_ORIGINS"]
['http://localhost:5173', 'http://a.b']
- get_frontend_dir()[source]#
Get the directory with the built web ui, if PYANTZ_FRONTEND_DIR is set.
Build it with
npm run buildinfrontend/pyantz, which makesdist. The server serves it at/next to the api, without asking for the token: the page has to load to ask the user for it.- Parameters:
None.
- Returns:
the directory, or None if the variable isn’t set.
- Return type:
Path|None- Raises:
None. –
- get_runs_dir()[source]#
Get the directory holding one working directory per run.
- Parameters:
None.
- Returns:
PYANTZ_RUNS_DIR if set, otherwise
pyantz-runsin the system’s temporary directory.- Return type:
Path- Raises:
None. –
- get_settings()[source]#
Read the settings from PYANTZ_HOST and PYANTZ_PORT.
- Parameters:
None.
- Returns:
the settings, with defaults for the variables which aren’t set.
- Return type:
- Raises:
ValueError – if a value is invalid; the message names the variable
Example
import os from pyantz.api.settings import get_settings os.environ["PYANTZ_PORT"] = "70000" try: get_settings() except ValueError as exc: print(str(exc).split(":")[1].strip()) finally: del os.environ["PYANTZ_PORT"]
PYANTZ_PORT='70000'
Module contents#
Simple REST API to allow a user to edit a config in a frontend.