ozon-env-api exposes the FastAPI REST sidecar required by OzonOrmRest in
ozon-env 4.0.0. It does not reimplement ORM behavior: requests are
translated to the existing DB-backed ozon-env model methods.
The app reads the same DB settings used by ozon-env:
APP_CODEMONGO_USERMONGO_PASSMONGO_URLMONGO_DBMONGO_REPLICAMODELS_FOLDER
Additional sidecar settings:
OZON_API_PREFIX, default/v2OZON_API_REQUIRE_AUTH, defaulttrueOZON_AUTH_MODE,sessionorkeycloakOZON_OAUTH_URL, Keycloak token endpointOZON_CLIENT_ID, expected M2M client idOZON_TOKEN_AUDIENCE, optional JWT audience checkOZON_KEYCLOAK_JWKS_URL, optional explicit JWKS URLOZON_KEYCLOAK_ISSUER, optional explicit issuerOZON_BOOTSTRAP_USER_FILE, defaultbase_data/user.jsonOZON_ENV_UPOLOAD_FOLDER, attachment destination folderOZON_ENV_UPLOAD_FOLDER, supported alias for the same folderOZON_ENV_TMP_UPLOAD_FOLDER, temporary staging folder, default/tmpOZON_API_HOST, default0.0.0.0OZON_API_PORT, default8000
Run:
ozon-env-apiASGI factory:
uvicorn ozon_env_api.app:create_app --factoryFastAPI apps can also include only the sidecar router:
from fastapi import FastAPI
from ozon_env_api import OzonEnvApiService, OzonEnvApiSettings, create_router
settings = OzonEnvApiSettings.from_env()
service = OzonEnvApiService(settings=settings)
app = FastAPI()
app.include_router(create_router(settings=settings, service=service))Bootstrap:
GET /v2/collections_namesGET /v2/init_settings/{app_code}
CRUD/query operations. Each accepts POST JSON and should receive
Authorization: Bearer <token>. REST worker calls can also pass
job_token: jctx_..., matching the ozon-env sidecar handler contract:
/v2/count/v2/load/v2/find/v2/aggregate/v2/insert/v2/upsert/v2/update/v2/remove/v2/remove_all/v2/distinct/v2/search_all_distinct
The upload endpoint accepts multipart file fields, writes each file first below
OZON_ENV_TMP_UPLOAD_FOLDER using {data_model}/{rec_name}/{filename}, then
moves it below OZON_ENV_UPOLOAD_FOLDER. It returns rows shaped for FormIO
upload values:
{
"data": [
{
"filename": "document.pdf",
"content_type": "application/pdf",
"file_path": "request/REQ-1",
"url": "/request/REQ-1/document.pdf",
"key": "REQ-1"
}
]
}For REST/JSON record persistence with attachments, call insert, update, or
upsert with base64 file objects inside the record field:
{
"model": "request",
"record": {
"rec_name": "REQ-1",
"uploadBase64": [
{
"filename": "document.pdf",
"content_type": "application/pdf",
"content": "<base64>"
}
]
}
}The accepted base64 keys are content, base64, data, or a url that starts
with data:...;base64,. Multipart remains supported for compatibility:
formObj contains the JSON operation payload and each file field name is the
record field key, for example uploadBase64.
The sidecar writes each file to the temporary folder, injects the attachment row
into record[field_key], persists the record through ozon-env, and only then
moves the file into OZON_ENV_UPOLOAD_FOLDER. This keeps the stored record and
the file coordinates aligned for later download.
Payloads match OzonOrmRest calls from ozonenv/core/OzonOrm.py.
For Keycloak M2M calls, wrap the ORM payload:
{
"action_user_uid": "admin",
"data": {"model": "user"}
}The bearer token is verified against Keycloak JWKS. For job_token calls,
ozon-env validates the persisted jobcontext and resolves the current user.
For direct M2M calls without job_token, the sidecar resolves action_user_uid
from the user model and marks that User as the API user_session.
Generate a local bootstrap user file:
scripts/create_base_user.shAt startup, if the user table is empty and OZON_BOOTSTRAP_USER_FILE exists,
records from that JSON file are inserted.