From faac53ebe3ae2bac2cfc58d3edae3588a8858f02 Mon Sep 17 00:00:00 2001 From: octodog Date: Fri, 10 Jan 2025 16:30:13 +0900 Subject: [PATCH] chore: Manage the api spec file in the docs directory (#2143) (#3425) Co-authored-by: Sion Kang --- .github/labeler.yml | 2 - .github/workflows/update-api-schema.yml | 20 +- .readthedocs.yaml | 2 - docs/README.md | 9 +- .../manager/graphql-reference}/schema.graphql | 0 docs/manager/rest-reference/openapi.json | 8407 +++++++++++++++++ src/ai/backend/manager/cli/api.py | 26 +- src/ai/backend/manager/openapi.py | 4 +- 8 files changed, 8430 insertions(+), 40 deletions(-) rename {src/ai/backend/manager/api => docs/manager/graphql-reference}/schema.graphql (100%) create mode 100644 docs/manager/rest-reference/openapi.json diff --git a/.github/labeler.yml b/.github/labeler.yml index 42cec0fb8e..154799455c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -7,8 +7,6 @@ area:docs: - changed-files: - any-glob-to-any-file: - 'docs/**/*' - - 'src/ai/backend/manager/api/**/*.py' - - 'src/ai/backend/manager/models/gql.py' comp:storage-proxy: - changed-files: diff --git a/.github/workflows/update-api-schema.yml b/.github/workflows/update-api-schema.yml index 1f9eec3d67..0f990e0776 100644 --- a/.github/workflows/update-api-schema.yml +++ b/.github/workflows/update-api-schema.yml @@ -4,9 +4,10 @@ on: pull_request: paths: - 'src/ai/backend/manager/models/**' + - 'src/ai/backend/manager/api/**' jobs: - graphql-updated: + api-updated: runs-on: ubuntu-latest permissions: contents: write @@ -52,27 +53,28 @@ jobs: cache-lmdb-store: 'true' - name: Pants export run: pants export --resolve=python-default - - name: Create GraphQL schema dump + - name: Create api schema dump run: | - ./backend.ai mgr api dump-gql-schema --output src/ai/backend/manager/api/schema.graphql - - name: Extract the author information - id: get_author_info + ./backend.ai mgr api dump-gql-schema --output docs/manager/graphql-reference/schema.graphql + ./backend.ai mgr api dump-openapi --output docs/manager/rest-reference/openapi.json + - name: Make commit message for changing change log file run: | + git add docs/manager/graphql-reference/schema.graphql + git add docs/manager/rest-reference/openapi.json author_name=$(git show -q --pretty='format:%an') author_email=$(git show -q --pretty='format:%ae') git config user.email "$author_email" git config user.name "$author_name" if [ -n "$(git diff --staged)" ]; then git commit \ - -m "chore: update GraphQL schema dump" \ + -m "chore: update api schema dump" \ --author="$author_name <$author_email>" \ --trailer "Co-authored-by: octodog " git push fi graphql-inspector: - needs: graphql-updated - name: Check Schema + needs: api-updated runs-on: ubuntu-latest permissions: contents: read @@ -82,6 +84,6 @@ jobs: - uses: actions/checkout@v4 - uses: kamilkisiela/graphql-inspector@release-1717403590269 with: - schema: '${{ github.base_ref }}:src/ai/backend/manager/api/schema.graphql' + schema: '${{ github.base_ref }}:docs/manager/graphql-reference/schema.graphql' rules: | gql-inspector-checker.js diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 455b4d9922..ea8278bd0e 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -16,8 +16,6 @@ build: exit 183; fi pre_build: - # Auto-generate REST API reference - - PYTHONPATH="src" python -m ai.backend.manager.openapi -o docs/manager/rest-reference/openapi.json - | if [ "$READTHEDOCS_VERSION_TYPE" != "external" ]; then diff --git a/docs/README.md b/docs/README.md index 01dd8f98ea..95ac18bdd4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,11 +26,16 @@ $ pip install -U -r requirements.txt ## Building API Reference JSON file +REST API ```console $ ./backend.ai mgr api dump-openapi --output docs/manager/rest-reference/openapi.json ``` +Graphql API +```console +$ ./backend.ai mgr api dump-graphql-schema --output docs/manager/graphql-reference/schema.graphql +``` This script must be executed on behalf of the virtual environment managed by pants, not by the venv for the sphinx. -Generated OpenAPI JSON file will be located at under `manager/rest-reference/openapi.json`. +Generated OpenAPI file will be located at under `manager/rest-reference/openapi.json` and `manager/graphql-reference/schema.graphql`. ## Building HTML document @@ -166,7 +171,7 @@ to interact and inspect the Backend.AI Manager's GraphQL API. 3. From your web browser, navigate to `/spec/openapi` under proxy server set up at step 2. Enjoy auto-completion and schema introspection of Backend.AI admin API! -### Interactive GraphQL browser +### Interactive GraphQL API browser You may use [GraphiQL](https://github.com/graphql/graphiql/tree/main/packages/graphiql#graphiql) to interact and inspect the Backend.AI Manager's GraphQL API. diff --git a/src/ai/backend/manager/api/schema.graphql b/docs/manager/graphql-reference/schema.graphql similarity index 100% rename from src/ai/backend/manager/api/schema.graphql rename to docs/manager/graphql-reference/schema.graphql diff --git a/docs/manager/rest-reference/openapi.json b/docs/manager/rest-reference/openapi.json new file mode 100644 index 0000000000..c959f8e80b --- /dev/null +++ b/docs/manager/rest-reference/openapi.json @@ -0,0 +1,8407 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Backend.AI Manager API", + "description": "Backend.AI Manager REST API specification", + "version": "24.09.5", + "contact": { + "name": "Lablup Inc.", + "url": "https://docs.backend.ai", + "email": "contect@lablup.com" + } + }, + "components": { + "securitySchemes": { + "TokenAuth": { + "type": "ApiKey", + "in": "header", + "name": "Authorization: BackendAI", + "description": "Check https://docs.backend.ai/en/latest/manager/common-api/auth.html for more information" + } + }, + "schemas": { + "VFolderPermission": { + "description": "Permissions for a virtual folder given to a specific access key.\nRW_DELETE includes READ_WRITE and READ_WRITE includes READ_ONLY.", + "enum": [ + "ro", + "rw", + "wd", + "wd" + ], + "title": "VFolderPermission", + "type": "string" + }, + "VFolderUsageMode": { + "description": "Usage mode of virtual folder.\n\nGENERAL: normal virtual folder\nMODEL: virtual folder which provides shared models\nDATA: virtual folder which provides shared data", + "enum": [ + "general", + "model", + "data" + ], + "title": "VFolderUsageMode", + "type": "string" + }, + "CreateRequestModel": { + "properties": { + "name": { + "description": "Name of the vfolder", + "title": "Name", + "type": "string" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Host" + }, + "usage_mode": { + "$ref": "#/components/schemas/VFolderUsageMode", + "default": "general" + }, + "permission": { + "$ref": "#/components/schemas/VFolderPermission", + "default": "rw" + }, + "unmanaged_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unmanaged Path" + }, + "group": { + "anyOf": [ + { + "type": "string" + }, + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Group" + }, + "cloneable": { + "default": false, + "title": "Cloneable", + "type": "boolean" + } + }, + "required": [ + "name" + ], + "title": "CreateRequestModel", + "type": "object" + }, + "DeleteRequestModel": { + "properties": { + "vfolder_id": { + "description": "Target vfolder id to soft-delete, to go to trash bin", + "format": "uuid", + "title": "Vfolder Id", + "type": "string" + } + }, + "required": [ + "vfolder_id" + ], + "title": "DeleteRequestModel", + "type": "object" + }, + "IDRequestModel": { + "properties": { + "vfolder_name": { + "description": "Target vfolder name", + "title": "Vfolder Name", + "type": "string" + } + }, + "required": [ + "vfolder_name" + ], + "title": "IDRequestModel", + "type": "object" + }, + "CompactVFolderInfoModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "id": { + "description": "Unique ID referencing the vfolder.", + "format": "uuid", + "title": "Id", + "type": "string" + }, + "name": { + "description": "Name of the vfolder.", + "title": "Name", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "title": "CompactVFolderInfoModel", + "type": "object" + }, + "RenameRequestModel": { + "properties": { + "new_name": { + "description": "Name of the vfolder", + "title": "New Name", + "type": "string" + } + }, + "required": [ + "new_name" + ], + "title": "RenameRequestModel", + "type": "object" + }, + "PurgeRequestModel": { + "properties": { + "vfolder_id": { + "description": "Target vfolder id to purge, permanently remove from DB", + "format": "uuid", + "title": "Vfolder Id", + "type": "string" + } + }, + "required": [ + "vfolder_id" + ], + "title": "PurgeRequestModel", + "type": "object" + }, + "RestoreRequestModel": { + "properties": { + "vfolder_id": { + "description": "Target vfolder id to restore", + "format": "uuid", + "title": "Vfolder Id", + "type": "string" + } + }, + "required": [ + "vfolder_id" + ], + "title": "RestoreRequestModel", + "type": "object" + }, + "DeleteFromTrashRequestModel": { + "properties": { + "vfolder_id": { + "description": "Target vfolder id to hard-delete, permanently remove from storage", + "format": "uuid", + "title": "Vfolder Id", + "type": "string" + } + }, + "required": [ + "vfolder_id" + ], + "title": "DeleteFromTrashRequestModel", + "type": "object" + }, + "UserPermMapping": { + "properties": { + "user": { + "description": "Target user id to update sharing status.", + "format": "uuid", + "title": "User", + "type": "string" + }, + "perm": { + "anyOf": [ + { + "$ref": "#/components/schemas/VFolderPermission" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Permission to update. Delete the sharing between vfolder and user if this value is null. Should be one of ['ro', 'rw', 'wd']. Default value is null." + } + }, + "required": [ + "user" + ], + "title": "UserPermMapping", + "type": "object" + }, + "UpdateSharedRequestModel": { + "properties": { + "vfolder_id": { + "description": "Target vfolder id to update sharing status.", + "format": "uuid", + "title": "Vfolder Id", + "type": "string" + }, + "user_perm": { + "description": "A list of user and permission mappings.", + "items": { + "$ref": "#/components/schemas/UserPermMapping" + }, + "title": "User Perm", + "type": "array" + } + }, + "required": [ + "vfolder_id", + "user_perm" + ], + "title": "UpdateSharedRequestModel", + "type": "object" + }, + "ListServeRequestModel": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + } + }, + "title": "ListServeRequestModel", + "type": "object" + }, + "CompactServeInfoModel": { + "properties": { + "id": { + "description": "Unique ID referencing the model service.", + "format": "uuid", + "title": "Id", + "type": "string" + }, + "name": { + "description": "Name of the model service.", + "title": "Name", + "type": "string" + }, + "desired_session_count": { + "description": "Number of identical inference sessions.", + "minimum": 0, + "title": "Desired Session Count", + "type": "integer" + }, + "active_route_count": { + "description": "Information of routes which are actually spawned and ready to accept the traffic.", + "minimum": 0, + "title": "Active Route Count", + "type": "integer" + }, + "service_endpoint": { + "anyOf": [ + { + "format": "uri", + "maxLength": 2083, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "HTTP(S) endpoint to the API service. This field will be filed after the attempt to create a first inference session succeeds. Endpoint created is fixed and immutable for the bound endpoint until the endpoint is destroyed.", + "title": "Service Endpoint" + }, + "is_public": { + "description": "Indicates if the API endpoint is open to public. In this context \"public\" means there will be no authentication required to communicate with this API service.", + "title": "Is Public", + "type": "boolean" + } + }, + "required": [ + "id", + "name", + "desired_session_count", + "active_route_count", + "is_public" + ], + "title": "CompactServeInfoModel", + "type": "object" + }, + "CompactServeInfoModel_List": { + "items": { + "$ref": "#/components/schemas/CompactServeInfoModel" + }, + "type": "array" + }, + "ClusterMode": { + "enum": [ + "single-node", + "multi-node" + ], + "title": "ClusterMode", + "type": "string" + }, + "MountOptionModel": { + "properties": { + "mount_destination": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Mount destination, defaults to /home/work/{folder_name}.", + "title": "Mount Destination" + }, + "type": { + "$ref": "#/components/schemas/MountTypes", + "default": "bind" + }, + "permission": { + "anyOf": [ + { + "$ref": "#/components/schemas/MountPermission" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "MountOptionModel", + "type": "object" + }, + "MountPermission": { + "enum": [ + "ro", + "rw", + "wd" + ], + "title": "MountPermission", + "type": "string" + }, + "MountTypes": { + "enum": [ + "volume", + "bind", + "tmpfs", + "k8s-generic", + "k8s-hostpath" + ], + "title": "MountTypes", + "type": "string" + }, + "RuntimeVariant": { + "enum": [ + "vllm", + "nim", + "cmd", + "custom" + ], + "title": "RuntimeVariant", + "type": "string" + }, + "ServiceConfigModel": { + "properties": { + "model": { + "description": "Name or ID of the model VFolder", + "examples": [ + "ResNet50" + ], + "title": "Model", + "type": "string" + }, + "model_definition_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Path to the model definition file. If not set, Backend.AI will look for model-definition.yml or model-definition.yaml by default.", + "title": "Model Definition Path" + }, + "model_version": { + "default": 1, + "description": "Unused; Reserved for future works", + "title": "Model Version", + "type": "integer" + }, + "model_mount_destination": { + "default": "/models", + "description": "Mount destination for the model VFolder will be mounted inside the inference session. Must be set to `/models` when choosing `runtime_variant` other than `CUSTOM` or `CMD`.", + "title": "Model Mount Destination", + "type": "string" + }, + "extra_mounts": { + "additionalProperties": { + "$ref": "#/components/schemas/MountOptionModel" + }, + "default": {}, + "description": "Specifications about extra VFolders mounted to model service session. MODEL type VFolders are not allowed to be attached to model service session with this option.", + "title": "Extra Mounts", + "type": "object" + }, + "environ": { + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Environment variables to be set inside the inference session", + "title": "Environ" + }, + "scaling_group": { + "description": "Name of the resource group to spawn inference sessions", + "examples": [ + "nvidia-H100" + ], + "title": "Scaling Group", + "type": "string" + }, + "resources": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "examples": [ + { + "cpu": 4, + "cuda.shares": 2.5, + "mem": "32g" + } + ], + "title": "Resources", + "type": "object" + }, + "resource_opts": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "default": {}, + "examples": [ + { + "shmem": "2g" + } + ], + "title": "Resource Opts", + "type": "object" + } + }, + "required": [ + "model", + "scaling_group", + "resources" + ], + "title": "ServiceConfigModel", + "type": "object" + }, + "NewServiceRequestModel": { + "properties": { + "name": { + "description": "Name of the service", + "title": "Name", + "type": "string" + }, + "desired_session_count": { + "description": "Number of sessions to serve traffic", + "title": "Desired Session Count", + "type": "integer" + }, + "image": { + "description": "String reference of the image which will be used to create session", + "examples": [ + "cr.backend.ai/stable/python-tensorflow:2.7-py38-cuda11.3" + ], + "title": "Image", + "type": "string" + }, + "runtime_variant": { + "$ref": "#/components/schemas/RuntimeVariant", + "default": "custom", + "description": "Type of the inference runtime the image will try to load." + }, + "arch": { + "default": "x86_64", + "description": "Image architecture", + "title": "Arch", + "type": "string" + }, + "group": { + "default": "default", + "description": "Name of project to spawn session", + "title": "Group", + "type": "string" + }, + "domain": { + "default": "default", + "description": "Name of domain to spawn session", + "title": "Domain", + "type": "string" + }, + "cluster_size": { + "default": 1, + "title": "Cluster Size", + "type": "integer" + }, + "cluster_mode": { + "$ref": "#/components/schemas/ClusterMode", + "default": "single-node" + }, + "tag": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Tag" + }, + "startup_command": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Startup Command" + }, + "bootstrap_script": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Bootstrap Script" + }, + "callback_url": { + "anyOf": [ + { + "format": "uri", + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Callback Url" + }, + "owner_access_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "(for privileged users only) when specified, transfer ownership of the inference session to specified user", + "title": "Owner Access Key" + }, + "open_to_public": { + "default": false, + "description": "If set to true, do not require an API key to access the model service", + "title": "Open To Public", + "type": "boolean" + }, + "config": { + "$ref": "#/components/schemas/ServiceConfigModel" + } + }, + "required": [ + "name", + "desired_session_count", + "image", + "config" + ], + "title": "NewServiceRequestModel", + "type": "object" + }, + "RouteInfoModel": { + "properties": { + "route_id": { + "description": "Unique ID referencing endpoint route. Each endpoint route has a one-to-one relationship with the inference session.", + "format": "uuid", + "title": "Route Id", + "type": "string" + }, + "session_id": { + "description": "Unique ID referencing the inference session.", + "format": "uuid", + "title": "Session Id", + "type": "string" + }, + "traffic_ratio": { + "minimum": 0.0, + "title": "Traffic Ratio", + "type": "number" + } + }, + "required": [ + "route_id", + "session_id", + "traffic_ratio" + ], + "title": "RouteInfoModel", + "type": "object" + }, + "ServeInfoModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "endpoint_id": { + "description": "Unique ID referencing the model service.", + "format": "uuid", + "title": "Endpoint Id", + "type": "string" + }, + "model_id": { + "description": "ID of model VFolder.", + "format": "uuid", + "title": "Model Id", + "type": "string" + }, + "extra_mounts": { + "description": "List of extra VFolders which will be mounted to model service session.", + "items": { + "format": "uuid", + "type": "string" + }, + "title": "Extra Mounts", + "type": "array" + }, + "name": { + "description": "Name of the model service.", + "title": "Name", + "type": "string" + }, + "desired_session_count": { + "description": "Number of identical inference sessions.", + "minimum": 0, + "title": "Desired Session Count", + "type": "integer" + }, + "model_definition_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Path to the the model definition file. If not set, Backend.AI will look for model-definition.yml or model-definition.yaml by default.", + "title": "Model Definition Path" + }, + "active_routes": { + "description": "Information of routes which are bound with healthy sessions.", + "items": { + "$ref": "#/components/schemas/RouteInfoModel" + }, + "title": "Active Routes", + "type": "array" + }, + "service_endpoint": { + "anyOf": [ + { + "format": "uri", + "maxLength": 2083, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "HTTP(S) endpoint to the API service. This field will be filed after the attempt to create a first inference session succeeds. Endpoint created is fixed and immutable for the bound endpoint until the endpoint is destroyed.", + "title": "Service Endpoint" + }, + "is_public": { + "description": "Indicates if the API endpoint is open to public. In this context \"public\" means there will be no authentication required to communicate with this API service.", + "title": "Is Public", + "type": "boolean" + }, + "runtime_variant": { + "$ref": "#/components/schemas/RuntimeVariant", + "description": "Type of the inference runtime the image will try to load." + } + }, + "required": [ + "endpoint_id", + "model_id", + "extra_mounts", + "name", + "desired_session_count", + "model_definition_path", + "active_routes", + "is_public", + "runtime_variant" + ], + "title": "ServeInfoModel", + "type": "object" + }, + "TryStartResponseModel": { + "properties": { + "task_id": { + "title": "Task Id", + "type": "string" + } + }, + "required": [ + "task_id" + ], + "title": "TryStartResponseModel", + "type": "object" + }, + "RuntimeInfo": { + "properties": { + "name": { + "description": "Identifier to be passed later inside request body", + "title": "Name", + "type": "string" + }, + "human_readable_name": { + "description": "Use this value as displayed label to user", + "title": "Human Readable Name", + "type": "string" + } + }, + "required": [ + "name", + "human_readable_name" + ], + "title": "RuntimeInfo", + "type": "object" + }, + "RuntimeInfoModel": { + "properties": { + "runtimes": { + "items": { + "$ref": "#/components/schemas/RuntimeInfo" + }, + "title": "Runtimes", + "type": "array" + } + }, + "required": [ + "runtimes" + ], + "title": "RuntimeInfoModel", + "type": "object" + }, + "SuccessResponseModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "success": { + "default": true, + "title": "Success", + "type": "boolean" + } + }, + "title": "SuccessResponseModel", + "type": "object" + }, + "ErrorInfoModel": { + "properties": { + "session_id": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "error": { + "title": "Error", + "type": "object" + } + }, + "required": [ + "session_id", + "error" + ], + "title": "ErrorInfoModel", + "type": "object" + }, + "ErrorListResponseModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "errors": { + "items": { + "$ref": "#/components/schemas/ErrorInfoModel" + }, + "title": "Errors", + "type": "array" + }, + "retries": { + "title": "Retries", + "type": "integer" + } + }, + "required": [ + "errors", + "retries" + ], + "title": "ErrorListResponseModel", + "type": "object" + }, + "ScaleRequestModel": { + "properties": { + "to": { + "description": "Ideal number of inference sessions", + "title": "To", + "type": "integer" + } + }, + "required": [ + "to" + ], + "title": "ScaleRequestModel", + "type": "object" + }, + "ScaleResponseModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "current_route_count": { + "title": "Current Route Count", + "type": "integer" + }, + "target_count": { + "title": "Target Count", + "type": "integer" + } + }, + "required": [ + "current_route_count", + "target_count" + ], + "title": "ScaleResponseModel", + "type": "object" + }, + "UpdateRouteRequestModel": { + "properties": { + "traffic_ratio": { + "minimum": 0.0, + "title": "Traffic Ratio", + "type": "number" + } + }, + "required": [ + "traffic_ratio" + ], + "title": "UpdateRouteRequestModel", + "type": "object" + }, + "TokenRequestModel": { + "properties": { + "duration": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The lifetime duration of the token.", + "title": "Duration" + }, + "valid_until": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The absolute token expiry date expressed in the Unix epoch format.", + "title": "Valid Until" + }, + "expires_at": { + "default": -1, + "description": "The expiration timestamp computed from duration or valid_until.", + "title": "Expires At", + "type": "integer" + } + }, + "title": "TokenRequestModel", + "type": "object" + }, + "TokenResponseModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "token": { + "title": "Token", + "type": "string" + } + }, + "required": [ + "token" + ], + "title": "TokenResponseModel", + "type": "object" + }, + "TransitSessionStatusRequestModel": { + "properties": { + "ids": { + "description": "ID array of sessions to check and transit status.", + "items": { + "format": "uuid", + "type": "string" + }, + "title": "Ids", + "type": "array" + } + }, + "required": [ + "ids" + ], + "title": "TransitSessionStatusRequestModel", + "type": "object" + }, + "SessionStatusResponseModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "session_status_map": { + "additionalProperties": { + "type": "string" + }, + "title": "Session Status Map", + "type": "object" + } + }, + "required": [ + "session_status_map" + ], + "title": "SessionStatusResponseModel", + "type": "object" + }, + "ContainerLogRequestModel": { + "properties": { + "owner_access_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Owner Access Key" + }, + "kernel_id": { + "anyOf": [ + { + "format": "uuid", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Target kernel to get container logs.", + "title": "Kernel Id" + } + }, + "title": "ContainerLogRequestModel", + "type": "object" + }, + "CustomizedImageVisibilityScope": { + "enum": [ + "user", + "project" + ], + "title": "CustomizedImageVisibilityScope", + "type": "string" + }, + "ConvertSessionToImageRequesteModel": { + "properties": { + "image_name": { + "description": "Name of the image to be created.", + "pattern": "[a-zA-Z0-9\\.\\-_]+", + "title": "Image Name", + "type": "string" + }, + "login_session_token": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Login Session Token" + }, + "image_visibility": { + "$ref": "#/components/schemas/CustomizedImageVisibilityScope", + "default": "user", + "description": "Visibility scope of newly created image. currently only supports `USER` scope. Setting this to value other than `USER` will raise error." + } + }, + "required": [ + "image_name" + ], + "title": "ConvertSessionToImageRequesteModel", + "type": "object" + }, + "ConvertSessionToImageResponseModel": { + "properties": { + "status": { + "default": 200, + "exclusiveMaximum": 600, + "minimum": 100, + "title": "Status", + "type": "integer" + }, + "task_id": { + "title": "Task Id", + "type": "string" + } + }, + "required": [ + "task_id" + ], + "title": "ConvertSessionToImageResponseModel", + "type": "object" + } + } + }, + "paths": { + "/acl": { + "get": { + "operationId": "acl.get_permission", + "tags": [ + "acl" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/config/resource-slots": { + "get": { + "operationId": "config.get_resource_slots", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [], + "description": "" + } + }, + "/config/resource-slots/details": { + "get": { + "operationId": "config.get_resource_metadata", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [ + { + "name": "sgroup", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "" + } + }, + "/config/vfolder-types": { + "get": { + "operationId": "config.get_vfolder_types", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [], + "description": "" + } + }, + "/config/docker-registries": { + "get": { + "operationId": "config.get_docker_registries", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nReturns the list of all registered docker registries.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/config/get": { + "post": { + "operationId": "config.get_config", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "prefix": { + "type": "boolean" + } + }, + "required": [ + "key", + "prefix" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nA raw access API to read key-value pairs from the etcd.\n\n.. warning::\n\n When reading the keys with ``prefix=True``, it uses a simple string-prefix\n matching over the flattened keys (with the delimiter \"/\"). Thus, it may\n return additional keys that you may not want.\n\n For example, reading \"some/key1\" will fetch all of the following keys:\n\n .. code-block:: text\n\n some/key1\n some/key1/field1\n some/key1/field2\n some/key12\n some/key12/field1\n some/key12/field2\n\n **To avoid this issue, developers must use dedicated CRUD APIs\n instead of relying on the etcd raw access APIs whenever possible.**\n\n\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/config/set": { + "post": { + "operationId": "config.set_config", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nA raw access API to write key-value pairs into the etcd.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/config/delete": { + "post": { + "operationId": "config.delete_config", + "tags": [ + "config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "prefix": { + "type": "boolean" + } + }, + "required": [ + "key", + "prefix" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nA raw access API to delete key-value pairs from the etcd.\n\n.. warning::\n\n When deleting the keys with ``prefix=True``, it uses a simple string-prefix\n matching over the flattened keys (with the delimiter \"/\"). This may result in\n unexpected deletion of sibling keys.\n\n For example, deleting \"some/key1\" will DELETE all of the following keys:\n\n .. code-block:: text\n\n some/key1\n some/key1/field1\n some/key1/field2\n some/key12\n some/key12/field1\n some/key12/field2\n\n **To avoid this issue, developers must use dedicated CRUD APIs\n instead of relying on the etcd raw access APIs whenever possible.**\n\n\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/events/background-task": { + "get": { + "operationId": "events.push_background_task_events", + "tags": [ + "events" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "task_id", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/events/session": { + "get": { + "operationId": "events.push_session_events", + "tags": [ + "events" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "schema": { + "type": "string", + "default": "*" + }, + "required": true, + "in": "query" + }, + { + "name": "ownerAccessKey", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "sessionId", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": false, + "in": "query" + }, + { + "name": "group", + "schema": { + "type": "string", + "default": "*" + }, + "required": true, + "in": "query" + }, + { + "name": "scope", + "schema": { + "type": "string", + "enum": [ + "*", + "session", + "kernel" + ], + "default": "*" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/auth": { + "get": { + "operationId": "auth.test", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "echo", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n" + }, + "post": { + "operationId": "auth.test.2", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "echo": { + "type": "string" + } + }, + "required": [ + "echo" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/auth/test": { + "get": { + "operationId": "auth.test.3", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "echo", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n" + }, + "post": { + "operationId": "auth.test.4", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "echo": { + "type": "string" + } + }, + "required": [ + "echo" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/auth/authorize": { + "post": { + "operationId": "auth.authorize", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "keypair", + "jwt" + ] + }, + "domain": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "required": [ + "type", + "domain", + "username", + "password" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "" + } + }, + "/auth/role": { + "get": { + "operationId": "auth.get_role", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "group", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/auth/signup": { + "post": { + "operationId": "auth.signup", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "required": [ + "domain", + "email", + "password" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "" + } + }, + "/auth/signout": { + "post": { + "operationId": "auth.signout", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "required": [ + "email", + "password" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/auth/update-password-no-auth": { + "post": { + "operationId": "auth.update_password_no_auth", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "username": { + "type": "string" + }, + "current_password": { + "type": "string" + }, + "new_password": { + "type": "string" + } + }, + "required": [ + "domain", + "username", + "current_password", + "new_password" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nUpdate user's password without any authorization\nto allows users to update passwords that have expired\nbecause it's been too long since a user changed the password.\n" + } + }, + "/auth/update-password": { + "post": { + "operationId": "auth.update_password", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "old_password": { + "type": "string" + }, + "new_password": { + "type": "string" + }, + "new_password2": { + "type": "string" + } + }, + "required": [ + "old_password", + "new_password", + "new_password2" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/auth/update-full-name": { + "post": { + "operationId": "auth.update_full_name", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "full_name": { + "type": "string" + } + }, + "required": [ + "email", + "full_name" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/auth/ssh-keypair": { + "get": { + "operationId": "auth.get_ssh_keypair", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + }, + "patch": { + "operationId": "auth.generate_ssh_keypair", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + }, + "post": { + "operationId": "auth.upload_ssh_keypair", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "pubkey": { + "type": "string" + }, + "privkey": { + "type": "string" + } + }, + "required": [ + "pubkey", + "privkey" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/folders": { + "post": { + "operationId": "folders.create", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateRequestModel" + } + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "folders.list_folders", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "all", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + }, + { + "name": "group_id", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": false, + "in": "query" + }, + { + "name": "owner_user_email", + "schema": { + "type": "string", + "format": "email" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "folders.delete_by_id", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteRequestModel" + } + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}": { + "get": { + "operationId": "folders.get_info", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "folders.delete_by_name", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/id": { + "get": { + "operationId": "folders.get_vfolder_id", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompactVFolderInfoModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IDRequestModel" + } + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/hosts": { + "get": { + "operationId": "folders.list_hosts", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "group_id", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/all-hosts": { + "get": { + "operationId": "folders.list_all_hosts", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/allowed-types": { + "get": { + "operationId": "folders.list_allowed_types", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/all_hosts": { + "get": { + "operationId": "folders.list_all_hosts.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/allowed_types": { + "get": { + "operationId": "folders.list_allowed_types.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/perf-metric": { + "get": { + "operationId": "folders.get_volume_perf_metric", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "folder_host", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/rename": { + "post": { + "operationId": "folders.rename_vfolder", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RenameRequestModel" + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/update-options": { + "post": { + "operationId": "folders.update_vfolder_options", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "cloneable": { + "type": "boolean" + }, + "permission": { + "type": "string", + "enum": [ + "ro", + "rw", + "wd" + ] + } + }, + "required": [] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/mkdir": { + "post": { + "operationId": "folders.mkdir", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "parents": { + "type": "boolean", + "default": true + }, + "exist_ok": { + "type": "boolean" + } + }, + "required": [ + "path", + "parents", + "exist_ok" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/request-upload": { + "post": { + "operationId": "folders.create_upload_session", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "size": { + "type": "integer" + } + }, + "required": [ + "path", + "size" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/request-download": { + "post": { + "operationId": "folders.create_download_session", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "archive": { + "type": "boolean" + } + }, + "required": [ + "path", + "archive" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/move-file": { + "post": { + "operationId": "folders.move_file", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "src": { + "type": "string" + }, + "dst": { + "type": "string" + } + }, + "required": [ + "src", + "dst" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/rename-file": { + "post": { + "operationId": "folders.rename_file", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "target_path": { + "type": "string" + }, + "new_name": { + "type": "string" + }, + "is_dir": { + "type": "boolean" + } + }, + "required": [ + "target_path", + "new_name", + "is_dir" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/delete-files": { + "post": { + "operationId": "folders.delete_files", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "files": { + "type": "array", + "items": { + "type": "string" + } + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "files", + "recursive" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "folders.delete_files.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "files", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true, + "in": "query" + }, + { + "name": "recursive", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/rename_file": { + "post": { + "operationId": "folders.rename_file.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "target_path": { + "type": "string" + }, + "new_name": { + "type": "string" + }, + "is_dir": { + "type": "boolean" + } + }, + "required": [ + "target_path", + "new_name", + "is_dir" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/delete_files": { + "delete": { + "operationId": "folders.delete_files.3", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "files", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true, + "in": "query" + }, + { + "name": "recursive", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/files": { + "get": { + "operationId": "folders.list_files", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/invite": { + "post": { + "operationId": "folders.invite", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "perm": { + "type": "string", + "enum": [ + "ro", + "rw", + "wd" + ], + "default": "rw" + }, + "emails": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "perm", + "emails" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/leave": { + "post": { + "operationId": "folders.leave", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "shared_user_uuid": { + "type": "string" + } + }, + "required": [] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nLeave from shared VFolder.\n\nCannot leave a group VFolder or a VFolder that the requesting user owns.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/share": { + "post": { + "operationId": "folders.share", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "permission": { + "type": "string", + "enum": [ + "ro", + "rw", + "wd" + ], + "default": "rw" + }, + "emails": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "permission", + "emails" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nShare a group folder to users with overriding permission.\n\nThis will create vfolder_permission(s) relation directly without\ncreating invitation(s). Only group-type vfolders are allowed to\nbe shared directly.\n\n\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/unshare": { + "post": { + "operationId": "folders.unshare", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "emails": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "emails" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nUnshare a group folder from users.\n\n\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "folders.unshare.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "emails", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true, + "in": "query" + } + ], + "description": "\nUnshare a group folder from users.\n\n\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/{name}/clone": { + "post": { + "operationId": "folders.clone", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "cloneable": { + "type": "boolean" + }, + "target_name": { + "type": "string", + "description": "String composed of alpha-numeric characters with hyphen and underscores in the middle (space and dot may be additionally allowed depending on the used locations)" + }, + "target_host": { + "type": "string" + }, + "usage_mode": { + "type": "string", + "enum": [ + "general", + "model", + "data" + ], + "default": "general" + }, + "permission": { + "type": "string", + "enum": [ + "ro", + "rw", + "wd" + ], + "default": "rw" + } + }, + "required": [ + "cloneable", + "target_name" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/purge": { + "post": { + "operationId": "folders.purge", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PurgeRequestModel" + } + } + } + }, + "parameters": [], + "description": "\nDelete `delete-complete`d vfolder rows in DB\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/restore-from-trash-bin": { + "post": { + "operationId": "folders.restore", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RestoreRequestModel" + } + } + } + }, + "parameters": [], + "description": "\nRecover vfolder from trash bin, by changing status.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/delete-from-trash-bin": { + "post": { + "operationId": "folders.delete_from_trash_bin", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteFromTrashRequestModel" + } + } + } + }, + "parameters": [], + "description": "\nDelete `delete-pending` vfolders in storage proxy\n\n\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/folders/invitations/list-sent": { + "get": { + "operationId": "folders.list_sent_invitations", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/invitations/list_sent": { + "get": { + "operationId": "folders.list_sent_invitations.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/invitations/update/{inv_id}": { + "post": { + "operationId": "folders.update_invitation", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "perm": { + "type": "string", + "enum": [ + "ro", + "rw", + "wd" + ] + } + }, + "required": [ + "perm" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "inv_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nUpdate sent invitation's permission. Other fields are not allowed to be updated.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/invitations/list": { + "get": { + "operationId": "folders.invitations", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/invitations/accept": { + "post": { + "operationId": "folders.accept_invitation", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "inv_id": { + "type": "string" + } + }, + "required": [ + "inv_id" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "Accept invitation by invitee.\n\n * `inv_ak` parameter is removed from 19.06 since virtual folder's ownership is\n moved from keypair to a user or a group.\n\n :param inv_id: ID of vfolder_invitations row.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/invitations/delete": { + "post": { + "operationId": "folders.delete_invitation", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "inv_id": { + "type": "string" + } + }, + "required": [ + "inv_id" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "folders.delete_invitation.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "inv_id", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/shared": { + "get": { + "operationId": "folders.list_shared_vfolders", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "vfolder_id", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": false, + "in": "query" + } + ], + "description": "\nList shared vfolders.\n\nNot available for group vfolders.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "post": { + "operationId": "folders.update_shared_vfolder", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "vfolder": { + "type": "string", + "format": "uuid" + }, + "user": { + "type": "string", + "format": "uuid" + }, + "perm": { + "type": "string", + "enum": [ + "ro", + "rw", + "wd" + ] + } + }, + "required": [ + "vfolder", + "user" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nUpdate permission for shared vfolders.\n\nIf params['perm'] is None, remove user's permission for the vfolder.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/sharing": { + "post": { + "operationId": "folders.update_vfolder_sharing_status", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSharedRequestModel" + } + } + } + }, + "parameters": [], + "description": "\nUpdate permission for shared vfolders.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/fstab": { + "get": { + "operationId": "folders.get_fstab_contents", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "fstab_path", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "agent_id", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\nReturn the contents of `/etc/fstab` file.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/mounts": { + "get": { + "operationId": "folders.list_mounts", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nList all mounted vfolder hosts in vfroot.\n\nAll mounted hosts from connected (ALIVE) agents are also gathered.\nGenerally, agents should be configured to have same hosts structure,\nbut newly introduced one may not.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + }, + "post": { + "operationId": "folders.mount_host", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "fs_location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "fs_type": { + "type": "string", + "default": "nfs" + }, + "options": { + "type": "string" + }, + "scaling_group": { + "type": "string" + }, + "fstab_path": { + "type": "string" + }, + "edit_fstab": { + "type": "boolean" + } + }, + "required": [ + "fs_location", + "name", + "fs_type", + "edit_fstab" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nMount device into vfolder host.\n\nMount a device (eg: nfs) located at `fs_location` into `/name` in the\nhost machines (manager and all agents). `fs_type` can be specified by requester,\nwhich fallbaks to 'nfs'.\n\nIf `scaling_group` is specified, try to mount for agents in the scaling group.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "folders.umount_host.2", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "name", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "scaling_group", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "fstab_path", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "edit_fstab", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + } + ], + "description": "\nUnmount device from vfolder host.\n\nUnmount a device (eg: nfs) located at `/name` from the host machines\n(manager and all agents).\n\nIf `scaling_group` is specified, try to unmount for agents in the scaling group.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/umounts": { + "post": { + "operationId": "folders.umount_host", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "scaling_group": { + "type": "string" + }, + "fstab_path": { + "type": "string" + }, + "edit_fstab": { + "type": "boolean" + } + }, + "required": [ + "name", + "edit_fstab" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nUnmount device from vfolder host.\n\nUnmount a device (eg: nfs) located at `/name` from the host machines\n(manager and all agents).\n\nIf `scaling_group` is specified, try to unmount for agents in the scaling group.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/change-ownership": { + "post": { + "operationId": "folders.change_vfolder_ownership", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "vfolder": { + "type": "string", + "format": "uuid" + }, + "user_email": { + "type": "string" + } + }, + "required": [ + "vfolder", + "user_email" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nChange the ownership of vfolder\nFor now, we only provide changing the ownership of user-folder\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/quota": { + "get": { + "operationId": "folders.get_quota", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "folder_host", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "id", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "post": { + "operationId": "folders.update_quota", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "folder_host": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "input": { + "type": "object", + "description": "Mapping(String => Any)", + "additionalProperties": true + } + }, + "required": [ + "folder_host", + "id", + "input" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/usage": { + "get": { + "operationId": "folders.get_usage", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "folder_host", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "id", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/folders/_/used-bytes": { + "get": { + "operationId": "folders.get_used_bytes", + "tags": [ + "folders" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "folder_host", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "id", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "//graphql": { + "post": { + "operationId": "root.handle_gql_legacy", + "tags": [ + "root" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "query": { + "type": "string" + }, + "variables": { + "type": "object", + "description": "Mapping(String => Any)", + "additionalProperties": true + }, + "operation_name": { + "type": "string" + } + }, + "required": [ + "query" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "//gql": { + "post": { + "operationId": "root.handle_gql", + "tags": [ + "root" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "query": { + "type": "string" + }, + "variables": { + "type": "object", + "description": "Mapping(String => Any)", + "additionalProperties": true + }, + "operation_name": { + "type": "string" + } + }, + "required": [ + "query" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/spec/graphiql": { + "get": { + "operationId": "spec.render_graphiql_html", + "tags": [ + "spec" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/spec/openapi": { + "get": { + "operationId": "spec.render_openapi_html", + "tags": [ + "spec" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/spec/openapi/spec.json": { + "get": { + "operationId": "spec.generate_openapi_spec", + "tags": [ + "spec" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/services": { + "get": { + "operationId": "services.list_serve", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompactServeInfoModel_List" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListServeRequestModel" + } + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "post": { + "operationId": "services.create", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServeInfoModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewServiceRequestModel" + } + } + } + }, + "parameters": [], + "description": "\nCreates a new model service. If `desired_session_count` is greater than zero,\nthen inference sessions will be automatically scheduled upon successful creation of model service.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/_/try": { + "post": { + "operationId": "services.try_start", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TryStartResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewServiceRequestModel" + } + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/_/runtimes": { + "get": { + "operationId": "services.list_supported_runtimes", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeInfoModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}": { + "get": { + "operationId": "services.get_info", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServeInfoModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "services.delete", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nRemoves model service (and inference sessions for the service also).\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}/errors": { + "get": { + "operationId": "services.list_errors", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorListResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nList errors raised while trying to create the inference sessions. Backend.AI will\nstop trying to create an inference session for the model service if six (6) error stacks\nup. The only way to clear the error and retry spawning session is to call\n`clear_error` (POST /services/{service_id}/errors/clear) API.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}/errors/clear": { + "post": { + "operationId": "services.clear_error", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}/scale": { + "post": { + "operationId": "services.scale", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScaleResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScaleRequestModel" + } + } + } + }, + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nUpdates ideal inference session count manually. Based on the difference of this number,\ninference sessions will be created or removed automatically.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}/sync": { + "post": { + "operationId": "services.sync", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nForce syncs up-to-date model service information with AppProxy.\nIn normal situations this will be automatically handled by Backend.AI schedulers,\nbut this API is left open in case of unexpected restart of AppProxy process.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}/routings/{route_id}": { + "put": { + "operationId": "services.update_route", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateRouteRequestModel" + } + } + } + }, + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "route_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nUpdates traffic bias of specific route.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "services.delete_route", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuccessResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "route_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nScales down the service by removing specific inference session.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/services/{service_id}/token": { + "post": { + "operationId": "services.generate_token", + "tags": [ + "services" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRequestModel" + } + } + } + }, + "parameters": [ + { + "name": "service_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nGenerates a token which acts as an API key to authenticate when calling model service endpoint.\nIf both duration and valid_until is not set then the AppProxy will determine appropriate lifetime of the token.\nduration and valid_until can't be both specified.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session": { + "post": { + "operationId": "session.create_from_params", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^(?=.{4,64}$)\\w[\\w.-]*\\w$" + }, + "priority": { + "type": "integer", + "maximum": 100, + "default": 10 + }, + "image": { + "type": "string" + }, + "arch": { + "type": "string", + "default": "x86_64" + }, + "type": { + "type": "string", + "enum": [ + "interactive", + "batch", + "inference", + "system" + ], + "default": "interactive" + }, + "group": { + "type": "string", + "default": "default" + }, + "domain": { + "type": "string", + "default": "default" + }, + "cluster_size": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "cluster_mode": { + "type": "string", + "enum": [ + "single-node", + "multi-node" + ], + "default": "single-node" + }, + "config": { + "type": "object", + "description": "Mapping(String => Any)", + "additionalProperties": true, + "default": {} + }, + "tag": { + "type": "string" + }, + "enqueueOnly": { + "type": "boolean" + }, + "maxWaitSeconds": { + "type": "integer" + }, + "starts_at": { + "type": "string" + }, + "reuseIfExists": { + "type": "boolean", + "default": true + }, + "startupCommand": { + "type": "string" + }, + "bootstrap_script": { + "type": "string" + }, + "dependencies": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "callback_url": { + "type": "string", + "format": "uri" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "name", + "priority", + "image", + "arch", + "type", + "group", + "domain", + "cluster_size", + "cluster_mode", + "config", + "enqueueOnly", + "maxWaitSeconds", + "reuseIfExists", + "dependencies" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/create": { + "post": { + "operationId": "session.create_from_params.2", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^(?=.{4,64}$)\\w[\\w.-]*\\w$" + }, + "priority": { + "type": "integer", + "maximum": 100, + "default": 10 + }, + "image": { + "type": "string" + }, + "arch": { + "type": "string", + "default": "x86_64" + }, + "type": { + "type": "string", + "enum": [ + "interactive", + "batch", + "inference", + "system" + ], + "default": "interactive" + }, + "group": { + "type": "string", + "default": "default" + }, + "domain": { + "type": "string", + "default": "default" + }, + "cluster_size": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "cluster_mode": { + "type": "string", + "enum": [ + "single-node", + "multi-node" + ], + "default": "single-node" + }, + "config": { + "type": "object", + "description": "Mapping(String => Any)", + "additionalProperties": true, + "default": {} + }, + "tag": { + "type": "string" + }, + "enqueueOnly": { + "type": "boolean" + }, + "maxWaitSeconds": { + "type": "integer" + }, + "starts_at": { + "type": "string" + }, + "reuseIfExists": { + "type": "boolean", + "default": true + }, + "startupCommand": { + "type": "string" + }, + "bootstrap_script": { + "type": "string" + }, + "dependencies": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "callback_url": { + "type": "string", + "format": "uri" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "name", + "priority", + "image", + "arch", + "type", + "group", + "domain", + "cluster_size", + "cluster_mode", + "config", + "enqueueOnly", + "maxWaitSeconds", + "reuseIfExists", + "dependencies" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/create-from-template": { + "post": { + "operationId": "session.create_from_template", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "template_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "pattern": "^(?=.{4,64}$)\\w[\\w.-]*\\w$", + "default": null + }, + "priority": { + "type": "integer", + "maximum": 100, + "default": 10 + }, + "image": { + "type": "string", + "default": null + }, + "arch": { + "type": "string", + "default": null + }, + "type": { + "type": "string", + "enum": [ + "interactive", + "batch", + "inference", + "system" + ], + "default": null + }, + "group": { + "type": "string", + "default": null + }, + "domain": { + "type": "string", + "default": null + }, + "cluster_size": { + "type": "integer", + "minimum": 1, + "default": 1 + }, + "cluster_mode": { + "type": "string", + "enum": [ + "single-node", + "multi-node" + ], + "default": "single-node" + }, + "config": { + "type": "object", + "description": "Mapping(String => Any)", + "additionalProperties": true, + "default": {} + }, + "tag": { + "type": "string", + "default": null + }, + "enqueueOnly": { + "type": "boolean" + }, + "maxWaitSeconds": { + "type": "integer" + }, + "starts_at": { + "type": "string" + }, + "reuseIfExists": { + "type": "boolean", + "default": true + }, + "startupCommand": { + "type": "string" + }, + "bootstrap_script": { + "type": "string", + "default": null + }, + "dependencies": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "callback_url": { + "type": "string", + "format": "uri" + }, + "owner_access_key": { + "type": "string", + "default": null + } + }, + "required": [ + "priority", + "image", + "group", + "domain", + "cluster_size", + "cluster_mode", + "config", + "tag", + "enqueueOnly", + "maxWaitSeconds", + "reuseIfExists", + "startupCommand", + "bootstrap_script", + "dependencies", + "callback_url", + "owner_access_key" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/create-cluster": { + "post": { + "operationId": "session.create_cluster", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "clientSessionToken": { + "type": "string", + "pattern": "^(?=.{4,64}$)\\w[\\w.-]*\\w$" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string", + "enum": [ + "interactive", + "batch", + "inference", + "system" + ], + "default": "interactive" + }, + "group": { + "type": "string", + "default": "default" + }, + "domain": { + "type": "string", + "default": "default" + }, + "scaling_group": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "enqueueOnly": { + "type": "boolean" + }, + "maxWaitSeconds": { + "type": "integer" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "clientSessionToken", + "type", + "group", + "domain", + "enqueueOnly", + "maxWaitSeconds" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/match": { + "get": { + "operationId": "session.match_sessions", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "id", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\nA quick session-ID matcher API for use with auto-completion in CLI.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/sync-agent-registry": { + "post": { + "operationId": "session.sync_agent_registry", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agent": { + "type": "string" + } + }, + "required": [ + "agent" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/transit-status": { + "post": { + "operationId": "session.check_and_transit_status", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SessionStatusResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransitSessionStatusRequestModel" + } + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}": { + "get": { + "operationId": "session.get_info", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "patch": { + "operationId": "session.restart", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "owner_access_key": { + "type": "string" + } + }, + "required": [] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "session.destroy", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "forced", + "schema": { + "type": "boolean", + "default": "false" + }, + "required": true, + "in": "query" + }, + { + "name": "recursive", + "schema": { + "type": "boolean", + "default": "false" + }, + "required": true, + "in": "query" + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "post": { + "operationId": "session.execute", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/_/logs": { + "head": { + "operationId": "session.get_task_logs", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "session_name": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "session_name" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "session.get_task_logs.2", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "schema": { + "type": "string", + "format": "uuid" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/direct-access-info": { + "get": { + "operationId": "session.get_direct_access_info", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/logs": { + "get": { + "operationId": "session.get_container_logs", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContainerLogRequestModel" + } + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/rename": { + "post": { + "operationId": "session.rename_session", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^(?=.{4,64}$)\\w[\\w.-]*\\w$" + } + }, + "required": [ + "name" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/interrupt": { + "post": { + "operationId": "session.interrupt", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/complete": { + "post": { + "operationId": "session.complete", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/shutdown-service": { + "post": { + "operationId": "session.shutdown_service", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "service_name": { + "type": "string" + } + }, + "required": [ + "service_name" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/upload": { + "post": { + "operationId": "session.upload_files", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/download": { + "get": { + "operationId": "session.deprecated_stub_impl", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "" + }, + "post": { + "operationId": "session.download_files", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "files": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "files" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/download_single": { + "get": { + "operationId": "session.deprecated_stub_impl.2", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "" + }, + "post": { + "operationId": "session.download_single", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string" + } + }, + "required": [ + "file" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nDownload a single file from the scratch root. Only for small files.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/files": { + "get": { + "operationId": "session.list_files", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/start-service": { + "post": { + "operationId": "session.start_service", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "login_session_token": { + "type": "string" + }, + "app": { + "type": "string" + }, + "port": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + }, + "envs": { + "type": "string" + }, + "arguments": { + "type": "string" + } + }, + "required": [ + "app" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/commit": { + "post": { + "operationId": "session.commit_session", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "login_session_token": { + "type": "string" + }, + "filename": { + "type": "string" + } + }, + "required": [] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "session.get_commit_status", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "login_session_token", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/imagify": { + "post": { + "operationId": "session.convert_session_to_image", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConvertSessionToImageResponseModel" + } + } + } + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConvertSessionToImageRequesteModel" + } + } + } + }, + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/abusing-report": { + "get": { + "operationId": "session.get_abusing_report", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "login_session_token", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/session/{session_name}/dependency-graph": { + "get": { + "operationId": "session.get_dependency_graph", + "tags": [ + "session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/stream/session/{session_name}/pty": { + "get": { + "operationId": "stream.stream_pty", + "tags": [ + "stream" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/stream/session/{session_name}/execute": { + "get": { + "operationId": "stream.stream_execute", + "tags": [ + "stream" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\nWebSocket-version of gateway.kernel.execute().\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/stream/session/{session_name}/apps": { + "get": { + "operationId": "stream.get_stream_apps", + "tags": [ + "stream" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/stream/session/{session_name}/httpproxy": { + "get": { + "operationId": "stream.stream_proxy", + "tags": [ + "stream" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "app", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "port", + "schema": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + }, + "required": false, + "in": "query" + }, + { + "name": "envs", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "arguments", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/stream/session/{session_name}/tcpproxy": { + "get": { + "operationId": "stream.stream_proxy.2", + "tags": [ + "stream" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "session_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "app", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "port", + "schema": { + "type": "integer", + "minimum": 1024, + "maximum": 65535 + }, + "required": false, + "in": "query" + }, + { + "name": "envs", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "arguments", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/manager/status": { + "get": { + "operationId": "manager.fetch_manager_status", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [], + "description": "" + }, + "put": { + "operationId": "manager.update_manager_status", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "terminated", + "preparing", + "running", + "frozen" + ] + }, + "force_kill": { + "type": "boolean" + } + }, + "required": [ + "status", + "force_kill" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/manager/announcement": { + "get": { + "operationId": "manager.get_announcement", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "parameters": [], + "description": "" + }, + "post": { + "operationId": "manager.update_announcement", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": "false" + }, + "message": { + "type": "string" + } + }, + "required": [ + "enabled" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/manager/scheduler/operation": { + "post": { + "operationId": "manager.perform_scheduler_ops", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "op": { + "type": "string", + "enum": [ + "include-agents", + "exclude-agents" + ] + }, + "args": { + "type": "string" + } + }, + "required": [ + "op", + "args" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/manager/scheduler/trigger": { + "post": { + "operationId": "manager.scheduler_trigger", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "event": { + "type": "string", + "enum": [ + "schedule", + "prepare", + "scale_services" + ] + } + }, + "required": [ + "event" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/manager/scheduler/status": { + "get": { + "operationId": "manager.scheduler_healthcheck", + "tags": [ + "manager" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/resource/presets": { + "get": { + "operationId": "resource.list_presets", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nReturns the list of all resource presets.\n\n\n**Preconditions:**\n* User privilege required.\n" + } + }, + "/resource/container-registries": { + "get": { + "operationId": "resource.get_container_registries", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nReturns the list of all registered container registries.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n" + } + }, + "/resource/check-presets": { + "post": { + "operationId": "resource.check_presets", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "scaling_group": { + "type": "string" + }, + "group": { + "type": "string", + "default": "default" + } + }, + "required": [ + "group" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\nReturns the list of all resource presets in the current scaling group,\nwith additional information including allocatability of each preset,\namount of total remaining resources, and the current keypair resource limits.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/recalculate-usage": { + "post": { + "operationId": "resource.recalculate_usage", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nUpdate `keypair_resource_usages` in redis and `agents.c.occupied_slots`.\n\nThose two values are sometimes out of sync. In that case, calling this API\nre-calculates the values for running containers and updates them in DB.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/usage/month": { + "get": { + "operationId": "resource.usage_per_month", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "group_ids", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": false, + "in": "query" + }, + { + "name": "month", + "schema": { + "type": "string", + "pattern": "^\\d{6}" + }, + "required": true, + "in": "query" + } + ], + "description": "\nReturn usage statistics of terminated containers for a specified month.\nThe date/time comparison is done using the configured timezone.\n\n:param group_ids: If not None, query containers only in those groups.\n:param month: The year-month to query usage statistics. ex) \"202006\" to query for Jun 2020\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/usage/period": { + "get": { + "operationId": "resource.usage_per_period", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "project_id", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "start_date", + "schema": { + "type": "string", + "pattern": "^\\d{8}$" + }, + "required": true, + "in": "query" + }, + { + "name": "end_date", + "schema": { + "type": "string", + "pattern": "^\\d{8}$" + }, + "required": true, + "in": "query" + } + ], + "description": "\nReturn usage statistics of terminated containers belonged to the given group for a specified\nperiod in dates.\nThe date/time comparison is done using the configured timezone.\n\n:param project_id: If not None, query containers only in the project.\n:param start_date str: \"yyyymmdd\" format.\n:param end_date str: \"yyyymmdd\" format.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/stats/user/month": { + "get": { + "operationId": "resource.user_month_stats", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nReturn time-binned (15 min) stats for terminated user sessions\nover last 30 days.\n\n\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/stats/admin/month": { + "get": { + "operationId": "resource.admin_month_stats", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\nReturn time-binned (15 min) stats for all terminated sessions\nover last 30 days.\n\n\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/watcher": { + "get": { + "operationId": "resource.get_watcher_status", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "agent_id", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/watcher/agent/start": { + "post": { + "operationId": "resource.watcher_agent_start", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + } + }, + "required": [ + "agent_id" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/watcher/agent/stop": { + "post": { + "operationId": "resource.watcher_agent_stop", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + } + }, + "required": [ + "agent_id" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/resource/watcher/agent/restart": { + "post": { + "operationId": "resource.watcher_agent_restart", + "tags": [ + "resource" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + } + }, + "required": [ + "agent_id" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Superadmin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/scaling-groups": { + "get": { + "operationId": "scaling-groups.list_available_sgroups", + "tags": [ + "scaling-groups" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "group", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/scaling-groups/{scaling_group}/wsproxy-version": { + "get": { + "operationId": "scaling-groups.get_wsproxy_version", + "tags": [ + "scaling-groups" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "scaling_group", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "group", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/template/cluster": { + "post": { + "operationId": "template/cluster.create", + "tags": [ + "template/cluster" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group": { + "type": "string", + "default": "default" + }, + "domain": { + "type": "string", + "default": "default" + }, + "owner_access_key": { + "type": "string" + }, + "payload": { + "type": "string" + } + }, + "required": [ + "group", + "domain", + "payload" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "template/cluster.list_template", + "tags": [ + "template/cluster" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "all", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + }, + { + "name": "group_id", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/template/cluster/{template_id}": { + "get": { + "operationId": "template/cluster.get", + "tags": [ + "template/cluster" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "format", + "schema": { + "type": "string", + "enum": [ + "yaml", + "json" + ], + "default": "yaml" + }, + "required": false, + "in": "query" + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "put": { + "operationId": "template/cluster.put", + "tags": [ + "template/cluster" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "payload": { + "type": "string" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "payload" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "template/cluster.delete", + "tags": [ + "template/cluster" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/template/session": { + "post": { + "operationId": "template/session.create", + "tags": [ + "template/session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group": { + "type": "string", + "default": "default" + }, + "domain": { + "type": "string", + "default": "default" + }, + "owner_access_key": { + "type": "string" + }, + "payload": { + "type": "string" + } + }, + "required": [ + "group", + "domain", + "payload" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "template/session.list_template", + "tags": [ + "template/session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "all", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + }, + { + "name": "group_id", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/template/session/{template_id}": { + "get": { + "operationId": "template/session.get", + "tags": [ + "template/session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "format", + "schema": { + "type": "string", + "enum": [ + "yaml", + "json" + ], + "default": "json" + }, + "required": false, + "in": "query" + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "put": { + "operationId": "template/session.put", + "tags": [ + "template/session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group": { + "type": "string", + "default": "default" + }, + "domain": { + "type": "string", + "default": "default" + }, + "payload": { + "type": "string" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "group", + "domain", + "payload" + ] + }, + "examples": {} + } + } + }, + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "template/session.delete", + "tags": [ + "template/session" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/user-config/dotfiles": { + "post": { + "operationId": "user-config.create", + "tags": [ + "user-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + }, + "path": { + "type": "string" + }, + "permission": { + "type": "string", + "pattern": "^[0-7]{3}$" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "data", + "path", + "permission" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "user-config.list_or_get", + "tags": [ + "user-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "path", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "patch": { + "operationId": "user-config.update", + "tags": [ + "user-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + }, + "path": { + "type": "string" + }, + "permission": { + "type": "string", + "pattern": "^[0-7]{3}$" + }, + "owner_access_key": { + "type": "string" + } + }, + "required": [ + "data", + "path", + "permission" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "user-config.delete", + "tags": [ + "user-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "path", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "owner_access_key", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/user-config/bootstrap-script": { + "post": { + "operationId": "user-config.update_bootstrap_script", + "tags": [ + "user-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "script": { + "type": "string" + } + }, + "required": [ + "script" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "user-config.get_bootstrap_script", + "tags": [ + "user-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/domain-config/dotfiles": { + "post": { + "operationId": "domain-config.create", + "tags": [ + "domain-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "data": { + "type": "string" + }, + "path": { + "type": "string" + }, + "permission": { + "type": "string", + "pattern": "^[0-7]{3}$" + } + }, + "required": [ + "domain", + "data", + "path", + "permission" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "domain-config.list_or_get", + "tags": [ + "domain-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "domain", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "path", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "patch": { + "operationId": "domain-config.update", + "tags": [ + "domain-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "domain": { + "type": "string" + }, + "data": { + "type": "string" + }, + "path": { + "type": "string" + }, + "permission": { + "type": "string", + "pattern": "^[0-7]{3}$" + } + }, + "required": [ + "domain", + "data", + "path", + "permission" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "domain-config.delete", + "tags": [ + "domain-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "domain", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + }, + { + "name": "path", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/group-config/dotfiles": { + "post": { + "operationId": "group-config.create", + "tags": [ + "group-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "domain": { + "type": "string" + }, + "data": { + "type": "string" + }, + "path": { + "type": "string" + }, + "permission": { + "type": "string", + "pattern": "^[0-7]{3}$" + } + }, + "required": [ + "group", + "data", + "path", + "permission" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "group-config.list_or_get", + "tags": [ + "group-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "group", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": true, + "in": "query" + }, + { + "name": "domain", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "path", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "patch": { + "operationId": "group-config.update", + "tags": [ + "group-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "group": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "domain": { + "type": "string" + }, + "data": { + "type": "string" + }, + "path": { + "type": "string" + }, + "permission": { + "type": "string", + "pattern": "^[0-7]{3}$" + } + }, + "required": [ + "group", + "data", + "path", + "permission" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + }, + "delete": { + "operationId": "group-config.delete", + "tags": [ + "group-config" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "group", + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "string" + } + ] + }, + "required": true, + "in": "query" + }, + { + "name": "domain", + "schema": { + "type": "string" + }, + "required": false, + "in": "query" + }, + { + "name": "path", + "schema": { + "type": "string" + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* Admin privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/logs/error": { + "post": { + "operationId": "logs/error.append", + "tags": [ + "logs/error" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "severity": { + "type": "string", + "enum": [ + "CRITICAL", + "ERROR", + "WARNING", + "INFO", + "DEBUG", + "NOTSET" + ] + }, + "source": { + "type": "string" + }, + "message": { + "type": "string" + }, + "context_lang": { + "type": "string" + }, + "context_env": { + "type": "string", + "description": "JSON string" + }, + "request_url": { + "type": "string" + }, + "request_status": { + "type": "integer" + }, + "traceback": { + "type": "string" + } + }, + "required": [ + "severity", + "source", + "message", + "context_lang", + "context_env" + ] + }, + "examples": {} + } + } + }, + "parameters": [], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + }, + "get": { + "operationId": "logs/error.list_logs", + "tags": [ + "logs/error" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "mark_read", + "schema": { + "type": "boolean" + }, + "required": true, + "in": "query" + }, + { + "name": "page_size", + "schema": { + "type": "integer", + "default": 20 + }, + "required": true, + "in": "query" + }, + { + "name": "page_no", + "schema": { + "type": "integer", + "default": 1 + }, + "required": true, + "in": "query" + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + }, + "/logs/error/{log_id}/clear": { + "post": { + "operationId": "logs/error.mark_cleared", + "tags": [ + "logs/error" + ], + "responses": { + "200": { + "description": "Successful response" + } + }, + "security": [ + { + "TokenAuth": [] + } + ], + "parameters": [ + { + "name": "log_id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "description": "\n**Preconditions:**\n* User privilege required.\n* Manager status required: RUNNING\n" + } + } + } +} \ No newline at end of file diff --git a/src/ai/backend/manager/cli/api.py b/src/ai/backend/manager/cli/api.py index b48a20e023..7c5b51ff69 100644 --- a/src/ai/backend/manager/cli/api.py +++ b/src/ai/backend/manager/cli/api.py @@ -1,19 +1,16 @@ from __future__ import annotations import asyncio -import importlib import json import logging from pathlib import Path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING import aiofiles -import aiohttp_cors import click import graphene -from aiohttp import web -from ai.backend.manager.openapi import generate_openapi +from ai.backend.manager.openapi import generate from ..models.gql import Mutations, Queries @@ -51,23 +48,6 @@ def dump_gql_schema(cli_ctx: CLIContext, output: Path) -> None: asyncio.run(generate_gql_schema(output)) -async def _generate() -> dict[str, Any]: - from ai.backend.manager.server import global_subapp_pkgs - - cors_options = { - "*": aiohttp_cors.ResourceOptions( - allow_credentials=False, expose_headers="*", allow_headers="*" - ), - } - - subapps: list[web.Application] = [] - for subapp in global_subapp_pkgs: - pkg = importlib.import_module("ai.backend.manager.api" + subapp) - app, _ = pkg.create_app(cors_options) - subapps.append(app) - return generate_openapi(subapps, verbose=True) - - @cli.command() @click.pass_obj @click.option( @@ -81,7 +61,7 @@ def dump_openapi(cli_ctx: CLIContext, output: Path) -> None: """ Generates OpenAPI specification of Backend.AI API. """ - openapi = asyncio.run(_generate()) + openapi = asyncio.run(generate()) if output == "-" or output is None: print(json.dumps(openapi, ensure_ascii=False, indent=2)) else: diff --git a/src/ai/backend/manager/openapi.py b/src/ai/backend/manager/openapi.py index 6f059fa2af..7e6f563c89 100644 --- a/src/ai/backend/manager/openapi.py +++ b/src/ai/backend/manager/openapi.py @@ -375,7 +375,7 @@ def generate_openapi(subapps: list[web.Application], verbose=False) -> dict[str, return openapi -async def _generate() -> dict[str, Any]: +async def generate() -> dict[str, Any]: from ai.backend.manager.server import global_subapp_pkgs cors_options = { @@ -404,7 +404,7 @@ def main(output: Path) -> None: """ Generates OpenAPI specification of Backend.AI API. """ - openapi = asyncio.run(_generate()) + openapi = asyncio.run(generate()) if output == "-" or output is None: print(json.dumps(openapi, ensure_ascii=False, indent=2)) else: