From a566252e0163a70b6a71597cc0089ddcde1d5cf3 Mon Sep 17 00:00:00 2001 From: njbrake Date: Fri, 5 Jun 2026 17:15:30 +0000 Subject: [PATCH 1/6] Add generated control-plane client (preview) Generated control-plane client (keys, users, budgets, pricing, usage) from the otari gateway OpenAPI spec via OpenAPI Generator. Preview for review and integration design; not yet wired into the public client. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../_generated/.github/workflows/python.yml | 34 + src/otari/_generated/.gitignore | 66 + src/otari/_generated/.gitlab-ci.yml | 31 + .../_generated/.openapi-generator-ignore | 23 + src/otari/_generated/.openapi-generator/FILES | 89 + .../_generated/.openapi-generator/VERSION | 1 + src/otari/_generated/.travis.yml | 17 + src/otari/_generated/README.md | 143 ++ src/otari/_generated/docs/BudgetResponse.md | 34 + src/otari/_generated/docs/BudgetsApi.md | 361 ++++ .../_generated/docs/CreateBudgetRequest.md | 31 + src/otari/_generated/docs/CreateKeyRequest.md | 33 + .../_generated/docs/CreateKeyResponse.md | 37 + .../_generated/docs/CreateUserRequest.md | 34 + .../_generated/docs/HTTPValidationError.md | 29 + src/otari/_generated/docs/KeyInfo.md | 37 + src/otari/_generated/docs/KeysApi.md | 374 ++++ src/otari/_generated/docs/LocationInner.md | 28 + src/otari/_generated/docs/PricingApi.md | 362 ++++ src/otari/_generated/docs/PricingResponse.md | 35 + .../_generated/docs/SetPricingRequest.md | 33 + .../_generated/docs/UpdateBudgetRequest.md | 31 + src/otari/_generated/docs/UpdateKeyRequest.md | 33 + .../_generated/docs/UpdateUserRequest.md | 33 + src/otari/_generated/docs/UsageApi.md | 89 + src/otari/_generated/docs/UsageEntry.md | 42 + src/otari/_generated/docs/UsageLogResponse.md | 42 + src/otari/_generated/docs/UserResponse.md | 40 + src/otari/_generated/docs/UsersApi.md | 435 +++++ src/otari/_generated/docs/ValidationError.md | 33 + src/otari/_generated/git_push.sh | 57 + .../otari_control_plane/__init__.py | 90 + .../otari_control_plane/api/__init__.py | 9 + .../otari_control_plane/api/budgets_api.py | 1415 ++++++++++++++ .../otari_control_plane/api/keys_api.py | 1416 ++++++++++++++ .../otari_control_plane/api/pricing_api.py | 1439 ++++++++++++++ .../otari_control_plane/api/usage_api.py | 390 ++++ .../otari_control_plane/api/users_api.py | 1713 +++++++++++++++++ .../otari_control_plane/api_client.py | 804 ++++++++ .../otari_control_plane/api_response.py | 21 + .../otari_control_plane/configuration.py | 596 ++++++ .../otari_control_plane/exceptions.py | 218 +++ .../otari_control_plane/models/__init__.py | 33 + .../models/budget_response.py | 106 + .../models/create_budget_request.py | 101 + .../models/create_key_request.py | 110 ++ .../models/create_key_response.py | 117 ++ .../models/create_user_request.py | 106 + .../models/http_validation_error.py | 96 + .../otari_control_plane/models/key_info.py | 122 ++ .../models/location_inner.py | 138 ++ .../models/pricing_response.py | 98 + .../models/set_pricing_request.py | 101 + .../models/update_budget_request.py | 101 + .../models/update_key_request.py | 115 ++ .../models/update_user_request.py | 114 ++ .../otari_control_plane/models/usage_entry.py | 152 ++ .../models/usage_log_response.py | 152 ++ .../models/user_response.py | 128 ++ .../models/validation_error.py | 109 ++ .../_generated/otari_control_plane/py.typed | 0 .../_generated/otari_control_plane/rest.py | 263 +++ src/otari/_generated/pyproject.toml | 94 + src/otari/_generated/requirements.txt | 4 + src/otari/_generated/setup.cfg | 2 + src/otari/_generated/setup.py | 47 + src/otari/_generated/test-requirements.txt | 6 + src/otari/_generated/test/__init__.py | 0 .../_generated/test/test_budget_response.py | 60 + src/otari/_generated/test/test_budgets_api.py | 66 + .../test/test_create_budget_request.py | 52 + .../test/test_create_key_request.py | 54 + .../test/test_create_key_response.py | 66 + .../test/test_create_user_request.py | 56 + .../test/test_http_validation_error.py | 60 + src/otari/_generated/test/test_key_info.py | 66 + src/otari/_generated/test/test_keys_api.py | 66 + .../_generated/test/test_location_inner.py | 50 + src/otari/_generated/test/test_pricing_api.py | 66 + .../_generated/test/test_pricing_response.py | 62 + .../test/test_set_pricing_request.py | 57 + .../test/test_update_budget_request.py | 52 + .../test/test_update_key_request.py | 54 + .../test/test_update_user_request.py | 54 + src/otari/_generated/test/test_usage_api.py | 38 + src/otari/_generated/test/test_usage_entry.py | 76 + .../test/test_usage_log_response.py | 76 + .../_generated/test/test_user_response.py | 72 + src/otari/_generated/test/test_users_api.py | 73 + .../_generated/test/test_validation_error.py | 62 + src/otari/_generated/tox.ini | 9 + 91 files changed, 14540 insertions(+) create mode 100644 src/otari/_generated/.github/workflows/python.yml create mode 100644 src/otari/_generated/.gitignore create mode 100644 src/otari/_generated/.gitlab-ci.yml create mode 100644 src/otari/_generated/.openapi-generator-ignore create mode 100644 src/otari/_generated/.openapi-generator/FILES create mode 100644 src/otari/_generated/.openapi-generator/VERSION create mode 100644 src/otari/_generated/.travis.yml create mode 100644 src/otari/_generated/README.md create mode 100644 src/otari/_generated/docs/BudgetResponse.md create mode 100644 src/otari/_generated/docs/BudgetsApi.md create mode 100644 src/otari/_generated/docs/CreateBudgetRequest.md create mode 100644 src/otari/_generated/docs/CreateKeyRequest.md create mode 100644 src/otari/_generated/docs/CreateKeyResponse.md create mode 100644 src/otari/_generated/docs/CreateUserRequest.md create mode 100644 src/otari/_generated/docs/HTTPValidationError.md create mode 100644 src/otari/_generated/docs/KeyInfo.md create mode 100644 src/otari/_generated/docs/KeysApi.md create mode 100644 src/otari/_generated/docs/LocationInner.md create mode 100644 src/otari/_generated/docs/PricingApi.md create mode 100644 src/otari/_generated/docs/PricingResponse.md create mode 100644 src/otari/_generated/docs/SetPricingRequest.md create mode 100644 src/otari/_generated/docs/UpdateBudgetRequest.md create mode 100644 src/otari/_generated/docs/UpdateKeyRequest.md create mode 100644 src/otari/_generated/docs/UpdateUserRequest.md create mode 100644 src/otari/_generated/docs/UsageApi.md create mode 100644 src/otari/_generated/docs/UsageEntry.md create mode 100644 src/otari/_generated/docs/UsageLogResponse.md create mode 100644 src/otari/_generated/docs/UserResponse.md create mode 100644 src/otari/_generated/docs/UsersApi.md create mode 100644 src/otari/_generated/docs/ValidationError.md create mode 100644 src/otari/_generated/git_push.sh create mode 100644 src/otari/_generated/otari_control_plane/__init__.py create mode 100644 src/otari/_generated/otari_control_plane/api/__init__.py create mode 100644 src/otari/_generated/otari_control_plane/api/budgets_api.py create mode 100644 src/otari/_generated/otari_control_plane/api/keys_api.py create mode 100644 src/otari/_generated/otari_control_plane/api/pricing_api.py create mode 100644 src/otari/_generated/otari_control_plane/api/usage_api.py create mode 100644 src/otari/_generated/otari_control_plane/api/users_api.py create mode 100644 src/otari/_generated/otari_control_plane/api_client.py create mode 100644 src/otari/_generated/otari_control_plane/api_response.py create mode 100644 src/otari/_generated/otari_control_plane/configuration.py create mode 100644 src/otari/_generated/otari_control_plane/exceptions.py create mode 100644 src/otari/_generated/otari_control_plane/models/__init__.py create mode 100644 src/otari/_generated/otari_control_plane/models/budget_response.py create mode 100644 src/otari/_generated/otari_control_plane/models/create_budget_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/create_key_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/create_key_response.py create mode 100644 src/otari/_generated/otari_control_plane/models/create_user_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/http_validation_error.py create mode 100644 src/otari/_generated/otari_control_plane/models/key_info.py create mode 100644 src/otari/_generated/otari_control_plane/models/location_inner.py create mode 100644 src/otari/_generated/otari_control_plane/models/pricing_response.py create mode 100644 src/otari/_generated/otari_control_plane/models/set_pricing_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/update_budget_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/update_key_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/update_user_request.py create mode 100644 src/otari/_generated/otari_control_plane/models/usage_entry.py create mode 100644 src/otari/_generated/otari_control_plane/models/usage_log_response.py create mode 100644 src/otari/_generated/otari_control_plane/models/user_response.py create mode 100644 src/otari/_generated/otari_control_plane/models/validation_error.py create mode 100644 src/otari/_generated/otari_control_plane/py.typed create mode 100644 src/otari/_generated/otari_control_plane/rest.py create mode 100644 src/otari/_generated/pyproject.toml create mode 100644 src/otari/_generated/requirements.txt create mode 100644 src/otari/_generated/setup.cfg create mode 100644 src/otari/_generated/setup.py create mode 100644 src/otari/_generated/test-requirements.txt create mode 100644 src/otari/_generated/test/__init__.py create mode 100644 src/otari/_generated/test/test_budget_response.py create mode 100644 src/otari/_generated/test/test_budgets_api.py create mode 100644 src/otari/_generated/test/test_create_budget_request.py create mode 100644 src/otari/_generated/test/test_create_key_request.py create mode 100644 src/otari/_generated/test/test_create_key_response.py create mode 100644 src/otari/_generated/test/test_create_user_request.py create mode 100644 src/otari/_generated/test/test_http_validation_error.py create mode 100644 src/otari/_generated/test/test_key_info.py create mode 100644 src/otari/_generated/test/test_keys_api.py create mode 100644 src/otari/_generated/test/test_location_inner.py create mode 100644 src/otari/_generated/test/test_pricing_api.py create mode 100644 src/otari/_generated/test/test_pricing_response.py create mode 100644 src/otari/_generated/test/test_set_pricing_request.py create mode 100644 src/otari/_generated/test/test_update_budget_request.py create mode 100644 src/otari/_generated/test/test_update_key_request.py create mode 100644 src/otari/_generated/test/test_update_user_request.py create mode 100644 src/otari/_generated/test/test_usage_api.py create mode 100644 src/otari/_generated/test/test_usage_entry.py create mode 100644 src/otari/_generated/test/test_usage_log_response.py create mode 100644 src/otari/_generated/test/test_user_response.py create mode 100644 src/otari/_generated/test/test_users_api.py create mode 100644 src/otari/_generated/test/test_validation_error.py create mode 100644 src/otari/_generated/tox.ini diff --git a/src/otari/_generated/.github/workflows/python.yml b/src/otari/_generated/.github/workflows/python.yml new file mode 100644 index 0000000..a0af3a0 --- /dev/null +++ b/src/otari/_generated/.github/workflows/python.yml @@ -0,0 +1,34 @@ +# NOTE: This file is auto generated by OpenAPI Generator. +# URL: https://openapi-generator.tech +# +# ref: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: otari_control_plane Python package + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install -r test-requirements.txt + - name: Test with pytest + run: | + pytest --cov=otari_control_plane diff --git a/src/otari/_generated/.gitignore b/src/otari/_generated/.gitignore new file mode 100644 index 0000000..65b06b9 --- /dev/null +++ b/src/otari/_generated/.gitignore @@ -0,0 +1,66 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +venv/ +.venv/ +.python-version +.pytest_cache + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Ipython Notebook +.ipynb_checkpoints diff --git a/src/otari/_generated/.gitlab-ci.yml b/src/otari/_generated/.gitlab-ci.yml new file mode 100644 index 0000000..56c77b7 --- /dev/null +++ b/src/otari/_generated/.gitlab-ci.yml @@ -0,0 +1,31 @@ +# NOTE: This file is auto generated by OpenAPI Generator. +# URL: https://openapi-generator.tech +# +# ref: https://docs.gitlab.com/ee/ci/README.html +# ref: https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml + +stages: + - test + +.pytest: + stage: test + script: + - pip install -r requirements.txt + - pip install -r test-requirements.txt + - pytest --cov=otari_control_plane + +pytest-3.10: + extends: .pytest + image: python:3.10-alpine +pytest-3.11: + extends: .pytest + image: python:3.11-alpine +pytest-3.12: + extends: .pytest + image: python:3.12-alpine +pytest-3.13: + extends: .pytest + image: python:3.13-alpine +pytest-3.14: + extends: .pytest + image: python:3.14-alpine diff --git a/src/otari/_generated/.openapi-generator-ignore b/src/otari/_generated/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/src/otari/_generated/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/src/otari/_generated/.openapi-generator/FILES b/src/otari/_generated/.openapi-generator/FILES new file mode 100644 index 0000000..6d0f285 --- /dev/null +++ b/src/otari/_generated/.openapi-generator/FILES @@ -0,0 +1,89 @@ +.github/workflows/python.yml +.gitignore +.gitlab-ci.yml +.openapi-generator-ignore +.travis.yml +README.md +docs/BudgetResponse.md +docs/BudgetsApi.md +docs/CreateBudgetRequest.md +docs/CreateKeyRequest.md +docs/CreateKeyResponse.md +docs/CreateUserRequest.md +docs/HTTPValidationError.md +docs/KeyInfo.md +docs/KeysApi.md +docs/LocationInner.md +docs/PricingApi.md +docs/PricingResponse.md +docs/SetPricingRequest.md +docs/UpdateBudgetRequest.md +docs/UpdateKeyRequest.md +docs/UpdateUserRequest.md +docs/UsageApi.md +docs/UsageEntry.md +docs/UsageLogResponse.md +docs/UserResponse.md +docs/UsersApi.md +docs/ValidationError.md +git_push.sh +otari_control_plane/__init__.py +otari_control_plane/api/__init__.py +otari_control_plane/api/budgets_api.py +otari_control_plane/api/keys_api.py +otari_control_plane/api/pricing_api.py +otari_control_plane/api/usage_api.py +otari_control_plane/api/users_api.py +otari_control_plane/api_client.py +otari_control_plane/api_response.py +otari_control_plane/configuration.py +otari_control_plane/exceptions.py +otari_control_plane/models/__init__.py +otari_control_plane/models/budget_response.py +otari_control_plane/models/create_budget_request.py +otari_control_plane/models/create_key_request.py +otari_control_plane/models/create_key_response.py +otari_control_plane/models/create_user_request.py +otari_control_plane/models/http_validation_error.py +otari_control_plane/models/key_info.py +otari_control_plane/models/location_inner.py +otari_control_plane/models/pricing_response.py +otari_control_plane/models/set_pricing_request.py +otari_control_plane/models/update_budget_request.py +otari_control_plane/models/update_key_request.py +otari_control_plane/models/update_user_request.py +otari_control_plane/models/usage_entry.py +otari_control_plane/models/usage_log_response.py +otari_control_plane/models/user_response.py +otari_control_plane/models/validation_error.py +otari_control_plane/py.typed +otari_control_plane/rest.py +pyproject.toml +requirements.txt +setup.cfg +setup.py +test-requirements.txt +test/__init__.py +test/test_budget_response.py +test/test_budgets_api.py +test/test_create_budget_request.py +test/test_create_key_request.py +test/test_create_key_response.py +test/test_create_user_request.py +test/test_http_validation_error.py +test/test_key_info.py +test/test_keys_api.py +test/test_location_inner.py +test/test_pricing_api.py +test/test_pricing_response.py +test/test_set_pricing_request.py +test/test_update_budget_request.py +test/test_update_key_request.py +test/test_update_user_request.py +test/test_usage_api.py +test/test_usage_entry.py +test/test_usage_log_response.py +test/test_user_response.py +test/test_users_api.py +test/test_validation_error.py +tox.ini diff --git a/src/otari/_generated/.openapi-generator/VERSION b/src/otari/_generated/.openapi-generator/VERSION new file mode 100644 index 0000000..696eaac --- /dev/null +++ b/src/otari/_generated/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.22.0 diff --git a/src/otari/_generated/.travis.yml b/src/otari/_generated/.travis.yml new file mode 100644 index 0000000..b377cf9 --- /dev/null +++ b/src/otari/_generated/.travis.yml @@ -0,0 +1,17 @@ +# ref: https://docs.travis-ci.com/user/languages/python +language: python +python: + - "3.10" + - "3.11" + - "3.12" + - "3.13" + - "3.14" + # uncomment the following if needed + #- "3.14-dev" # 3.14 development branch + #- "nightly" # nightly build +# command to install dependencies +install: + - "pip install -r requirements.txt" + - "pip install -r test-requirements.txt" +# command to run tests +script: pytest --cov=otari_control_plane diff --git a/src/otari/_generated/README.md b/src/otari/_generated/README.md new file mode 100644 index 0000000..ee135e7 --- /dev/null +++ b/src/otari/_generated/README.md @@ -0,0 +1,143 @@ +# otari-control-plane +A clean FastAPI gateway for otari with API key management + +This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 0.0.0-dev +- Package version: 1.0.0 +- Generator version: 7.22.0 +- Build package: org.openapitools.codegen.languages.PythonClientCodegen + +## Requirements. + +Python 3.10+ + +## Installation & Usage +### pip install + +If the python package is hosted on a repository, you can install directly using: + +```sh +pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git +``` +(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`) + +Then import the package: +```python +import otari_control_plane +``` + +### Setuptools + +Install via [Setuptools](http://pypi.python.org/pypi/setuptools). + +```sh +python setup.py install --user +``` +(or `sudo python setup.py install` to install the package for all users) + +Then import the package: +```python +import otari_control_plane +``` + +### Tests + +Execute `pytest` to run the tests. + +## Getting Started + +Please follow the [installation procedure](#installation--usage) and then run the following: + +```python + +import otari_control_plane +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.BudgetsApi(api_client) + create_budget_request = otari_control_plane.CreateBudgetRequest() # CreateBudgetRequest | + + try: + # Create Budget + api_response = api_instance.create_budget_v1_budgets_post(create_budget_request) + print("The response of BudgetsApi->create_budget_v1_budgets_post:\n") + pprint(api_response) + except ApiException as e: + print("Exception when calling BudgetsApi->create_budget_v1_budgets_post: %s\n" % e) + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*BudgetsApi* | [**create_budget_v1_budgets_post**](docs/BudgetsApi.md#create_budget_v1_budgets_post) | **POST** /v1/budgets | Create Budget +*BudgetsApi* | [**delete_budget_v1_budgets_budget_id_delete**](docs/BudgetsApi.md#delete_budget_v1_budgets_budget_id_delete) | **DELETE** /v1/budgets/{budget_id} | Delete Budget +*BudgetsApi* | [**get_budget_v1_budgets_budget_id_get**](docs/BudgetsApi.md#get_budget_v1_budgets_budget_id_get) | **GET** /v1/budgets/{budget_id} | Get Budget +*BudgetsApi* | [**list_budgets_v1_budgets_get**](docs/BudgetsApi.md#list_budgets_v1_budgets_get) | **GET** /v1/budgets | List Budgets +*BudgetsApi* | [**update_budget_v1_budgets_budget_id_patch**](docs/BudgetsApi.md#update_budget_v1_budgets_budget_id_patch) | **PATCH** /v1/budgets/{budget_id} | Update Budget +*KeysApi* | [**create_key_v1_keys_post**](docs/KeysApi.md#create_key_v1_keys_post) | **POST** /v1/keys | Create Key +*KeysApi* | [**delete_key_v1_keys_key_id_delete**](docs/KeysApi.md#delete_key_v1_keys_key_id_delete) | **DELETE** /v1/keys/{key_id} | Delete Key +*KeysApi* | [**get_key_v1_keys_key_id_get**](docs/KeysApi.md#get_key_v1_keys_key_id_get) | **GET** /v1/keys/{key_id} | Get Key +*KeysApi* | [**list_keys_v1_keys_get**](docs/KeysApi.md#list_keys_v1_keys_get) | **GET** /v1/keys | List Keys +*KeysApi* | [**update_key_v1_keys_key_id_patch**](docs/KeysApi.md#update_key_v1_keys_key_id_patch) | **PATCH** /v1/keys/{key_id} | Update Key +*PricingApi* | [**delete_pricing_v1_pricing_model_key_delete**](docs/PricingApi.md#delete_pricing_v1_pricing_model_key_delete) | **DELETE** /v1/pricing/{model_key} | Delete Pricing +*PricingApi* | [**get_pricing_history_v1_pricing_model_key_history_get**](docs/PricingApi.md#get_pricing_history_v1_pricing_model_key_history_get) | **GET** /v1/pricing/{model_key}/history | Get Pricing History +*PricingApi* | [**get_pricing_v1_pricing_model_key_get**](docs/PricingApi.md#get_pricing_v1_pricing_model_key_get) | **GET** /v1/pricing/{model_key} | Get Pricing +*PricingApi* | [**list_pricing_v1_pricing_get**](docs/PricingApi.md#list_pricing_v1_pricing_get) | **GET** /v1/pricing | List Pricing +*PricingApi* | [**set_pricing_v1_pricing_post**](docs/PricingApi.md#set_pricing_v1_pricing_post) | **POST** /v1/pricing | Set Pricing +*UsageApi* | [**list_usage_v1_usage_get**](docs/UsageApi.md#list_usage_v1_usage_get) | **GET** /v1/usage | List Usage +*UsersApi* | [**create_user_v1_users_post**](docs/UsersApi.md#create_user_v1_users_post) | **POST** /v1/users | Create User +*UsersApi* | [**delete_user_v1_users_user_id_delete**](docs/UsersApi.md#delete_user_v1_users_user_id_delete) | **DELETE** /v1/users/{user_id} | Delete User +*UsersApi* | [**get_user_usage_v1_users_user_id_usage_get**](docs/UsersApi.md#get_user_usage_v1_users_user_id_usage_get) | **GET** /v1/users/{user_id}/usage | Get User Usage +*UsersApi* | [**get_user_v1_users_user_id_get**](docs/UsersApi.md#get_user_v1_users_user_id_get) | **GET** /v1/users/{user_id} | Get User +*UsersApi* | [**list_users_v1_users_get**](docs/UsersApi.md#list_users_v1_users_get) | **GET** /v1/users | List Users +*UsersApi* | [**update_user_v1_users_user_id_patch**](docs/UsersApi.md#update_user_v1_users_user_id_patch) | **PATCH** /v1/users/{user_id} | Update User + + +## Documentation For Models + + - [BudgetResponse](docs/BudgetResponse.md) + - [CreateBudgetRequest](docs/CreateBudgetRequest.md) + - [CreateKeyRequest](docs/CreateKeyRequest.md) + - [CreateKeyResponse](docs/CreateKeyResponse.md) + - [CreateUserRequest](docs/CreateUserRequest.md) + - [HTTPValidationError](docs/HTTPValidationError.md) + - [KeyInfo](docs/KeyInfo.md) + - [LocationInner](docs/LocationInner.md) + - [PricingResponse](docs/PricingResponse.md) + - [SetPricingRequest](docs/SetPricingRequest.md) + - [UpdateBudgetRequest](docs/UpdateBudgetRequest.md) + - [UpdateKeyRequest](docs/UpdateKeyRequest.md) + - [UpdateUserRequest](docs/UpdateUserRequest.md) + - [UsageEntry](docs/UsageEntry.md) + - [UsageLogResponse](docs/UsageLogResponse.md) + - [UserResponse](docs/UserResponse.md) + - [ValidationError](docs/ValidationError.md) + + + +## Documentation For Authorization + +Endpoints do not require authorization. + + +## Author + + + + diff --git a/src/otari/_generated/docs/BudgetResponse.md b/src/otari/_generated/docs/BudgetResponse.md new file mode 100644 index 0000000..74ab026 --- /dev/null +++ b/src/otari/_generated/docs/BudgetResponse.md @@ -0,0 +1,34 @@ +# BudgetResponse + +Response model for budget information. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**budget_duration_sec** | **int** | | +**budget_id** | **str** | | +**created_at** | **str** | | +**max_budget** | **float** | | +**updated_at** | **str** | | + +## Example + +```python +from otari_control_plane.models.budget_response import BudgetResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of BudgetResponse from a JSON string +budget_response_instance = BudgetResponse.from_json(json) +# print the JSON string representation of the object +print(BudgetResponse.to_json()) + +# convert the object into a dict +budget_response_dict = budget_response_instance.to_dict() +# create an instance of BudgetResponse from a dict +budget_response_from_dict = BudgetResponse.from_dict(budget_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/BudgetsApi.md b/src/otari/_generated/docs/BudgetsApi.md new file mode 100644 index 0000000..e0aee0c --- /dev/null +++ b/src/otari/_generated/docs/BudgetsApi.md @@ -0,0 +1,361 @@ +# otari_control_plane.BudgetsApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**create_budget_v1_budgets_post**](BudgetsApi.md#create_budget_v1_budgets_post) | **POST** /v1/budgets | Create Budget +[**delete_budget_v1_budgets_budget_id_delete**](BudgetsApi.md#delete_budget_v1_budgets_budget_id_delete) | **DELETE** /v1/budgets/{budget_id} | Delete Budget +[**get_budget_v1_budgets_budget_id_get**](BudgetsApi.md#get_budget_v1_budgets_budget_id_get) | **GET** /v1/budgets/{budget_id} | Get Budget +[**list_budgets_v1_budgets_get**](BudgetsApi.md#list_budgets_v1_budgets_get) | **GET** /v1/budgets | List Budgets +[**update_budget_v1_budgets_budget_id_patch**](BudgetsApi.md#update_budget_v1_budgets_budget_id_patch) | **PATCH** /v1/budgets/{budget_id} | Update Budget + + +# **create_budget_v1_budgets_post** +> BudgetResponse create_budget_v1_budgets_post(create_budget_request) + +Create Budget + +Create a new budget. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.budget_response import BudgetResponse +from otari_control_plane.models.create_budget_request import CreateBudgetRequest +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.BudgetsApi(api_client) + create_budget_request = otari_control_plane.CreateBudgetRequest() # CreateBudgetRequest | + + try: + # Create Budget + api_response = api_instance.create_budget_v1_budgets_post(create_budget_request) + print("The response of BudgetsApi->create_budget_v1_budgets_post:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling BudgetsApi->create_budget_v1_budgets_post: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **create_budget_request** | [**CreateBudgetRequest**](CreateBudgetRequest.md)| | + +### Return type + +[**BudgetResponse**](BudgetResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **delete_budget_v1_budgets_budget_id_delete** +> delete_budget_v1_budgets_budget_id_delete(budget_id) + +Delete Budget + +Delete a budget. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.BudgetsApi(api_client) + budget_id = 'budget_id_example' # str | + + try: + # Delete Budget + api_instance.delete_budget_v1_budgets_budget_id_delete(budget_id) + except Exception as e: + print("Exception when calling BudgetsApi->delete_budget_v1_budgets_budget_id_delete: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **budget_id** | **str**| | + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_budget_v1_budgets_budget_id_get** +> BudgetResponse get_budget_v1_budgets_budget_id_get(budget_id) + +Get Budget + +Get details of a specific budget. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.budget_response import BudgetResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.BudgetsApi(api_client) + budget_id = 'budget_id_example' # str | + + try: + # Get Budget + api_response = api_instance.get_budget_v1_budgets_budget_id_get(budget_id) + print("The response of BudgetsApi->get_budget_v1_budgets_budget_id_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling BudgetsApi->get_budget_v1_budgets_budget_id_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **budget_id** | **str**| | + +### Return type + +[**BudgetResponse**](BudgetResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_budgets_v1_budgets_get** +> List[BudgetResponse] list_budgets_v1_budgets_get(skip=skip, limit=limit) + +List Budgets + +List all budgets with pagination. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.budget_response import BudgetResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.BudgetsApi(api_client) + skip = 0 # int | (optional) (default to 0) + limit = 100 # int | (optional) (default to 100) + + try: + # List Budgets + api_response = api_instance.list_budgets_v1_budgets_get(skip=skip, limit=limit) + print("The response of BudgetsApi->list_budgets_v1_budgets_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling BudgetsApi->list_budgets_v1_budgets_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **skip** | **int**| | [optional] [default to 0] + **limit** | **int**| | [optional] [default to 100] + +### Return type + +[**List[BudgetResponse]**](BudgetResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **update_budget_v1_budgets_budget_id_patch** +> BudgetResponse update_budget_v1_budgets_budget_id_patch(budget_id, update_budget_request) + +Update Budget + +Update a budget. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.budget_response import BudgetResponse +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.BudgetsApi(api_client) + budget_id = 'budget_id_example' # str | + update_budget_request = otari_control_plane.UpdateBudgetRequest() # UpdateBudgetRequest | + + try: + # Update Budget + api_response = api_instance.update_budget_v1_budgets_budget_id_patch(budget_id, update_budget_request) + print("The response of BudgetsApi->update_budget_v1_budgets_budget_id_patch:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling BudgetsApi->update_budget_v1_budgets_budget_id_patch: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **budget_id** | **str**| | + **update_budget_request** | [**UpdateBudgetRequest**](UpdateBudgetRequest.md)| | + +### Return type + +[**BudgetResponse**](BudgetResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/src/otari/_generated/docs/CreateBudgetRequest.md b/src/otari/_generated/docs/CreateBudgetRequest.md new file mode 100644 index 0000000..c07cf07 --- /dev/null +++ b/src/otari/_generated/docs/CreateBudgetRequest.md @@ -0,0 +1,31 @@ +# CreateBudgetRequest + +Request model for creating a new budget. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**budget_duration_sec** | **int** | Budget duration in seconds (e.g., 86400 for daily, 604800 for weekly) | [optional] +**max_budget** | **float** | Maximum spending limit | [optional] + +## Example + +```python +from otari_control_plane.models.create_budget_request import CreateBudgetRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of CreateBudgetRequest from a JSON string +create_budget_request_instance = CreateBudgetRequest.from_json(json) +# print the JSON string representation of the object +print(CreateBudgetRequest.to_json()) + +# convert the object into a dict +create_budget_request_dict = create_budget_request_instance.to_dict() +# create an instance of CreateBudgetRequest from a dict +create_budget_request_from_dict = CreateBudgetRequest.from_dict(create_budget_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/CreateKeyRequest.md b/src/otari/_generated/docs/CreateKeyRequest.md new file mode 100644 index 0000000..0100894 --- /dev/null +++ b/src/otari/_generated/docs/CreateKeyRequest.md @@ -0,0 +1,33 @@ +# CreateKeyRequest + +Request model for creating a new API key. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**expires_at** | **datetime** | Optional expiration timestamp | [optional] +**key_name** | **str** | Optional name for the key | [optional] +**metadata** | **Dict[str, object]** | Optional metadata | [optional] +**user_id** | **str** | Optional user ID to associate with this key | [optional] + +## Example + +```python +from otari_control_plane.models.create_key_request import CreateKeyRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of CreateKeyRequest from a JSON string +create_key_request_instance = CreateKeyRequest.from_json(json) +# print the JSON string representation of the object +print(CreateKeyRequest.to_json()) + +# convert the object into a dict +create_key_request_dict = create_key_request_instance.to_dict() +# create an instance of CreateKeyRequest from a dict +create_key_request_from_dict = CreateKeyRequest.from_dict(create_key_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/CreateKeyResponse.md b/src/otari/_generated/docs/CreateKeyResponse.md new file mode 100644 index 0000000..a05e916 --- /dev/null +++ b/src/otari/_generated/docs/CreateKeyResponse.md @@ -0,0 +1,37 @@ +# CreateKeyResponse + +Response model for creating a new API key. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**created_at** | **str** | | +**expires_at** | **str** | | +**id** | **str** | | +**is_active** | **bool** | | +**key** | **str** | | +**key_name** | **str** | | +**metadata** | **Dict[str, object]** | | +**user_id** | **str** | | + +## Example + +```python +from otari_control_plane.models.create_key_response import CreateKeyResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of CreateKeyResponse from a JSON string +create_key_response_instance = CreateKeyResponse.from_json(json) +# print the JSON string representation of the object +print(CreateKeyResponse.to_json()) + +# convert the object into a dict +create_key_response_dict = create_key_response_instance.to_dict() +# create an instance of CreateKeyResponse from a dict +create_key_response_from_dict = CreateKeyResponse.from_dict(create_key_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/CreateUserRequest.md b/src/otari/_generated/docs/CreateUserRequest.md new file mode 100644 index 0000000..b2dc2a2 --- /dev/null +++ b/src/otari/_generated/docs/CreateUserRequest.md @@ -0,0 +1,34 @@ +# CreateUserRequest + +Request model for creating a new user. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**alias** | **str** | Optional admin-facing alias | [optional] +**blocked** | **bool** | Whether user is blocked | [optional] [default to False] +**budget_id** | **str** | Optional budget ID | [optional] +**metadata** | **Dict[str, object]** | Optional metadata | [optional] +**user_id** | **str** | Unique user identifier | + +## Example + +```python +from otari_control_plane.models.create_user_request import CreateUserRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of CreateUserRequest from a JSON string +create_user_request_instance = CreateUserRequest.from_json(json) +# print the JSON string representation of the object +print(CreateUserRequest.to_json()) + +# convert the object into a dict +create_user_request_dict = create_user_request_instance.to_dict() +# create an instance of CreateUserRequest from a dict +create_user_request_from_dict = CreateUserRequest.from_dict(create_user_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/HTTPValidationError.md b/src/otari/_generated/docs/HTTPValidationError.md new file mode 100644 index 0000000..9f3ab89 --- /dev/null +++ b/src/otari/_generated/docs/HTTPValidationError.md @@ -0,0 +1,29 @@ +# HTTPValidationError + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**detail** | [**List[ValidationError]**](ValidationError.md) | | [optional] + +## Example + +```python +from otari_control_plane.models.http_validation_error import HTTPValidationError + +# TODO update the JSON string below +json = "{}" +# create an instance of HTTPValidationError from a JSON string +http_validation_error_instance = HTTPValidationError.from_json(json) +# print the JSON string representation of the object +print(HTTPValidationError.to_json()) + +# convert the object into a dict +http_validation_error_dict = http_validation_error_instance.to_dict() +# create an instance of HTTPValidationError from a dict +http_validation_error_from_dict = HTTPValidationError.from_dict(http_validation_error_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/KeyInfo.md b/src/otari/_generated/docs/KeyInfo.md new file mode 100644 index 0000000..fe7b646 --- /dev/null +++ b/src/otari/_generated/docs/KeyInfo.md @@ -0,0 +1,37 @@ +# KeyInfo + +Response model for key information. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**created_at** | **str** | | +**expires_at** | **str** | | +**id** | **str** | | +**is_active** | **bool** | | +**key_name** | **str** | | +**last_used_at** | **str** | | +**metadata** | **Dict[str, object]** | | +**user_id** | **str** | | + +## Example + +```python +from otari_control_plane.models.key_info import KeyInfo + +# TODO update the JSON string below +json = "{}" +# create an instance of KeyInfo from a JSON string +key_info_instance = KeyInfo.from_json(json) +# print the JSON string representation of the object +print(KeyInfo.to_json()) + +# convert the object into a dict +key_info_dict = key_info_instance.to_dict() +# create an instance of KeyInfo from a dict +key_info_from_dict = KeyInfo.from_dict(key_info_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/KeysApi.md b/src/otari/_generated/docs/KeysApi.md new file mode 100644 index 0000000..78698ce --- /dev/null +++ b/src/otari/_generated/docs/KeysApi.md @@ -0,0 +1,374 @@ +# otari_control_plane.KeysApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**create_key_v1_keys_post**](KeysApi.md#create_key_v1_keys_post) | **POST** /v1/keys | Create Key +[**delete_key_v1_keys_key_id_delete**](KeysApi.md#delete_key_v1_keys_key_id_delete) | **DELETE** /v1/keys/{key_id} | Delete Key +[**get_key_v1_keys_key_id_get**](KeysApi.md#get_key_v1_keys_key_id_get) | **GET** /v1/keys/{key_id} | Get Key +[**list_keys_v1_keys_get**](KeysApi.md#list_keys_v1_keys_get) | **GET** /v1/keys | List Keys +[**update_key_v1_keys_key_id_patch**](KeysApi.md#update_key_v1_keys_key_id_patch) | **PATCH** /v1/keys/{key_id} | Update Key + + +# **create_key_v1_keys_post** +> CreateKeyResponse create_key_v1_keys_post(create_key_request) + +Create Key + +Create a new API key. + +Requires master key authentication. + +If user_id is provided, the key will be associated with that user (creates user if it doesn't exist). +If user_id is not provided, a new user will be created automatically and the key will be associated with it. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.create_key_request import CreateKeyRequest +from otari_control_plane.models.create_key_response import CreateKeyResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.KeysApi(api_client) + create_key_request = otari_control_plane.CreateKeyRequest() # CreateKeyRequest | + + try: + # Create Key + api_response = api_instance.create_key_v1_keys_post(create_key_request) + print("The response of KeysApi->create_key_v1_keys_post:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KeysApi->create_key_v1_keys_post: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **create_key_request** | [**CreateKeyRequest**](CreateKeyRequest.md)| | + +### Return type + +[**CreateKeyResponse**](CreateKeyResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **delete_key_v1_keys_key_id_delete** +> delete_key_v1_keys_key_id_delete(key_id) + +Delete Key + +Delete (revoke) an API key. + +Requires master key authentication. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.KeysApi(api_client) + key_id = 'key_id_example' # str | + + try: + # Delete Key + api_instance.delete_key_v1_keys_key_id_delete(key_id) + except Exception as e: + print("Exception when calling KeysApi->delete_key_v1_keys_key_id_delete: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **key_id** | **str**| | + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_key_v1_keys_key_id_get** +> KeyInfo get_key_v1_keys_key_id_get(key_id) + +Get Key + +Get details of a specific API key. + +Requires master key authentication. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.key_info import KeyInfo +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.KeysApi(api_client) + key_id = 'key_id_example' # str | + + try: + # Get Key + api_response = api_instance.get_key_v1_keys_key_id_get(key_id) + print("The response of KeysApi->get_key_v1_keys_key_id_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KeysApi->get_key_v1_keys_key_id_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **key_id** | **str**| | + +### Return type + +[**KeyInfo**](KeyInfo.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_keys_v1_keys_get** +> List[KeyInfo] list_keys_v1_keys_get(skip=skip, limit=limit) + +List Keys + +List all API keys. + +Requires master key authentication. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.key_info import KeyInfo +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.KeysApi(api_client) + skip = 0 # int | (optional) (default to 0) + limit = 100 # int | (optional) (default to 100) + + try: + # List Keys + api_response = api_instance.list_keys_v1_keys_get(skip=skip, limit=limit) + print("The response of KeysApi->list_keys_v1_keys_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KeysApi->list_keys_v1_keys_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **skip** | **int**| | [optional] [default to 0] + **limit** | **int**| | [optional] [default to 100] + +### Return type + +[**List[KeyInfo]**](KeyInfo.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **update_key_v1_keys_key_id_patch** +> KeyInfo update_key_v1_keys_key_id_patch(key_id, update_key_request) + +Update Key + +Update an API key. + +Requires master key authentication. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.key_info import KeyInfo +from otari_control_plane.models.update_key_request import UpdateKeyRequest +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.KeysApi(api_client) + key_id = 'key_id_example' # str | + update_key_request = otari_control_plane.UpdateKeyRequest() # UpdateKeyRequest | + + try: + # Update Key + api_response = api_instance.update_key_v1_keys_key_id_patch(key_id, update_key_request) + print("The response of KeysApi->update_key_v1_keys_key_id_patch:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling KeysApi->update_key_v1_keys_key_id_patch: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **key_id** | **str**| | + **update_key_request** | [**UpdateKeyRequest**](UpdateKeyRequest.md)| | + +### Return type + +[**KeyInfo**](KeyInfo.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/src/otari/_generated/docs/LocationInner.md b/src/otari/_generated/docs/LocationInner.md new file mode 100644 index 0000000..a848752 --- /dev/null +++ b/src/otari/_generated/docs/LocationInner.md @@ -0,0 +1,28 @@ +# LocationInner + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +## Example + +```python +from otari_control_plane.models.location_inner import LocationInner + +# TODO update the JSON string below +json = "{}" +# create an instance of LocationInner from a JSON string +location_inner_instance = LocationInner.from_json(json) +# print the JSON string representation of the object +print(LocationInner.to_json()) + +# convert the object into a dict +location_inner_dict = location_inner_instance.to_dict() +# create an instance of LocationInner from a dict +location_inner_from_dict = LocationInner.from_dict(location_inner_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/PricingApi.md b/src/otari/_generated/docs/PricingApi.md new file mode 100644 index 0000000..3deb4fc --- /dev/null +++ b/src/otari/_generated/docs/PricingApi.md @@ -0,0 +1,362 @@ +# otari_control_plane.PricingApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**delete_pricing_v1_pricing_model_key_delete**](PricingApi.md#delete_pricing_v1_pricing_model_key_delete) | **DELETE** /v1/pricing/{model_key} | Delete Pricing +[**get_pricing_history_v1_pricing_model_key_history_get**](PricingApi.md#get_pricing_history_v1_pricing_model_key_history_get) | **GET** /v1/pricing/{model_key}/history | Get Pricing History +[**get_pricing_v1_pricing_model_key_get**](PricingApi.md#get_pricing_v1_pricing_model_key_get) | **GET** /v1/pricing/{model_key} | Get Pricing +[**list_pricing_v1_pricing_get**](PricingApi.md#list_pricing_v1_pricing_get) | **GET** /v1/pricing | List Pricing +[**set_pricing_v1_pricing_post**](PricingApi.md#set_pricing_v1_pricing_post) | **POST** /v1/pricing | Set Pricing + + +# **delete_pricing_v1_pricing_model_key_delete** +> delete_pricing_v1_pricing_model_key_delete(model_key, effective_at=effective_at) + +Delete Pricing + +Delete pricing entries for a model. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.PricingApi(api_client) + model_key = 'model_key_example' # str | + effective_at = '2013-10-20T19:20:30+01:00' # datetime | ISO datetime identifying a specific pricing row to delete (optional) + + try: + # Delete Pricing + api_instance.delete_pricing_v1_pricing_model_key_delete(model_key, effective_at=effective_at) + except Exception as e: + print("Exception when calling PricingApi->delete_pricing_v1_pricing_model_key_delete: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **model_key** | **str**| | + **effective_at** | **datetime**| ISO datetime identifying a specific pricing row to delete | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_pricing_history_v1_pricing_model_key_history_get** +> List[PricingResponse] get_pricing_history_v1_pricing_model_key_history_get(model_key) + +Get Pricing History + +Return the full pricing history for a model. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.pricing_response import PricingResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.PricingApi(api_client) + model_key = 'model_key_example' # str | + + try: + # Get Pricing History + api_response = api_instance.get_pricing_history_v1_pricing_model_key_history_get(model_key) + print("The response of PricingApi->get_pricing_history_v1_pricing_model_key_history_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling PricingApi->get_pricing_history_v1_pricing_model_key_history_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **model_key** | **str**| | + +### Return type + +[**List[PricingResponse]**](PricingResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_pricing_v1_pricing_model_key_get** +> PricingResponse get_pricing_v1_pricing_model_key_get(model_key, as_of=as_of) + +Get Pricing + +Get pricing for a specific model as of a timestamp. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.pricing_response import PricingResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.PricingApi(api_client) + model_key = 'model_key_example' # str | + as_of = '2013-10-20T19:20:30+01:00' # datetime | ISO datetime for effective lookup (optional) + + try: + # Get Pricing + api_response = api_instance.get_pricing_v1_pricing_model_key_get(model_key, as_of=as_of) + print("The response of PricingApi->get_pricing_v1_pricing_model_key_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling PricingApi->get_pricing_v1_pricing_model_key_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **model_key** | **str**| | + **as_of** | **datetime**| ISO datetime for effective lookup | [optional] + +### Return type + +[**PricingResponse**](PricingResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_pricing_v1_pricing_get** +> List[PricingResponse] list_pricing_v1_pricing_get(skip=skip, limit=limit) + +List Pricing + +List all model pricing. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.pricing_response import PricingResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.PricingApi(api_client) + skip = 0 # int | (optional) (default to 0) + limit = 100 # int | (optional) (default to 100) + + try: + # List Pricing + api_response = api_instance.list_pricing_v1_pricing_get(skip=skip, limit=limit) + print("The response of PricingApi->list_pricing_v1_pricing_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling PricingApi->list_pricing_v1_pricing_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **skip** | **int**| | [optional] [default to 0] + **limit** | **int**| | [optional] [default to 100] + +### Return type + +[**List[PricingResponse]**](PricingResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **set_pricing_v1_pricing_post** +> PricingResponse set_pricing_v1_pricing_post(set_pricing_request) + +Set Pricing + +Set or update pricing for a model. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.pricing_response import PricingResponse +from otari_control_plane.models.set_pricing_request import SetPricingRequest +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.PricingApi(api_client) + set_pricing_request = otari_control_plane.SetPricingRequest() # SetPricingRequest | + + try: + # Set Pricing + api_response = api_instance.set_pricing_v1_pricing_post(set_pricing_request) + print("The response of PricingApi->set_pricing_v1_pricing_post:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling PricingApi->set_pricing_v1_pricing_post: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **set_pricing_request** | [**SetPricingRequest**](SetPricingRequest.md)| | + +### Return type + +[**PricingResponse**](PricingResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/src/otari/_generated/docs/PricingResponse.md b/src/otari/_generated/docs/PricingResponse.md new file mode 100644 index 0000000..2e7b67b --- /dev/null +++ b/src/otari/_generated/docs/PricingResponse.md @@ -0,0 +1,35 @@ +# PricingResponse + +Response model for model pricing. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**created_at** | **str** | | +**effective_at** | **str** | | +**input_price_per_million** | **float** | | +**model_key** | **str** | | +**output_price_per_million** | **float** | | +**updated_at** | **str** | | + +## Example + +```python +from otari_control_plane.models.pricing_response import PricingResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of PricingResponse from a JSON string +pricing_response_instance = PricingResponse.from_json(json) +# print the JSON string representation of the object +print(PricingResponse.to_json()) + +# convert the object into a dict +pricing_response_dict = pricing_response_instance.to_dict() +# create an instance of PricingResponse from a dict +pricing_response_from_dict = PricingResponse.from_dict(pricing_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/SetPricingRequest.md b/src/otari/_generated/docs/SetPricingRequest.md new file mode 100644 index 0000000..2a0cf9b --- /dev/null +++ b/src/otari/_generated/docs/SetPricingRequest.md @@ -0,0 +1,33 @@ +# SetPricingRequest + +Request model for setting model pricing. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**effective_at** | **datetime** | ISO 8601 datetime from which this price applies. Defaults to now if omitted. | [optional] +**input_price_per_million** | **float** | Price per 1M input tokens | +**model_key** | **str** | Model identifier in format 'provider:model' | +**output_price_per_million** | **float** | Price per 1M output tokens | + +## Example + +```python +from otari_control_plane.models.set_pricing_request import SetPricingRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of SetPricingRequest from a JSON string +set_pricing_request_instance = SetPricingRequest.from_json(json) +# print the JSON string representation of the object +print(SetPricingRequest.to_json()) + +# convert the object into a dict +set_pricing_request_dict = set_pricing_request_instance.to_dict() +# create an instance of SetPricingRequest from a dict +set_pricing_request_from_dict = SetPricingRequest.from_dict(set_pricing_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UpdateBudgetRequest.md b/src/otari/_generated/docs/UpdateBudgetRequest.md new file mode 100644 index 0000000..04c5d1d --- /dev/null +++ b/src/otari/_generated/docs/UpdateBudgetRequest.md @@ -0,0 +1,31 @@ +# UpdateBudgetRequest + +Request model for updating a budget. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**budget_duration_sec** | **int** | | [optional] +**max_budget** | **float** | | [optional] + +## Example + +```python +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateBudgetRequest from a JSON string +update_budget_request_instance = UpdateBudgetRequest.from_json(json) +# print the JSON string representation of the object +print(UpdateBudgetRequest.to_json()) + +# convert the object into a dict +update_budget_request_dict = update_budget_request_instance.to_dict() +# create an instance of UpdateBudgetRequest from a dict +update_budget_request_from_dict = UpdateBudgetRequest.from_dict(update_budget_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UpdateKeyRequest.md b/src/otari/_generated/docs/UpdateKeyRequest.md new file mode 100644 index 0000000..214348c --- /dev/null +++ b/src/otari/_generated/docs/UpdateKeyRequest.md @@ -0,0 +1,33 @@ +# UpdateKeyRequest + +Request model for updating a key. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**expires_at** | **datetime** | | [optional] +**is_active** | **bool** | | [optional] +**key_name** | **str** | | [optional] +**metadata** | **Dict[str, object]** | | [optional] + +## Example + +```python +from otari_control_plane.models.update_key_request import UpdateKeyRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateKeyRequest from a JSON string +update_key_request_instance = UpdateKeyRequest.from_json(json) +# print the JSON string representation of the object +print(UpdateKeyRequest.to_json()) + +# convert the object into a dict +update_key_request_dict = update_key_request_instance.to_dict() +# create an instance of UpdateKeyRequest from a dict +update_key_request_from_dict = UpdateKeyRequest.from_dict(update_key_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UpdateUserRequest.md b/src/otari/_generated/docs/UpdateUserRequest.md new file mode 100644 index 0000000..ce0a250 --- /dev/null +++ b/src/otari/_generated/docs/UpdateUserRequest.md @@ -0,0 +1,33 @@ +# UpdateUserRequest + +Request model for updating a user. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**alias** | **str** | | [optional] +**blocked** | **bool** | | [optional] +**budget_id** | **str** | | [optional] +**metadata** | **Dict[str, object]** | | [optional] + +## Example + +```python +from otari_control_plane.models.update_user_request import UpdateUserRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdateUserRequest from a JSON string +update_user_request_instance = UpdateUserRequest.from_json(json) +# print the JSON string representation of the object +print(UpdateUserRequest.to_json()) + +# convert the object into a dict +update_user_request_dict = update_user_request_instance.to_dict() +# create an instance of UpdateUserRequest from a dict +update_user_request_from_dict = UpdateUserRequest.from_dict(update_user_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UsageApi.md b/src/otari/_generated/docs/UsageApi.md new file mode 100644 index 0000000..fad891d --- /dev/null +++ b/src/otari/_generated/docs/UsageApi.md @@ -0,0 +1,89 @@ +# otari_control_plane.UsageApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**list_usage_v1_usage_get**](UsageApi.md#list_usage_v1_usage_get) | **GET** /v1/usage | List Usage + + +# **list_usage_v1_usage_get** +> List[UsageEntry] list_usage_v1_usage_get(start_date=start_date, end_date=end_date, user_id=user_id, skip=skip, limit=limit) + +List Usage + +List usage logs ordered by timestamp (most recent first). + +Supports optional filters for time range and user. Paginated via skip/limit. +Timestamps accept either ISO 8601 strings or Unix epoch seconds (numeric). + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.usage_entry import UsageEntry +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsageApi(api_client) + start_date = '2013-10-20T19:20:30+01:00' # datetime | Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) (optional) + end_date = '2013-10-20T19:20:30+01:00' # datetime | Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) (optional) + user_id = 'user_id_example' # str | Filter to a single user (optional) + skip = 0 # int | (optional) (default to 0) + limit = 100 # int | (optional) (default to 100) + + try: + # List Usage + api_response = api_instance.list_usage_v1_usage_get(start_date=start_date, end_date=end_date, user_id=user_id, skip=skip, limit=limit) + print("The response of UsageApi->list_usage_v1_usage_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UsageApi->list_usage_v1_usage_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **start_date** | **datetime**| Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) | [optional] + **end_date** | **datetime**| Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) | [optional] + **user_id** | **str**| Filter to a single user | [optional] + **skip** | **int**| | [optional] [default to 0] + **limit** | **int**| | [optional] [default to 100] + +### Return type + +[**List[UsageEntry]**](UsageEntry.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/src/otari/_generated/docs/UsageEntry.md b/src/otari/_generated/docs/UsageEntry.md new file mode 100644 index 0000000..1616e8f --- /dev/null +++ b/src/otari/_generated/docs/UsageEntry.md @@ -0,0 +1,42 @@ +# UsageEntry + +A single usage log entry. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**api_key_id** | **str** | | +**completion_tokens** | **int** | | +**cost** | **float** | | +**endpoint** | **str** | | +**error_message** | **str** | | +**id** | **str** | | +**model** | **str** | | +**prompt_tokens** | **int** | | +**provider** | **str** | | +**status** | **str** | | +**timestamp** | **str** | | +**total_tokens** | **int** | | +**user_id** | **str** | | + +## Example + +```python +from otari_control_plane.models.usage_entry import UsageEntry + +# TODO update the JSON string below +json = "{}" +# create an instance of UsageEntry from a JSON string +usage_entry_instance = UsageEntry.from_json(json) +# print the JSON string representation of the object +print(UsageEntry.to_json()) + +# convert the object into a dict +usage_entry_dict = usage_entry_instance.to_dict() +# create an instance of UsageEntry from a dict +usage_entry_from_dict = UsageEntry.from_dict(usage_entry_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UsageLogResponse.md b/src/otari/_generated/docs/UsageLogResponse.md new file mode 100644 index 0000000..2096726 --- /dev/null +++ b/src/otari/_generated/docs/UsageLogResponse.md @@ -0,0 +1,42 @@ +# UsageLogResponse + +Response model for usage log. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**api_key_id** | **str** | | +**completion_tokens** | **int** | | +**cost** | **float** | | +**endpoint** | **str** | | +**error_message** | **str** | | +**id** | **str** | | +**model** | **str** | | +**prompt_tokens** | **int** | | +**provider** | **str** | | +**status** | **str** | | +**timestamp** | **str** | | +**total_tokens** | **int** | | +**user_id** | **str** | | + +## Example + +```python +from otari_control_plane.models.usage_log_response import UsageLogResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of UsageLogResponse from a JSON string +usage_log_response_instance = UsageLogResponse.from_json(json) +# print the JSON string representation of the object +print(UsageLogResponse.to_json()) + +# convert the object into a dict +usage_log_response_dict = usage_log_response_instance.to_dict() +# create an instance of UsageLogResponse from a dict +usage_log_response_from_dict = UsageLogResponse.from_dict(usage_log_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UserResponse.md b/src/otari/_generated/docs/UserResponse.md new file mode 100644 index 0000000..a777d32 --- /dev/null +++ b/src/otari/_generated/docs/UserResponse.md @@ -0,0 +1,40 @@ +# UserResponse + +Response model for user information. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**alias** | **str** | | +**blocked** | **bool** | | +**budget_id** | **str** | | +**budget_started_at** | **str** | | +**created_at** | **str** | | +**metadata** | **Dict[str, object]** | | +**next_budget_reset_at** | **str** | | +**reserved** | **float** | | +**spend** | **float** | | +**updated_at** | **str** | | +**user_id** | **str** | | + +## Example + +```python +from otari_control_plane.models.user_response import UserResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of UserResponse from a JSON string +user_response_instance = UserResponse.from_json(json) +# print the JSON string representation of the object +print(UserResponse.to_json()) + +# convert the object into a dict +user_response_dict = user_response_instance.to_dict() +# create an instance of UserResponse from a dict +user_response_from_dict = UserResponse.from_dict(user_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/docs/UsersApi.md b/src/otari/_generated/docs/UsersApi.md new file mode 100644 index 0000000..9a45b07 --- /dev/null +++ b/src/otari/_generated/docs/UsersApi.md @@ -0,0 +1,435 @@ +# otari_control_plane.UsersApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**create_user_v1_users_post**](UsersApi.md#create_user_v1_users_post) | **POST** /v1/users | Create User +[**delete_user_v1_users_user_id_delete**](UsersApi.md#delete_user_v1_users_user_id_delete) | **DELETE** /v1/users/{user_id} | Delete User +[**get_user_usage_v1_users_user_id_usage_get**](UsersApi.md#get_user_usage_v1_users_user_id_usage_get) | **GET** /v1/users/{user_id}/usage | Get User Usage +[**get_user_v1_users_user_id_get**](UsersApi.md#get_user_v1_users_user_id_get) | **GET** /v1/users/{user_id} | Get User +[**list_users_v1_users_get**](UsersApi.md#list_users_v1_users_get) | **GET** /v1/users | List Users +[**update_user_v1_users_user_id_patch**](UsersApi.md#update_user_v1_users_user_id_patch) | **PATCH** /v1/users/{user_id} | Update User + + +# **create_user_v1_users_post** +> UserResponse create_user_v1_users_post(create_user_request) + +Create User + +Create a new user. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.create_user_request import CreateUserRequest +from otari_control_plane.models.user_response import UserResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsersApi(api_client) + create_user_request = otari_control_plane.CreateUserRequest() # CreateUserRequest | + + try: + # Create User + api_response = api_instance.create_user_v1_users_post(create_user_request) + print("The response of UsersApi->create_user_v1_users_post:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UsersApi->create_user_v1_users_post: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **create_user_request** | [**CreateUserRequest**](CreateUserRequest.md)| | + +### Return type + +[**UserResponse**](UserResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **delete_user_v1_users_user_id_delete** +> delete_user_v1_users_user_id_delete(user_id) + +Delete User + +Delete a user. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsersApi(api_client) + user_id = 'user_id_example' # str | + + try: + # Delete User + api_instance.delete_user_v1_users_user_id_delete(user_id) + except Exception as e: + print("Exception when calling UsersApi->delete_user_v1_users_user_id_delete: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **user_id** | **str**| | + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_user_usage_v1_users_user_id_usage_get** +> List[UsageLogResponse] get_user_usage_v1_users_user_id_usage_get(user_id, skip=skip, limit=limit) + +Get User Usage + +Get usage history for a specific user. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.usage_log_response import UsageLogResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsersApi(api_client) + user_id = 'user_id_example' # str | + skip = 0 # int | (optional) (default to 0) + limit = 100 # int | (optional) (default to 100) + + try: + # Get User Usage + api_response = api_instance.get_user_usage_v1_users_user_id_usage_get(user_id, skip=skip, limit=limit) + print("The response of UsersApi->get_user_usage_v1_users_user_id_usage_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UsersApi->get_user_usage_v1_users_user_id_usage_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **user_id** | **str**| | + **skip** | **int**| | [optional] [default to 0] + **limit** | **int**| | [optional] [default to 100] + +### Return type + +[**List[UsageLogResponse]**](UsageLogResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_user_v1_users_user_id_get** +> UserResponse get_user_v1_users_user_id_get(user_id) + +Get User + +Get details of a specific user. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.user_response import UserResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsersApi(api_client) + user_id = 'user_id_example' # str | + + try: + # Get User + api_response = api_instance.get_user_v1_users_user_id_get(user_id) + print("The response of UsersApi->get_user_v1_users_user_id_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UsersApi->get_user_v1_users_user_id_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **user_id** | **str**| | + +### Return type + +[**UserResponse**](UserResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_users_v1_users_get** +> List[UserResponse] list_users_v1_users_get(skip=skip, limit=limit) + +List Users + +List all users with pagination. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.user_response import UserResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsersApi(api_client) + skip = 0 # int | (optional) (default to 0) + limit = 100 # int | (optional) (default to 100) + + try: + # List Users + api_response = api_instance.list_users_v1_users_get(skip=skip, limit=limit) + print("The response of UsersApi->list_users_v1_users_get:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UsersApi->list_users_v1_users_get: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **skip** | **int**| | [optional] [default to 0] + **limit** | **int**| | [optional] [default to 100] + +### Return type + +[**List[UserResponse]**](UserResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **update_user_v1_users_user_id_patch** +> UserResponse update_user_v1_users_user_id_patch(user_id, update_user_request) + +Update User + +Update a user. + +### Example + + +```python +import otari_control_plane +from otari_control_plane.models.update_user_request import UpdateUserRequest +from otari_control_plane.models.user_response import UserResponse +from otari_control_plane.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = otari_control_plane.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +with otari_control_plane.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = otari_control_plane.UsersApi(api_client) + user_id = 'user_id_example' # str | + update_user_request = otari_control_plane.UpdateUserRequest() # UpdateUserRequest | + + try: + # Update User + api_response = api_instance.update_user_v1_users_user_id_patch(user_id, update_user_request) + print("The response of UsersApi->update_user_v1_users_user_id_patch:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling UsersApi->update_user_v1_users_user_id_patch: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **user_id** | **str**| | + **update_user_request** | [**UpdateUserRequest**](UpdateUserRequest.md)| | + +### Return type + +[**UserResponse**](UserResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/src/otari/_generated/docs/ValidationError.md b/src/otari/_generated/docs/ValidationError.md new file mode 100644 index 0000000..af05c07 --- /dev/null +++ b/src/otari/_generated/docs/ValidationError.md @@ -0,0 +1,33 @@ +# ValidationError + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ctx** | **object** | | [optional] +**input** | **object** | | [optional] +**loc** | [**List[LocationInner]**](LocationInner.md) | | +**msg** | **str** | | +**type** | **str** | | + +## Example + +```python +from otari_control_plane.models.validation_error import ValidationError + +# TODO update the JSON string below +json = "{}" +# create an instance of ValidationError from a JSON string +validation_error_instance = ValidationError.from_json(json) +# print the JSON string representation of the object +print(ValidationError.to_json()) + +# convert the object into a dict +validation_error_dict = validation_error_instance.to_dict() +# create an instance of ValidationError from a dict +validation_error_from_dict = ValidationError.from_dict(validation_error_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/src/otari/_generated/git_push.sh b/src/otari/_generated/git_push.sh new file mode 100644 index 0000000..f53a75d --- /dev/null +++ b/src/otari/_generated/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/src/otari/_generated/otari_control_plane/__init__.py b/src/otari/_generated/otari_control_plane/__init__.py new file mode 100644 index 0000000..b70f9cc --- /dev/null +++ b/src/otari/_generated/otari_control_plane/__init__.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +# flake8: noqa + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +__version__ = "1.0.0" + +# Define package exports +__all__ = [ + "BudgetsApi", + "KeysApi", + "PricingApi", + "UsageApi", + "UsersApi", + "ApiResponse", + "ApiClient", + "Configuration", + "OpenApiException", + "ApiTypeError", + "ApiValueError", + "ApiKeyError", + "ApiAttributeError", + "ApiException", + "BudgetResponse", + "CreateBudgetRequest", + "CreateKeyRequest", + "CreateKeyResponse", + "CreateUserRequest", + "HTTPValidationError", + "KeyInfo", + "LocationInner", + "PricingResponse", + "SetPricingRequest", + "UpdateBudgetRequest", + "UpdateKeyRequest", + "UpdateUserRequest", + "UsageEntry", + "UsageLogResponse", + "UserResponse", + "ValidationError", +] + +# import apis into sdk package +from otari_control_plane.api.budgets_api import BudgetsApi as BudgetsApi +from otari_control_plane.api.keys_api import KeysApi as KeysApi +from otari_control_plane.api.pricing_api import PricingApi as PricingApi +from otari_control_plane.api.usage_api import UsageApi as UsageApi +from otari_control_plane.api.users_api import UsersApi as UsersApi + +# import ApiClient +from otari_control_plane.api_response import ApiResponse as ApiResponse +from otari_control_plane.api_client import ApiClient as ApiClient +from otari_control_plane.configuration import Configuration as Configuration +from otari_control_plane.exceptions import OpenApiException as OpenApiException +from otari_control_plane.exceptions import ApiTypeError as ApiTypeError +from otari_control_plane.exceptions import ApiValueError as ApiValueError +from otari_control_plane.exceptions import ApiKeyError as ApiKeyError +from otari_control_plane.exceptions import ApiAttributeError as ApiAttributeError +from otari_control_plane.exceptions import ApiException as ApiException + +# import models into sdk package +from otari_control_plane.models.budget_response import BudgetResponse as BudgetResponse +from otari_control_plane.models.create_budget_request import CreateBudgetRequest as CreateBudgetRequest +from otari_control_plane.models.create_key_request import CreateKeyRequest as CreateKeyRequest +from otari_control_plane.models.create_key_response import CreateKeyResponse as CreateKeyResponse +from otari_control_plane.models.create_user_request import CreateUserRequest as CreateUserRequest +from otari_control_plane.models.http_validation_error import HTTPValidationError as HTTPValidationError +from otari_control_plane.models.key_info import KeyInfo as KeyInfo +from otari_control_plane.models.location_inner import LocationInner as LocationInner +from otari_control_plane.models.pricing_response import PricingResponse as PricingResponse +from otari_control_plane.models.set_pricing_request import SetPricingRequest as SetPricingRequest +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest as UpdateBudgetRequest +from otari_control_plane.models.update_key_request import UpdateKeyRequest as UpdateKeyRequest +from otari_control_plane.models.update_user_request import UpdateUserRequest as UpdateUserRequest +from otari_control_plane.models.usage_entry import UsageEntry as UsageEntry +from otari_control_plane.models.usage_log_response import UsageLogResponse as UsageLogResponse +from otari_control_plane.models.user_response import UserResponse as UserResponse +from otari_control_plane.models.validation_error import ValidationError as ValidationError + diff --git a/src/otari/_generated/otari_control_plane/api/__init__.py b/src/otari/_generated/otari_control_plane/api/__init__.py new file mode 100644 index 0000000..897ef54 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api/__init__.py @@ -0,0 +1,9 @@ +# flake8: noqa + +# import apis into api package +from otari_control_plane.api.budgets_api import BudgetsApi +from otari_control_plane.api.keys_api import KeysApi +from otari_control_plane.api.pricing_api import PricingApi +from otari_control_plane.api.usage_api import UsageApi +from otari_control_plane.api.users_api import UsersApi + diff --git a/src/otari/_generated/otari_control_plane/api/budgets_api.py b/src/otari/_generated/otari_control_plane/api/budgets_api.py new file mode 100644 index 0000000..374dd38 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api/budgets_api.py @@ -0,0 +1,1415 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import List, Optional +from typing_extensions import Annotated +from otari_control_plane.models.budget_response import BudgetResponse +from otari_control_plane.models.create_budget_request import CreateBudgetRequest +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest + +from otari_control_plane.api_client import ApiClient, RequestSerialized +from otari_control_plane.api_response import ApiResponse +from otari_control_plane.rest import RESTResponseType + + +class BudgetsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_budget_v1_budgets_post( + self, + create_budget_request: CreateBudgetRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BudgetResponse: + """Create Budget + + Create a new budget. + + :param create_budget_request: (required) + :type create_budget_request: CreateBudgetRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_budget_v1_budgets_post_serialize( + create_budget_request=create_budget_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_budget_v1_budgets_post_with_http_info( + self, + create_budget_request: CreateBudgetRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BudgetResponse]: + """Create Budget + + Create a new budget. + + :param create_budget_request: (required) + :type create_budget_request: CreateBudgetRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_budget_v1_budgets_post_serialize( + create_budget_request=create_budget_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_budget_v1_budgets_post_without_preload_content( + self, + create_budget_request: CreateBudgetRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Budget + + Create a new budget. + + :param create_budget_request: (required) + :type create_budget_request: CreateBudgetRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_budget_v1_budgets_post_serialize( + create_budget_request=create_budget_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_budget_v1_budgets_post_serialize( + self, + create_budget_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_budget_request is not None: + _body_params = create_budget_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/budgets', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_budget_v1_budgets_budget_id_delete( + self, + budget_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete Budget + + Delete a budget. + + :param budget_id: (required) + :type budget_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_budget_v1_budgets_budget_id_delete_serialize( + budget_id=budget_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_budget_v1_budgets_budget_id_delete_with_http_info( + self, + budget_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete Budget + + Delete a budget. + + :param budget_id: (required) + :type budget_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_budget_v1_budgets_budget_id_delete_serialize( + budget_id=budget_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_budget_v1_budgets_budget_id_delete_without_preload_content( + self, + budget_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete Budget + + Delete a budget. + + :param budget_id: (required) + :type budget_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_budget_v1_budgets_budget_id_delete_serialize( + budget_id=budget_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_budget_v1_budgets_budget_id_delete_serialize( + self, + budget_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if budget_id is not None: + _path_params['budget_id'] = budget_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/budgets/{budget_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_budget_v1_budgets_budget_id_get( + self, + budget_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BudgetResponse: + """Get Budget + + Get details of a specific budget. + + :param budget_id: (required) + :type budget_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_budget_v1_budgets_budget_id_get_serialize( + budget_id=budget_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_budget_v1_budgets_budget_id_get_with_http_info( + self, + budget_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BudgetResponse]: + """Get Budget + + Get details of a specific budget. + + :param budget_id: (required) + :type budget_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_budget_v1_budgets_budget_id_get_serialize( + budget_id=budget_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_budget_v1_budgets_budget_id_get_without_preload_content( + self, + budget_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Budget + + Get details of a specific budget. + + :param budget_id: (required) + :type budget_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_budget_v1_budgets_budget_id_get_serialize( + budget_id=budget_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_budget_v1_budgets_budget_id_get_serialize( + self, + budget_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if budget_id is not None: + _path_params['budget_id'] = budget_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/budgets/{budget_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_budgets_v1_budgets_get( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[BudgetResponse]: + """List Budgets + + List all budgets with pagination. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_budgets_v1_budgets_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[BudgetResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_budgets_v1_budgets_get_with_http_info( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[BudgetResponse]]: + """List Budgets + + List all budgets with pagination. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_budgets_v1_budgets_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[BudgetResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_budgets_v1_budgets_get_without_preload_content( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Budgets + + List all budgets with pagination. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_budgets_v1_budgets_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[BudgetResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_budgets_v1_budgets_get_serialize( + self, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/budgets', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def update_budget_v1_budgets_budget_id_patch( + self, + budget_id: StrictStr, + update_budget_request: UpdateBudgetRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BudgetResponse: + """Update Budget + + Update a budget. + + :param budget_id: (required) + :type budget_id: str + :param update_budget_request: (required) + :type update_budget_request: UpdateBudgetRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_budget_v1_budgets_budget_id_patch_serialize( + budget_id=budget_id, + update_budget_request=update_budget_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_budget_v1_budgets_budget_id_patch_with_http_info( + self, + budget_id: StrictStr, + update_budget_request: UpdateBudgetRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BudgetResponse]: + """Update Budget + + Update a budget. + + :param budget_id: (required) + :type budget_id: str + :param update_budget_request: (required) + :type update_budget_request: UpdateBudgetRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_budget_v1_budgets_budget_id_patch_serialize( + budget_id=budget_id, + update_budget_request=update_budget_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_budget_v1_budgets_budget_id_patch_without_preload_content( + self, + budget_id: StrictStr, + update_budget_request: UpdateBudgetRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update Budget + + Update a budget. + + :param budget_id: (required) + :type budget_id: str + :param update_budget_request: (required) + :type update_budget_request: UpdateBudgetRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_budget_v1_budgets_budget_id_patch_serialize( + budget_id=budget_id, + update_budget_request=update_budget_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BudgetResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_budget_v1_budgets_budget_id_patch_serialize( + self, + budget_id, + update_budget_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if budget_id is not None: + _path_params['budget_id'] = budget_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if update_budget_request is not None: + _body_params = update_budget_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/v1/budgets/{budget_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_generated/otari_control_plane/api/keys_api.py b/src/otari/_generated/otari_control_plane/api/keys_api.py new file mode 100644 index 0000000..dc61a0f --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api/keys_api.py @@ -0,0 +1,1416 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import List, Optional +from typing_extensions import Annotated +from otari_control_plane.models.create_key_request import CreateKeyRequest +from otari_control_plane.models.create_key_response import CreateKeyResponse +from otari_control_plane.models.key_info import KeyInfo +from otari_control_plane.models.update_key_request import UpdateKeyRequest + +from otari_control_plane.api_client import ApiClient, RequestSerialized +from otari_control_plane.api_response import ApiResponse +from otari_control_plane.rest import RESTResponseType + + +class KeysApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_key_v1_keys_post( + self, + create_key_request: CreateKeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> CreateKeyResponse: + """Create Key + + Create a new API key. Requires master key authentication. If user_id is provided, the key will be associated with that user (creates user if it doesn't exist). If user_id is not provided, a new user will be created automatically and the key will be associated with it. + + :param create_key_request: (required) + :type create_key_request: CreateKeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_key_v1_keys_post_serialize( + create_key_request=create_key_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "CreateKeyResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_key_v1_keys_post_with_http_info( + self, + create_key_request: CreateKeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[CreateKeyResponse]: + """Create Key + + Create a new API key. Requires master key authentication. If user_id is provided, the key will be associated with that user (creates user if it doesn't exist). If user_id is not provided, a new user will be created automatically and the key will be associated with it. + + :param create_key_request: (required) + :type create_key_request: CreateKeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_key_v1_keys_post_serialize( + create_key_request=create_key_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "CreateKeyResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_key_v1_keys_post_without_preload_content( + self, + create_key_request: CreateKeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Key + + Create a new API key. Requires master key authentication. If user_id is provided, the key will be associated with that user (creates user if it doesn't exist). If user_id is not provided, a new user will be created automatically and the key will be associated with it. + + :param create_key_request: (required) + :type create_key_request: CreateKeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_key_v1_keys_post_serialize( + create_key_request=create_key_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "CreateKeyResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_key_v1_keys_post_serialize( + self, + create_key_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_key_request is not None: + _body_params = create_key_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/keys', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_key_v1_keys_key_id_delete( + self, + key_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete Key + + Delete (revoke) an API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_key_v1_keys_key_id_delete_serialize( + key_id=key_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_key_v1_keys_key_id_delete_with_http_info( + self, + key_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete Key + + Delete (revoke) an API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_key_v1_keys_key_id_delete_serialize( + key_id=key_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_key_v1_keys_key_id_delete_without_preload_content( + self, + key_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete Key + + Delete (revoke) an API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_key_v1_keys_key_id_delete_serialize( + key_id=key_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_key_v1_keys_key_id_delete_serialize( + self, + key_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if key_id is not None: + _path_params['key_id'] = key_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/keys/{key_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_key_v1_keys_key_id_get( + self, + key_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> KeyInfo: + """Get Key + + Get details of a specific API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_key_v1_keys_key_id_get_serialize( + key_id=key_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "KeyInfo", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_key_v1_keys_key_id_get_with_http_info( + self, + key_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[KeyInfo]: + """Get Key + + Get details of a specific API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_key_v1_keys_key_id_get_serialize( + key_id=key_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "KeyInfo", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_key_v1_keys_key_id_get_without_preload_content( + self, + key_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Key + + Get details of a specific API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_key_v1_keys_key_id_get_serialize( + key_id=key_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "KeyInfo", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_key_v1_keys_key_id_get_serialize( + self, + key_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if key_id is not None: + _path_params['key_id'] = key_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/keys/{key_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_keys_v1_keys_get( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[KeyInfo]: + """List Keys + + List all API keys. Requires master key authentication. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_keys_v1_keys_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[KeyInfo]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_keys_v1_keys_get_with_http_info( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[KeyInfo]]: + """List Keys + + List all API keys. Requires master key authentication. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_keys_v1_keys_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[KeyInfo]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_keys_v1_keys_get_without_preload_content( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Keys + + List all API keys. Requires master key authentication. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_keys_v1_keys_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[KeyInfo]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_keys_v1_keys_get_serialize( + self, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/keys', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def update_key_v1_keys_key_id_patch( + self, + key_id: StrictStr, + update_key_request: UpdateKeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> KeyInfo: + """Update Key + + Update an API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param update_key_request: (required) + :type update_key_request: UpdateKeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_key_v1_keys_key_id_patch_serialize( + key_id=key_id, + update_key_request=update_key_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "KeyInfo", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_key_v1_keys_key_id_patch_with_http_info( + self, + key_id: StrictStr, + update_key_request: UpdateKeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[KeyInfo]: + """Update Key + + Update an API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param update_key_request: (required) + :type update_key_request: UpdateKeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_key_v1_keys_key_id_patch_serialize( + key_id=key_id, + update_key_request=update_key_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "KeyInfo", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_key_v1_keys_key_id_patch_without_preload_content( + self, + key_id: StrictStr, + update_key_request: UpdateKeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update Key + + Update an API key. Requires master key authentication. + + :param key_id: (required) + :type key_id: str + :param update_key_request: (required) + :type update_key_request: UpdateKeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_key_v1_keys_key_id_patch_serialize( + key_id=key_id, + update_key_request=update_key_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "KeyInfo", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_key_v1_keys_key_id_patch_serialize( + self, + key_id, + update_key_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if key_id is not None: + _path_params['key_id'] = key_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if update_key_request is not None: + _body_params = update_key_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/v1/keys/{key_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_generated/otari_control_plane/api/pricing_api.py b/src/otari/_generated/otari_control_plane/api/pricing_api.py new file mode 100644 index 0000000..2e2bf80 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api/pricing_api.py @@ -0,0 +1,1439 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from datetime import datetime +from pydantic import Field, StrictStr +from typing import List, Optional +from typing_extensions import Annotated +from otari_control_plane.models.pricing_response import PricingResponse +from otari_control_plane.models.set_pricing_request import SetPricingRequest + +from otari_control_plane.api_client import ApiClient, RequestSerialized +from otari_control_plane.api_response import ApiResponse +from otari_control_plane.rest import RESTResponseType + + +class PricingApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def delete_pricing_v1_pricing_model_key_delete( + self, + model_key: StrictStr, + effective_at: Annotated[Optional[datetime], Field(description="ISO datetime identifying a specific pricing row to delete")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete Pricing + + Delete pricing entries for a model. + + :param model_key: (required) + :type model_key: str + :param effective_at: ISO datetime identifying a specific pricing row to delete + :type effective_at: datetime + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_pricing_v1_pricing_model_key_delete_serialize( + model_key=model_key, + effective_at=effective_at, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_pricing_v1_pricing_model_key_delete_with_http_info( + self, + model_key: StrictStr, + effective_at: Annotated[Optional[datetime], Field(description="ISO datetime identifying a specific pricing row to delete")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete Pricing + + Delete pricing entries for a model. + + :param model_key: (required) + :type model_key: str + :param effective_at: ISO datetime identifying a specific pricing row to delete + :type effective_at: datetime + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_pricing_v1_pricing_model_key_delete_serialize( + model_key=model_key, + effective_at=effective_at, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_pricing_v1_pricing_model_key_delete_without_preload_content( + self, + model_key: StrictStr, + effective_at: Annotated[Optional[datetime], Field(description="ISO datetime identifying a specific pricing row to delete")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete Pricing + + Delete pricing entries for a model. + + :param model_key: (required) + :type model_key: str + :param effective_at: ISO datetime identifying a specific pricing row to delete + :type effective_at: datetime + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_pricing_v1_pricing_model_key_delete_serialize( + model_key=model_key, + effective_at=effective_at, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_pricing_v1_pricing_model_key_delete_serialize( + self, + model_key, + effective_at, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if model_key is not None: + _path_params['model_key'] = model_key + # process the query parameters + if effective_at is not None: + if isinstance(effective_at, datetime): + _query_params.append( + ( + 'effective_at', + effective_at.strftime( + self.api_client.configuration.datetime_format + ) + ) + ) + else: + _query_params.append(('effective_at', effective_at)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/pricing/{model_key}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_pricing_history_v1_pricing_model_key_history_get( + self, + model_key: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[PricingResponse]: + """Get Pricing History + + Return the full pricing history for a model. + + :param model_key: (required) + :type model_key: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_pricing_history_v1_pricing_model_key_history_get_serialize( + model_key=model_key, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[PricingResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_pricing_history_v1_pricing_model_key_history_get_with_http_info( + self, + model_key: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[PricingResponse]]: + """Get Pricing History + + Return the full pricing history for a model. + + :param model_key: (required) + :type model_key: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_pricing_history_v1_pricing_model_key_history_get_serialize( + model_key=model_key, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[PricingResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_pricing_history_v1_pricing_model_key_history_get_without_preload_content( + self, + model_key: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Pricing History + + Return the full pricing history for a model. + + :param model_key: (required) + :type model_key: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_pricing_history_v1_pricing_model_key_history_get_serialize( + model_key=model_key, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[PricingResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_pricing_history_v1_pricing_model_key_history_get_serialize( + self, + model_key, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if model_key is not None: + _path_params['model_key'] = model_key + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/pricing/{model_key}/history', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_pricing_v1_pricing_model_key_get( + self, + model_key: StrictStr, + as_of: Annotated[Optional[datetime], Field(description="ISO datetime for effective lookup")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> PricingResponse: + """Get Pricing + + Get pricing for a specific model as of a timestamp. + + :param model_key: (required) + :type model_key: str + :param as_of: ISO datetime for effective lookup + :type as_of: datetime + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_pricing_v1_pricing_model_key_get_serialize( + model_key=model_key, + as_of=as_of, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "PricingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_pricing_v1_pricing_model_key_get_with_http_info( + self, + model_key: StrictStr, + as_of: Annotated[Optional[datetime], Field(description="ISO datetime for effective lookup")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[PricingResponse]: + """Get Pricing + + Get pricing for a specific model as of a timestamp. + + :param model_key: (required) + :type model_key: str + :param as_of: ISO datetime for effective lookup + :type as_of: datetime + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_pricing_v1_pricing_model_key_get_serialize( + model_key=model_key, + as_of=as_of, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "PricingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_pricing_v1_pricing_model_key_get_without_preload_content( + self, + model_key: StrictStr, + as_of: Annotated[Optional[datetime], Field(description="ISO datetime for effective lookup")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Pricing + + Get pricing for a specific model as of a timestamp. + + :param model_key: (required) + :type model_key: str + :param as_of: ISO datetime for effective lookup + :type as_of: datetime + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_pricing_v1_pricing_model_key_get_serialize( + model_key=model_key, + as_of=as_of, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "PricingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_pricing_v1_pricing_model_key_get_serialize( + self, + model_key, + as_of, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if model_key is not None: + _path_params['model_key'] = model_key + # process the query parameters + if as_of is not None: + if isinstance(as_of, datetime): + _query_params.append( + ( + 'as_of', + as_of.strftime( + self.api_client.configuration.datetime_format + ) + ) + ) + else: + _query_params.append(('as_of', as_of)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/pricing/{model_key}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_pricing_v1_pricing_get( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[PricingResponse]: + """List Pricing + + List all model pricing. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_pricing_v1_pricing_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[PricingResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_pricing_v1_pricing_get_with_http_info( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[PricingResponse]]: + """List Pricing + + List all model pricing. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_pricing_v1_pricing_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[PricingResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_pricing_v1_pricing_get_without_preload_content( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Pricing + + List all model pricing. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_pricing_v1_pricing_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[PricingResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_pricing_v1_pricing_get_serialize( + self, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/pricing', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def set_pricing_v1_pricing_post( + self, + set_pricing_request: SetPricingRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> PricingResponse: + """Set Pricing + + Set or update pricing for a model. + + :param set_pricing_request: (required) + :type set_pricing_request: SetPricingRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._set_pricing_v1_pricing_post_serialize( + set_pricing_request=set_pricing_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "PricingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def set_pricing_v1_pricing_post_with_http_info( + self, + set_pricing_request: SetPricingRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[PricingResponse]: + """Set Pricing + + Set or update pricing for a model. + + :param set_pricing_request: (required) + :type set_pricing_request: SetPricingRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._set_pricing_v1_pricing_post_serialize( + set_pricing_request=set_pricing_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "PricingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def set_pricing_v1_pricing_post_without_preload_content( + self, + set_pricing_request: SetPricingRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Set Pricing + + Set or update pricing for a model. + + :param set_pricing_request: (required) + :type set_pricing_request: SetPricingRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._set_pricing_v1_pricing_post_serialize( + set_pricing_request=set_pricing_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "PricingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _set_pricing_v1_pricing_post_serialize( + self, + set_pricing_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if set_pricing_request is not None: + _body_params = set_pricing_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/pricing', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_generated/otari_control_plane/api/usage_api.py b/src/otari/_generated/otari_control_plane/api/usage_api.py new file mode 100644 index 0000000..3406dff --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api/usage_api.py @@ -0,0 +1,390 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from datetime import datetime +from pydantic import Field, StrictStr +from typing import List, Optional +from typing_extensions import Annotated +from otari_control_plane.models.usage_entry import UsageEntry + +from otari_control_plane.api_client import ApiClient, RequestSerialized +from otari_control_plane.api_response import ApiResponse +from otari_control_plane.rest import RESTResponseType + + +class UsageApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def list_usage_v1_usage_get( + self, + start_date: Annotated[Optional[datetime], Field(description="Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds)")] = None, + end_date: Annotated[Optional[datetime], Field(description="Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds)")] = None, + user_id: Annotated[Optional[StrictStr], Field(description="Filter to a single user")] = None, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[UsageEntry]: + """List Usage + + List usage logs ordered by timestamp (most recent first). Supports optional filters for time range and user. Paginated via skip/limit. Timestamps accept either ISO 8601 strings or Unix epoch seconds (numeric). + + :param start_date: Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) + :type start_date: datetime + :param end_date: Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) + :type end_date: datetime + :param user_id: Filter to a single user + :type user_id: str + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_usage_v1_usage_get_serialize( + start_date=start_date, + end_date=end_date, + user_id=user_id, + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UsageEntry]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_usage_v1_usage_get_with_http_info( + self, + start_date: Annotated[Optional[datetime], Field(description="Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds)")] = None, + end_date: Annotated[Optional[datetime], Field(description="Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds)")] = None, + user_id: Annotated[Optional[StrictStr], Field(description="Filter to a single user")] = None, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[UsageEntry]]: + """List Usage + + List usage logs ordered by timestamp (most recent first). Supports optional filters for time range and user. Paginated via skip/limit. Timestamps accept either ISO 8601 strings or Unix epoch seconds (numeric). + + :param start_date: Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) + :type start_date: datetime + :param end_date: Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) + :type end_date: datetime + :param user_id: Filter to a single user + :type user_id: str + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_usage_v1_usage_get_serialize( + start_date=start_date, + end_date=end_date, + user_id=user_id, + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UsageEntry]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_usage_v1_usage_get_without_preload_content( + self, + start_date: Annotated[Optional[datetime], Field(description="Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds)")] = None, + end_date: Annotated[Optional[datetime], Field(description="Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds)")] = None, + user_id: Annotated[Optional[StrictStr], Field(description="Filter to a single user")] = None, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Usage + + List usage logs ordered by timestamp (most recent first). Supports optional filters for time range and user. Paginated via skip/limit. Timestamps accept either ISO 8601 strings or Unix epoch seconds (numeric). + + :param start_date: Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) + :type start_date: datetime + :param end_date: Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) + :type end_date: datetime + :param user_id: Filter to a single user + :type user_id: str + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_usage_v1_usage_get_serialize( + start_date=start_date, + end_date=end_date, + user_id=user_id, + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UsageEntry]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_usage_v1_usage_get_serialize( + self, + start_date, + end_date, + user_id, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if start_date is not None: + if isinstance(start_date, datetime): + _query_params.append( + ( + 'start_date', + start_date.strftime( + self.api_client.configuration.datetime_format + ) + ) + ) + else: + _query_params.append(('start_date', start_date)) + + if end_date is not None: + if isinstance(end_date, datetime): + _query_params.append( + ( + 'end_date', + end_date.strftime( + self.api_client.configuration.datetime_format + ) + ) + ) + else: + _query_params.append(('end_date', end_date)) + + if user_id is not None: + + _query_params.append(('user_id', user_id)) + + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/usage', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_generated/otari_control_plane/api/users_api.py b/src/otari/_generated/otari_control_plane/api/users_api.py new file mode 100644 index 0000000..5c369d6 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api/users_api.py @@ -0,0 +1,1713 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import List, Optional +from typing_extensions import Annotated +from otari_control_plane.models.create_user_request import CreateUserRequest +from otari_control_plane.models.update_user_request import UpdateUserRequest +from otari_control_plane.models.usage_log_response import UsageLogResponse +from otari_control_plane.models.user_response import UserResponse + +from otari_control_plane.api_client import ApiClient, RequestSerialized +from otari_control_plane.api_response import ApiResponse +from otari_control_plane.rest import RESTResponseType + + +class UsersApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_user_v1_users_post( + self, + create_user_request: CreateUserRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> UserResponse: + """Create User + + Create a new user. + + :param create_user_request: (required) + :type create_user_request: CreateUserRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_user_v1_users_post_serialize( + create_user_request=create_user_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_user_v1_users_post_with_http_info( + self, + create_user_request: CreateUserRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[UserResponse]: + """Create User + + Create a new user. + + :param create_user_request: (required) + :type create_user_request: CreateUserRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_user_v1_users_post_serialize( + create_user_request=create_user_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_user_v1_users_post_without_preload_content( + self, + create_user_request: CreateUserRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create User + + Create a new user. + + :param create_user_request: (required) + :type create_user_request: CreateUserRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_user_v1_users_post_serialize( + create_user_request=create_user_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_user_v1_users_post_serialize( + self, + create_user_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_user_request is not None: + _body_params = create_user_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/users', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_user_v1_users_user_id_delete( + self, + user_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete User + + Delete a user. + + :param user_id: (required) + :type user_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_user_v1_users_user_id_delete_serialize( + user_id=user_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_user_v1_users_user_id_delete_with_http_info( + self, + user_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete User + + Delete a user. + + :param user_id: (required) + :type user_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_user_v1_users_user_id_delete_serialize( + user_id=user_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_user_v1_users_user_id_delete_without_preload_content( + self, + user_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete User + + Delete a user. + + :param user_id: (required) + :type user_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_user_v1_users_user_id_delete_serialize( + user_id=user_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_user_v1_users_user_id_delete_serialize( + self, + user_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if user_id is not None: + _path_params['user_id'] = user_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/users/{user_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_user_usage_v1_users_user_id_usage_get( + self, + user_id: StrictStr, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[UsageLogResponse]: + """Get User Usage + + Get usage history for a specific user. + + :param user_id: (required) + :type user_id: str + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_user_usage_v1_users_user_id_usage_get_serialize( + user_id=user_id, + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UsageLogResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_user_usage_v1_users_user_id_usage_get_with_http_info( + self, + user_id: StrictStr, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[UsageLogResponse]]: + """Get User Usage + + Get usage history for a specific user. + + :param user_id: (required) + :type user_id: str + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_user_usage_v1_users_user_id_usage_get_serialize( + user_id=user_id, + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UsageLogResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_user_usage_v1_users_user_id_usage_get_without_preload_content( + self, + user_id: StrictStr, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get User Usage + + Get usage history for a specific user. + + :param user_id: (required) + :type user_id: str + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_user_usage_v1_users_user_id_usage_get_serialize( + user_id=user_id, + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UsageLogResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_user_usage_v1_users_user_id_usage_get_serialize( + self, + user_id, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if user_id is not None: + _path_params['user_id'] = user_id + # process the query parameters + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/users/{user_id}/usage', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_user_v1_users_user_id_get( + self, + user_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> UserResponse: + """Get User + + Get details of a specific user. + + :param user_id: (required) + :type user_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_user_v1_users_user_id_get_serialize( + user_id=user_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_user_v1_users_user_id_get_with_http_info( + self, + user_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[UserResponse]: + """Get User + + Get details of a specific user. + + :param user_id: (required) + :type user_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_user_v1_users_user_id_get_serialize( + user_id=user_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_user_v1_users_user_id_get_without_preload_content( + self, + user_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get User + + Get details of a specific user. + + :param user_id: (required) + :type user_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_user_v1_users_user_id_get_serialize( + user_id=user_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_user_v1_users_user_id_get_serialize( + self, + user_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if user_id is not None: + _path_params['user_id'] = user_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/users/{user_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_users_v1_users_get( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> List[UserResponse]: + """List Users + + List all users with pagination. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_users_v1_users_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UserResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_users_v1_users_get_with_http_info( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[List[UserResponse]]: + """List Users + + List all users with pagination. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_users_v1_users_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UserResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_users_v1_users_get_without_preload_content( + self, + skip: Optional[Annotated[int, Field(strict=True, ge=0)]] = None, + limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Users + + List all users with pagination. + + :param skip: + :type skip: int + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_users_v1_users_get_serialize( + skip=skip, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "List[UserResponse]", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_users_v1_users_get_serialize( + self, + skip, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if skip is not None: + + _query_params.append(('skip', skip)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/users', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def update_user_v1_users_user_id_patch( + self, + user_id: StrictStr, + update_user_request: UpdateUserRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> UserResponse: + """Update User + + Update a user. + + :param user_id: (required) + :type user_id: str + :param update_user_request: (required) + :type update_user_request: UpdateUserRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_user_v1_users_user_id_patch_serialize( + user_id=user_id, + update_user_request=update_user_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_user_v1_users_user_id_patch_with_http_info( + self, + user_id: StrictStr, + update_user_request: UpdateUserRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[UserResponse]: + """Update User + + Update a user. + + :param user_id: (required) + :type user_id: str + :param update_user_request: (required) + :type update_user_request: UpdateUserRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_user_v1_users_user_id_patch_serialize( + user_id=user_id, + update_user_request=update_user_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_user_v1_users_user_id_patch_without_preload_content( + self, + user_id: StrictStr, + update_user_request: UpdateUserRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update User + + Update a user. + + :param user_id: (required) + :type user_id: str + :param update_user_request: (required) + :type update_user_request: UpdateUserRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_user_v1_users_user_id_patch_serialize( + user_id=user_id, + update_user_request=update_user_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "UserResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_user_v1_users_user_id_patch_serialize( + self, + user_id, + update_user_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if user_id is not None: + _path_params['user_id'] = user_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if update_user_request is not None: + _body_params = update_user_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/v1/users/{user_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_generated/otari_control_plane/api_client.py b/src/otari/_generated/otari_control_plane/api_client.py new file mode 100644 index 0000000..10bf7a6 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api_client.py @@ -0,0 +1,804 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + + +import datetime +from dateutil.parser import parse +from enum import Enum +import decimal +import json +import mimetypes +import os +import re +import tempfile +import uuid + +from urllib.parse import quote +from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr + +from otari_control_plane.configuration import Configuration +from otari_control_plane.api_response import ApiResponse, T as ApiResponseT +import otari_control_plane.models +from otari_control_plane import rest +from otari_control_plane.exceptions import ( + ApiValueError, + ApiException, + BadRequestException, + UnauthorizedException, + ForbiddenException, + NotFoundException, + ServiceException +) + +RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]] + +class ApiClient: + """Generic API client for OpenAPI client library builds. + + OpenAPI generic API client. This client handles the client- + server communication, and is invariant across implementations. Specifics of + the methods and models for each application are generated from the OpenAPI + templates. + + :param configuration: .Configuration object for this client + :param header_name: a header to pass when making calls to the API. + :param header_value: a header value to pass when making calls to + the API. + :param cookie: a cookie to include in the header when making calls + to the API + """ + + PRIMITIVE_TYPES = (float, bool, bytes, str, int) + NATIVE_TYPES_MAPPING = { + 'int': int, + 'long': int, # TODO remove as only py3 is supported? + 'float': float, + 'str': str, + 'bool': bool, + 'date': datetime.date, + 'datetime': datetime.datetime, + 'decimal': decimal.Decimal, + 'UUID': uuid.UUID, + 'object': object, + } + _pool = None + + def __init__( + self, + configuration=None, + header_name=None, + header_value=None, + cookie=None + ) -> None: + # use default configuration if none is provided + if configuration is None: + configuration = Configuration.get_default() + self.configuration = configuration + + self.rest_client = rest.RESTClientObject(configuration) + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value + self.cookie = cookie + # Set default User-Agent. + self.user_agent = 'OpenAPI-Generator/1.0.0/python' + self.client_side_validation = configuration.client_side_validation + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + pass + + @property + def user_agent(self): + """User agent for this API client""" + return self.default_headers['User-Agent'] + + @user_agent.setter + def user_agent(self, value): + self.default_headers['User-Agent'] = value + + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value + + + _default = None + + @classmethod + def get_default(cls): + """Return new instance of ApiClient. + + This method returns newly created, based on default constructor, + object of ApiClient class or returns a copy of default + ApiClient. + + :return: The ApiClient object. + """ + if cls._default is None: + cls._default = ApiClient() + return cls._default + + @classmethod + def set_default(cls, default): + """Set default instance of ApiClient. + + It stores default ApiClient. + + :param default: object of ApiClient. + """ + cls._default = default + + def param_serialize( + self, + method, + resource_path, + path_params=None, + query_params=None, + header_params=None, + body=None, + post_params=None, + files=None, auth_settings=None, + collection_formats=None, + _host=None, + _request_auth=None + ) -> RequestSerialized: + + """Builds the HTTP request params needed by the request. + :param method: Method to call. + :param resource_path: Path to method endpoint. + :param path_params: Path parameters in the url. + :param query_params: Query parameters in the url. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param auth_settings list: Auth Settings names for the request. + :param files dict: key -> filename, value -> filepath, + for `multipart/form-data`. + :param collection_formats: dict of collection formats for path, query, + header, and post parameters. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :return: tuple of form (path, http_method, query_params, header_params, + body, post_params, files) + """ + + config = self.configuration + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params['Cookie'] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict( + self.parameters_to_tuples(header_params,collection_formats) + ) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples( + path_params, + collection_formats + ) + for k, v in path_params: + # specified safe chars, encode everything + resource_path = resource_path.replace( + '{%s}' % k, + quote(str(v), safe=config.safe_chars_for_path_param) + ) + + # post parameters + if post_params or files: + post_params = post_params if post_params else [] + post_params = self.sanitize_for_serialization(post_params) + post_params = self.parameters_to_tuples( + post_params, + collection_formats + ) + if files: + post_params.extend(self.files_parameters(files)) + + # auth setting + self.update_params_for_auth( + header_params, + query_params, + auth_settings, + resource_path, + method, + body, + request_auth=_request_auth + ) + + # body + if body: + body = self.sanitize_for_serialization(body) + + # request url + if _host is None or self.configuration.ignore_operation_servers: + url = self.configuration.host + resource_path + else: + # use server/host defined in path or operation instead + url = _host + resource_path + + # query parameters + if query_params: + query_params = self.sanitize_for_serialization(query_params) + url_query = self.parameters_to_url_query( + query_params, + collection_formats + ) + url += "?" + url_query + + return method, url, header_params, body, post_params + + + def call_api( + self, + method, + url, + header_params=None, + body=None, + post_params=None, + _request_timeout=None + ) -> rest.RESTResponse: + """Makes the HTTP request (synchronous) + :param method: Method to call. + :param url: Path to method endpoint. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param _request_timeout: timeout setting for this request. + :return: RESTResponse + """ + + try: + # perform request and return response + response_data = self.rest_client.request( + method, url, + headers=header_params, + body=body, post_params=post_params, + _request_timeout=_request_timeout + ) + + except ApiException as e: + raise e + + return response_data + + def response_deserialize( + self, + response_data: rest.RESTResponse, + response_types_map: Optional[Dict[str, ApiResponseT]]=None + ) -> ApiResponse[ApiResponseT]: + """Deserializes response into an object. + :param response_data: RESTResponse object to be deserialized. + :param response_types_map: dict of response types. + :return: ApiResponse + """ + + msg = "RESTResponse.read() must be called before passing it to response_deserialize()" + assert response_data.data is not None, msg + + response_type = response_types_map.get(str(response_data.status), None) + if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: + # if not found, look for '1XX', '2XX', etc. + response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) + + # deserialize response data + response_text = None + return_data = None + try: + if response_type in ("bytearray", "bytes"): + return_data = response_data.data + elif response_type == "file": + return_data = self.__deserialize_file(response_data) + elif response_type is not None: + match = None + content_type = response_data.headers.get('content-type') + if content_type is not None: + match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) + encoding = match.group(1) if match else "utf-8" + response_text = response_data.data.decode(encoding) + return_data = self.deserialize(response_text, response_type, content_type) + finally: + if not 200 <= response_data.status <= 299: + raise ApiException.from_response( + http_resp=response_data, + body=response_text, + data=return_data, + ) + + return ApiResponse( + status_code = response_data.status, + data = return_data, + headers = response_data.headers, + raw_data = response_data.data + ) + + def sanitize_for_serialization(self, obj): + """Builds a JSON POST object. + + If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() + If obj is str, int, long, float, bool, return directly. + If obj is datetime.datetime, datetime.date + convert to string in iso8601 format. + If obj is decimal.Decimal return string representation. + If obj is list, sanitize each element in the list. + If obj is dict, return the dict. + If obj is OpenAPI model, return the properties dict. + + :param obj: The data to serialize. + :return: The serialized form of data. + """ + if obj is None: + return None + elif isinstance(obj, Enum): + return obj.value + elif isinstance(obj, SecretStr): + return obj.get_secret_value() + elif isinstance(obj, self.PRIMITIVE_TYPES): + return obj + elif isinstance(obj, uuid.UUID): + return str(obj) + elif isinstance(obj, list): + return [ + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ] + elif isinstance(obj, tuple): + return tuple( + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ) + elif isinstance(obj, (datetime.datetime, datetime.date)): + return obj.isoformat() + elif isinstance(obj, decimal.Decimal): + return str(obj) + elif isinstance(obj, dict): + return { + key: self.sanitize_for_serialization(val) + for key, val in obj.items() + } + + # Convert model obj to dict except + # attributes `openapi_types`, `attribute_map` + # and attributes which value is not None. + # Convert attribute name to json key in + # model definition for request. + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ + + return self.sanitize_for_serialization(obj_dict) + + + def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]): + """Deserializes response into an object. + + :param response: RESTResponse object to be deserialized. + :param response_type: class literal for + deserialized object, or string of class name. + :param content_type: content type of response. + + :return: deserialized object. + """ + + # fetch data from response object + if content_type is None: + try: + data = json.loads(response_text) + except ValueError: + data = response_text + elif re.match(r'^application/(json|[\w!#$&.+\-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE): + if response_text == "": + data = "" + else: + data = json.loads(response_text) + elif re.match(r'^text\/[a-z.+-]+\s*(;|$)', content_type, re.IGNORECASE): + data = response_text + else: + raise ApiException( + status=0, + reason="Unsupported content type: {0}".format(content_type) + ) + + return self.__deserialize(data, response_type) + + def __deserialize(self, data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if isinstance(klass, str): + if klass.startswith('List['): + m = re.match(r'List\[(.*)]', klass) + assert m is not None, "Malformed List type definition" + sub_kls = m.group(1) + return [self.__deserialize(sub_data, sub_kls) + for sub_data in data] + + if klass.startswith('Dict['): + m = re.match(r'Dict\[([^,]*), (.*)]', klass) + assert m is not None, "Malformed Dict type definition" + sub_kls = m.group(2) + return {k: self.__deserialize(v, sub_kls) + for k, v in data.items()} + + # convert str to class + if klass in self.NATIVE_TYPES_MAPPING: + klass = self.NATIVE_TYPES_MAPPING[klass] + else: + klass = getattr(otari_control_plane.models, klass) + + if klass in self.PRIMITIVE_TYPES: + return self.__deserialize_primitive(data, klass) + elif klass is object: + return self.__deserialize_object(data) + elif klass is datetime.date: + return self.__deserialize_date(data) + elif klass is datetime.datetime: + return self.__deserialize_datetime(data) + elif klass is decimal.Decimal: + return decimal.Decimal(data) + elif klass is uuid.UUID: + return uuid.UUID(data) + elif issubclass(klass, Enum): + return self.__deserialize_enum(data, klass) + else: + return self.__deserialize_model(data, klass) + + def parameters_to_tuples(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: Parameters as list of tuples, collections formatted + """ + new_params: List[Tuple[str, str]] = [] + if collection_formats is None: + collection_formats = {} + for k, v in params.items() if isinstance(params, dict) else params: + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == 'multi': + new_params.extend((k, value) for value in v) + else: + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' + else: # csv is the default + delimiter = ',' + new_params.append( + (k, delimiter.join(str(value) for value in v))) + else: + new_params.append((k, v)) + return new_params + + def parameters_to_url_query(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: URL query string (e.g. a=Hello%20World&b=123) + """ + new_params: List[Tuple[str, str]] = [] + if collection_formats is None: + collection_formats = {} + for k, v in params.items() if isinstance(params, dict) else params: + if isinstance(v, bool): + v = str(v).lower() + if isinstance(v, (int, float)): + v = str(v) + if isinstance(v, dict): + v = json.dumps(v) + + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == 'multi': + new_params.extend((k, quote(str(value))) for value in v) + else: + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' + else: # csv is the default + delimiter = ',' + new_params.append( + (k, delimiter.join(quote(str(value)) for value in v)) + ) + else: + new_params.append((k, quote(str(v)))) + + return "&".join(["=".join(map(str, item)) for item in new_params]) + + def files_parameters( + self, + files: Dict[str, Union[str, bytes, List[str], List[bytes], Tuple[str, bytes]]], + ): + """Builds form parameters. + + :param files: File parameters. + :return: Form parameters with files. + """ + params = [] + for k, v in files.items(): + if isinstance(v, str): + with open(v, 'rb') as f: + filename = os.path.basename(f.name) + filedata = f.read() + elif isinstance(v, bytes): + filename = k + filedata = v + elif isinstance(v, tuple): + filename, filedata = v + elif isinstance(v, list): + for file_param in v: + params.extend(self.files_parameters({k: file_param})) + continue + else: + raise ValueError("Unsupported file value") + mimetype = ( + mimetypes.guess_type(filename)[0] + or 'application/octet-stream' + ) + params.append( + tuple([k, tuple([filename, filedata, mimetype])]) + ) + return params + + def select_header_accept(self, accepts: List[str]) -> Optional[str]: + """Returns `Accept` based on an array of accepts provided. + + :param accepts: List of headers. + :return: Accept (e.g. application/json). + """ + if not accepts: + return None + + for accept in accepts: + if re.search('json', accept, re.IGNORECASE): + return accept + + return accepts[0] + + def select_header_content_type(self, content_types): + """Returns `Content-Type` based on an array of content_types provided. + + :param content_types: List of content-types. + :return: Content-Type (e.g. application/json). + """ + if not content_types: + return None + + for content_type in content_types: + if re.search('json', content_type, re.IGNORECASE): + return content_type + + return content_types[0] + + def update_params_for_auth( + self, + headers, + queries, + auth_settings, + resource_path, + method, + body, + request_auth=None + ) -> None: + """Updates header and query params based on authentication setting. + + :param headers: Header parameters dict to be updated. + :param queries: Query parameters tuple list to be updated. + :param auth_settings: Authentication setting identifiers list. + :resource_path: A string representation of the HTTP request resource path. + :method: A string representation of the HTTP request method. + :body: A object representing the body of the HTTP request. + The object type is the return value of sanitize_for_serialization(). + :param request_auth: if set, the provided settings will + override the token in the configuration. + """ + if not auth_settings: + return + + if request_auth: + self._apply_auth_params( + headers, + queries, + resource_path, + method, + body, + request_auth + ) + else: + for auth in auth_settings: + auth_setting = self.configuration.auth_settings().get(auth) + if auth_setting: + self._apply_auth_params( + headers, + queries, + resource_path, + method, + body, + auth_setting + ) + + def _apply_auth_params( + self, + headers, + queries, + resource_path, + method, + body, + auth_setting + ) -> None: + """Updates the request parameters based on a single auth_setting + + :param headers: Header parameters dict to be updated. + :param queries: Query parameters tuple list to be updated. + :resource_path: A string representation of the HTTP request resource path. + :method: A string representation of the HTTP request method. + :body: A object representing the body of the HTTP request. + The object type is the return value of sanitize_for_serialization(). + :param auth_setting: auth settings for the endpoint + """ + if auth_setting['in'] == 'cookie': + headers['Cookie'] = auth_setting['value'] + elif auth_setting['in'] == 'header': + if auth_setting['type'] != 'http-signature': + headers[auth_setting['key']] = auth_setting['value'] + elif auth_setting['in'] == 'query': + queries.append((auth_setting['key'], auth_setting['value'])) + else: + raise ApiValueError( + 'Authentication token must be in `query` or `header`' + ) + + def __deserialize_file(self, response): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + handle file downloading + save response body into a tmp file and return the instance + + :param response: RESTResponse. + :return: file path. + """ + fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + content_disposition = response.headers.get("Content-Disposition") + if content_disposition: + m = re.search( + r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition + ) + assert m is not None, "Unexpected 'content-disposition' header value" + filename = os.path.basename(m.group(1)) # Strip any directory traversal + if filename in ("", ".", ".."): # fall back to tmp filename + filename = os.path.basename(path) + path = os.path.join(os.path.dirname(path), filename) + + with open(path, "wb") as f: + f.write(response.data) + + return path + + def __deserialize_primitive(self, data, klass): + """Deserializes string to primitive type. + + :param data: str. + :param klass: class literal. + + :return: int, long, float, str, bool. + """ + try: + return klass(data) + except UnicodeEncodeError: + return str(data) + except TypeError: + return data + + def __deserialize_object(self, value): + """Return an original value. + + :return: object. + """ + return value + + def __deserialize_date(self, string): + """Deserializes string to date. + + :param string: str. + :return: date. + """ + try: + return parse(string).date() + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason="Failed to parse `{0}` as date object".format(string) + ) + + def __deserialize_datetime(self, string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :return: datetime. + """ + try: + return parse(string) + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason=( + "Failed to parse `{0}` as datetime object" + .format(string) + ) + ) + + def __deserialize_enum(self, data, klass): + """Deserializes primitive type to enum. + + :param data: primitive type. + :param klass: class literal. + :return: enum value. + """ + try: + return klass(data) + except ValueError: + raise rest.ApiException( + status=0, + reason=( + "Failed to parse `{0}` as `{1}`" + .format(data, klass) + ) + ) + + def __deserialize_model(self, data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :param klass: class literal. + :return: model object. + """ + + return klass.from_dict(data) diff --git a/src/otari/_generated/otari_control_plane/api_response.py b/src/otari/_generated/otari_control_plane/api_response.py new file mode 100644 index 0000000..9bc7c11 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/api_response.py @@ -0,0 +1,21 @@ +"""API response object.""" + +from __future__ import annotations +from typing import Optional, Generic, Mapping, TypeVar +from pydantic import Field, StrictInt, StrictBytes, BaseModel + +T = TypeVar("T") + +class ApiResponse(BaseModel, Generic[T]): + """ + API response object + """ + + status_code: StrictInt = Field(description="HTTP status code") + headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers") + data: T = Field(description="Deserialized data given the data type") + raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") + + model_config = { + "arbitrary_types_allowed": True + } diff --git a/src/otari/_generated/otari_control_plane/configuration.py b/src/otari/_generated/otari_control_plane/configuration.py new file mode 100644 index 0000000..5712416 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/configuration.py @@ -0,0 +1,596 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import copy +import http.client as httplib +import logging +from logging import FileHandler +import multiprocessing +import sys +from typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union +from typing_extensions import NotRequired, Self + +import urllib3 + + +JSON_SCHEMA_VALIDATION_KEYWORDS = { + 'multipleOf', 'maximum', 'exclusiveMaximum', + 'minimum', 'exclusiveMinimum', 'maxLength', + 'minLength', 'pattern', 'maxItems', 'minItems' +} + +ServerVariablesT = Dict[str, str] + +GenericAuthSetting = TypedDict( + "GenericAuthSetting", + { + "type": str, + "in": str, + "key": str, + "value": str, + }, +) + + +OAuth2AuthSetting = TypedDict( + "OAuth2AuthSetting", + { + "type": Literal["oauth2"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": str, + }, +) + + +APIKeyAuthSetting = TypedDict( + "APIKeyAuthSetting", + { + "type": Literal["api_key"], + "in": str, + "key": str, + "value": Optional[str], + }, +) + + +BasicAuthSetting = TypedDict( + "BasicAuthSetting", + { + "type": Literal["basic"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": Optional[str], + }, +) + + +BearerFormatAuthSetting = TypedDict( + "BearerFormatAuthSetting", + { + "type": Literal["bearer"], + "in": Literal["header"], + "format": Literal["JWT"], + "key": Literal["Authorization"], + "value": str, + }, +) + + +BearerAuthSetting = TypedDict( + "BearerAuthSetting", + { + "type": Literal["bearer"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": str, + }, +) + + +HTTPSignatureAuthSetting = TypedDict( + "HTTPSignatureAuthSetting", + { + "type": Literal["http-signature"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": None, + }, +) + + +AuthSettings = TypedDict( + "AuthSettings", + { + }, + total=False, +) + + +class HostSettingVariable(TypedDict): + description: str + default_value: str + enum_values: List[str] + + +class HostSetting(TypedDict): + url: str + description: str + variables: NotRequired[Dict[str, HostSettingVariable]] + + +class Configuration: + """This class contains various settings of the API client. + + :param host: Base url. + :param ignore_operation_servers + Boolean to ignore operation servers for the API client. + Config will use `host` as the base url regardless of the operation servers. + :param api_key: Dict to store API key(s). + Each entry in the dict specifies an API key. + The dict key is the name of the security scheme in the OAS specification. + The dict value is the API key secret. + :param api_key_prefix: Dict to store API prefix (e.g. Bearer). + The dict key is the name of the security scheme in the OAS specification. + The dict value is an API key prefix when generating the auth data. + :param username: Username for HTTP basic authentication. + :param password: Password for HTTP basic authentication. + :param access_token: Access token. + :param server_index: Index to servers configuration. + :param server_variables: Mapping with string values to replace variables in + templated server configuration. The validation of enums is performed for + variables with defined enum values before. + :param server_operation_index: Mapping from operation ID to an index to server + configuration. + :param server_operation_variables: Mapping from operation ID to a mapping with + string values to replace variables in templated server configuration. + The validation of enums is performed for variables with defined enum + values before. + :param verify_ssl: bool - Set this to false to skip verifying SSL certificate + when calling API from https server. + :param ssl_ca_cert: str - the path to a file of concatenated CA certificates + in PEM format. + :param retries: int | urllib3.util.retry.Retry - Retry configuration. + :param ca_cert_data: verify the peer using concatenated CA certificate data + in PEM (str) or DER (bytes) format. + :param cert_file: the path to a client certificate file, for mTLS. + :param key_file: the path to a client key file, for mTLS. + :param assert_hostname: Set this to True/False to enable/disable SSL hostname verification. + :param tls_server_name: SSL/TLS Server Name Indication (SNI). Set this to the SNI value expected by the server. + :param connection_pool_maxsize: Connection pool max size. None in the constructor is coerced to 100 for async and cpu_count * 5 for sync. + :param proxy: Proxy URL. + :param proxy_headers: Proxy headers. + :param safe_chars_for_path_param: Safe characters for path parameter encoding. + :param client_side_validation: Enable client-side validation. Default True. + :param socket_options: Options to pass down to the underlying urllib3 socket. + :param datetime_format: Datetime format string for serialization. + :param date_format: Date format string for serialization. + + """ + + _default: ClassVar[Optional[Self]] = None + + def __init__( + self, + host: Optional[str]=None, + api_key: Optional[Dict[str, str]]=None, + api_key_prefix: Optional[Dict[str, str]]=None, + username: Optional[str]=None, + password: Optional[str]=None, + access_token: Optional[str]=None, + server_index: Optional[int]=None, + server_variables: Optional[ServerVariablesT]=None, + server_operation_index: Optional[Dict[int, int]]=None, + server_operation_variables: Optional[Dict[int, ServerVariablesT]]=None, + ignore_operation_servers: bool=False, + ssl_ca_cert: Optional[str]=None, + retries: Optional[Union[int, urllib3.util.retry.Retry]] = None, + ca_cert_data: Optional[Union[str, bytes]] = None, + cert_file: Optional[str]=None, + key_file: Optional[str]=None, + verify_ssl: bool=True, + assert_hostname: Optional[bool]=None, + tls_server_name: Optional[str]=None, + connection_pool_maxsize: Optional[int]=None, + proxy: Optional[str]=None, + proxy_headers: Optional[Any]=None, + safe_chars_for_path_param: str='', + client_side_validation: bool=True, + socket_options: Optional[Any]=None, + datetime_format: str="%Y-%m-%dT%H:%M:%S.%f%z", + date_format: str="%Y-%m-%d", + *, + debug: Optional[bool] = None, + ) -> None: + """Constructor + """ + self._base_path = "http://localhost" if host is None else host + """Default Base url + """ + self.server_index = 0 if server_index is None and host is None else server_index + self.server_operation_index = server_operation_index or {} + """Default server index + """ + self.server_variables = server_variables or {} + self.server_operation_variables = server_operation_variables or {} + """Default server variables + """ + self.ignore_operation_servers = ignore_operation_servers + """Ignore operation servers + """ + self.temp_folder_path = None + """Temp file folder for downloading files + """ + # Authentication Settings + self.api_key = {} + if api_key: + self.api_key = api_key + """dict to store API key(s) + """ + self.api_key_prefix = {} + if api_key_prefix: + self.api_key_prefix = api_key_prefix + """dict to store API prefix (e.g. Bearer) + """ + self.refresh_api_key_hook = None + """function hook to refresh API key if expired + """ + self.username = username + """Username for HTTP basic authentication + """ + self.password = password + """Password for HTTP basic authentication + """ + self.access_token = access_token + """Access token + """ + self.logger = {} + """Logging Settings + """ + self.logger["package_logger"] = logging.getLogger("otari_control_plane") + self.logger["urllib3_logger"] = logging.getLogger("urllib3") + self.logger_format = '%(asctime)s %(levelname)s %(message)s' + """Log format + """ + self.logger_stream_handler = None + """Log stream handler + """ + self.logger_file_handler: Optional[FileHandler] = None + """Log file handler + """ + self.logger_file = None + """Debug file location + """ + if debug is not None: + self.debug = debug + else: + self.__debug = False + """Debug switch + """ + + self.verify_ssl = verify_ssl + """SSL/TLS verification + Set this to false to skip verifying SSL certificate when calling API + from https server. + """ + self.ssl_ca_cert = ssl_ca_cert + """Set this to customize the certificate file to verify the peer. + """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ + self.cert_file = cert_file + """client certificate file + """ + self.key_file = key_file + """client key file + """ + self.assert_hostname = assert_hostname + """Set this to True/False to enable/disable SSL hostname verification. + """ + self.tls_server_name = tls_server_name + """SSL/TLS Server Name Indication (SNI) + Set this to the SNI value expected by the server. + """ + + self.connection_pool_maxsize = connection_pool_maxsize if connection_pool_maxsize is not None else multiprocessing.cpu_count() * 5 + """urllib3 connection pool's maximum number of connections saved + per pool. None in the constructor is coerced to cpu_count * 5. + """ + + self.proxy = proxy + """Proxy URL + """ + self.proxy_headers = proxy_headers + """Proxy headers + """ + self.safe_chars_for_path_param = safe_chars_for_path_param + """Safe chars for path_param + """ + self.retries = retries + """Retry configuration + """ + # Enable client side validation + self.client_side_validation = client_side_validation + + self.socket_options = socket_options + """Options to pass down to the underlying urllib3 socket + """ + + self.datetime_format = datetime_format + """datetime format + """ + + self.date_format = date_format + """date format + """ + + def __deepcopy__(self, memo: Dict[int, Any]) -> Self: + cls = self.__class__ + result = cls.__new__(cls) + memo[id(self)] = result + for k, v in self.__dict__.items(): + if k not in ('logger', 'logger_file_handler'): + setattr(result, k, copy.deepcopy(v, memo)) + # shallow copy of loggers + result.logger = copy.copy(self.logger) + # use setters to configure loggers + result.logger_file = self.logger_file + result.debug = self.debug + return result + + def __setattr__(self, name: str, value: Any) -> None: + object.__setattr__(self, name, value) + + @classmethod + def set_default(cls, default: Optional[Self]) -> None: + """Set default instance of configuration. + + It stores default configuration, which can be + returned by get_default_copy method. + + :param default: object of Configuration + """ + cls._default = default + + @classmethod + def get_default_copy(cls) -> Self: + """Deprecated. Please use `get_default` instead. + + Deprecated. Please use `get_default` instead. + + :return: The configuration object. + """ + return cls.get_default() + + @classmethod + def get_default(cls) -> Self: + """Return the default configuration. + + This method returns newly created, based on default constructor, + object of Configuration class or returns a copy of default + configuration. + + :return: The configuration object. + """ + if cls._default is None: + cls._default = cls() + return cls._default + + @property + def logger_file(self) -> Optional[str]: + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + return self.__logger_file + + @logger_file.setter + def logger_file(self, value: Optional[str]) -> None: + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + self.__logger_file = value + if self.__logger_file: + # If set logging file, + # then add file handler and remove stream handler. + self.logger_file_handler = logging.FileHandler(self.__logger_file) + self.logger_file_handler.setFormatter(self.logger_formatter) + for _, logger in self.logger.items(): + logger.addHandler(self.logger_file_handler) + + @property + def debug(self) -> bool: + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + return self.__debug + + @debug.setter + def debug(self, value: bool) -> None: + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + self.__debug = value + if self.__debug: + # if debug status is True, turn on debug logging + for _, logger in self.logger.items(): + logger.setLevel(logging.DEBUG) + # turn on httplib debug + httplib.HTTPConnection.debuglevel = 1 + else: + # if debug status is False, turn off debug logging, + # setting log level to default `logging.WARNING` + for _, logger in self.logger.items(): + logger.setLevel(logging.WARNING) + # turn off httplib debug + httplib.HTTPConnection.debuglevel = 0 + + @property + def logger_format(self) -> str: + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + return self.__logger_format + + @logger_format.setter + def logger_format(self, value: str) -> None: + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + self.__logger_format = value + self.logger_formatter = logging.Formatter(self.__logger_format) + + def get_api_key_with_prefix(self, identifier: str, alias: Optional[str]=None) -> Optional[str]: + """Gets API key (with prefix if set). + + :param identifier: The identifier of apiKey. + :param alias: The alternative identifier of apiKey. + :return: The token for api key authentication. + """ + if self.refresh_api_key_hook is not None: + self.refresh_api_key_hook(self) + key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None) + if key: + prefix = self.api_key_prefix.get(identifier) + if prefix: + return "%s %s" % (prefix, key) + else: + return key + + return None + + def get_basic_auth_token(self) -> Optional[str]: + """Gets HTTP basic authentication header (string). + + :return: The token for basic HTTP authentication. + """ + username = "" + if self.username is not None: + username = self.username + password = "" + if self.password is not None: + password = self.password + + return urllib3.util.make_headers( + basic_auth=username + ':' + password + ).get('authorization') + + def auth_settings(self)-> AuthSettings: + """Gets Auth Settings dict for api client. + + :return: The Auth Settings information dict. + """ + auth: AuthSettings = {} + return auth + + def to_debug_report(self) -> str: + """Gets the essential information for debugging. + + :return: The report for debugging. + """ + return "Python SDK Debug Report:\n"\ + "OS: {env}\n"\ + "Python Version: {pyversion}\n"\ + "Version of the API: 0.0.0-dev\n"\ + "SDK Package Version: 1.0.0".\ + format(env=sys.platform, pyversion=sys.version) + + def get_host_settings(self) -> List[HostSetting]: + """Gets an array of host settings + + :return: An array of host settings + """ + return [ + { + 'url': "", + 'description': "No description provided", + } + ] + + def get_host_from_settings( + self, + index: Optional[int], + variables: Optional[ServerVariablesT]=None, + servers: Optional[List[HostSetting]]=None, + ) -> str: + """Gets host URL based on the index and variables + :param index: array index of the host settings + :param variables: hash of variable and the corresponding value + :param servers: an array of host settings or None + :return: URL based on host settings + """ + if index is None: + return self._base_path + + variables = {} if variables is None else variables + servers = self.get_host_settings() if servers is None else servers + + try: + server = servers[index] + except IndexError: + raise ValueError( + "Invalid index {0} when selecting the host settings. " + "Must be less than {1}".format(index, len(servers))) + + url = server['url'] + + # go through variables and replace placeholders + for variable_name, variable in server.get('variables', {}).items(): + used_value = variables.get( + variable_name, variable['default_value']) + + if 'enum_values' in variable \ + and variable['enum_values'] \ + and used_value not in variable['enum_values']: + raise ValueError( + "The variable `{0}` in the host URL has invalid value " + "{1}. Must be {2}.".format( + variable_name, variables[variable_name], + variable['enum_values'])) + + url = url.replace("{" + variable_name + "}", used_value) + + return url + + @property + def host(self) -> str: + """Return generated host.""" + return self.get_host_from_settings(self.server_index, variables=self.server_variables) + + @host.setter + def host(self, value: str) -> None: + """Fix base path.""" + self._base_path = value + self.server_index = None diff --git a/src/otari/_generated/otari_control_plane/exceptions.py b/src/otari/_generated/otari_control_plane/exceptions.py new file mode 100644 index 0000000..2a606c6 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/exceptions.py @@ -0,0 +1,218 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from typing import Any, Optional +from typing_extensions import Self + +class OpenApiException(Exception): + """The base exception class for all OpenAPIExceptions""" + + +class ApiTypeError(OpenApiException, TypeError): + def __init__(self, msg, path_to_item=None, valid_classes=None, + key_type=None) -> None: + """ Raises an exception for TypeErrors + + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (list): a list of keys an indices to get to the + current_item + None if unset + valid_classes (tuple): the primitive classes that current item + should be an instance of + None if unset + key_type (bool): False if our value is a value in a dict + True if it is a key in a dict + False if our item is an item in a list + None if unset + """ + self.path_to_item = path_to_item + self.valid_classes = valid_classes + self.key_type = key_type + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiTypeError, self).__init__(full_msg) + + +class ApiValueError(OpenApiException, ValueError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (list) the path to the exception in the + received_data dict. None if unset + """ + + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiValueError, self).__init__(full_msg) + + +class ApiAttributeError(OpenApiException, AttributeError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Raised when an attribute reference or assignment fails. + + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (None/list) the path to the exception in the + received_data dict + """ + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiAttributeError, self).__init__(full_msg) + + +class ApiKeyError(OpenApiException, KeyError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (None/list) the path to the exception in the + received_data dict + """ + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiKeyError, self).__init__(full_msg) + + +class ApiException(OpenApiException): + + def __init__( + self, + status=None, + reason=None, + http_resp=None, + *, + body: Optional[str] = None, + data: Optional[Any] = None, + ) -> None: + self.status = status + self.reason = reason + self.body = body + self.data = data + self.headers = None + + if http_resp: + if self.status is None: + self.status = http_resp.status + if self.reason is None: + self.reason = http_resp.reason + if self.body is None: + try: + self.body = http_resp.data.decode('utf-8') + except Exception: + pass + self.headers = http_resp.headers + + @classmethod + def from_response( + cls, + *, + http_resp, + body: Optional[str], + data: Optional[Any], + ) -> Self: + if http_resp.status == 400: + raise BadRequestException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 401: + raise UnauthorizedException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 403: + raise ForbiddenException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 404: + raise NotFoundException(http_resp=http_resp, body=body, data=data) + + # Added new conditions for 409 and 422 + if http_resp.status == 409: + raise ConflictException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 422: + raise UnprocessableEntityException(http_resp=http_resp, body=body, data=data) + + if 500 <= http_resp.status <= 599: + raise ServiceException(http_resp=http_resp, body=body, data=data) + raise ApiException(http_resp=http_resp, body=body, data=data) + + def __str__(self): + """Custom error messages for exception""" + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}\n".format( + self.headers) + + if self.body: + error_message += "HTTP response body: {0}\n".format(self.body) + + if self.data: + error_message += "HTTP response data: {0}\n".format(self.data) + + return error_message + + +class BadRequestException(ApiException): + pass + + +class NotFoundException(ApiException): + pass + + +class UnauthorizedException(ApiException): + pass + + +class ForbiddenException(ApiException): + pass + + +class ServiceException(ApiException): + pass + + +class ConflictException(ApiException): + """Exception for HTTP 409 Conflict.""" + pass + + +class UnprocessableEntityException(ApiException): + """Exception for HTTP 422 Unprocessable Entity.""" + pass + + +def render_path(path_to_item): + """Returns a string representation of a path""" + result = "" + for pth in path_to_item: + if isinstance(pth, int): + result += "[{0}]".format(pth) + else: + result += "['{0}']".format(pth) + return result diff --git a/src/otari/_generated/otari_control_plane/models/__init__.py b/src/otari/_generated/otari_control_plane/models/__init__.py new file mode 100644 index 0000000..8630750 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/__init__.py @@ -0,0 +1,33 @@ +# coding: utf-8 + +# flake8: noqa +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +# import models into model package +from otari_control_plane.models.budget_response import BudgetResponse +from otari_control_plane.models.create_budget_request import CreateBudgetRequest +from otari_control_plane.models.create_key_request import CreateKeyRequest +from otari_control_plane.models.create_key_response import CreateKeyResponse +from otari_control_plane.models.create_user_request import CreateUserRequest +from otari_control_plane.models.http_validation_error import HTTPValidationError +from otari_control_plane.models.key_info import KeyInfo +from otari_control_plane.models.location_inner import LocationInner +from otari_control_plane.models.pricing_response import PricingResponse +from otari_control_plane.models.set_pricing_request import SetPricingRequest +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest +from otari_control_plane.models.update_key_request import UpdateKeyRequest +from otari_control_plane.models.update_user_request import UpdateUserRequest +from otari_control_plane.models.usage_entry import UsageEntry +from otari_control_plane.models.usage_log_response import UsageLogResponse +from otari_control_plane.models.user_response import UserResponse +from otari_control_plane.models.validation_error import ValidationError + diff --git a/src/otari/_generated/otari_control_plane/models/budget_response.py b/src/otari/_generated/otari_control_plane/models/budget_response.py new file mode 100644 index 0000000..2b4d473 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/budget_response.py @@ -0,0 +1,106 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class BudgetResponse(BaseModel): + """ + Response model for budget information. + """ # noqa: E501 + budget_duration_sec: Optional[StrictInt] + budget_id: StrictStr + created_at: StrictStr + max_budget: Optional[Union[StrictFloat, StrictInt]] + updated_at: StrictStr + __properties: ClassVar[List[str]] = ["budget_duration_sec", "budget_id", "created_at", "max_budget", "updated_at"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BudgetResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if budget_duration_sec (nullable) is None + # and model_fields_set contains the field + if self.budget_duration_sec is None and "budget_duration_sec" in self.model_fields_set: + _dict['budget_duration_sec'] = None + + # set to None if max_budget (nullable) is None + # and model_fields_set contains the field + if self.max_budget is None and "max_budget" in self.model_fields_set: + _dict['max_budget'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BudgetResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "budget_duration_sec": obj.get("budget_duration_sec"), + "budget_id": obj.get("budget_id"), + "created_at": obj.get("created_at"), + "max_budget": obj.get("max_budget"), + "updated_at": obj.get("updated_at") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/create_budget_request.py b/src/otari/_generated/otari_control_plane/models/create_budget_request.py new file mode 100644 index 0000000..e9f8a41 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/create_budget_request.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CreateBudgetRequest(BaseModel): + """ + Request model for creating a new budget. + """ # noqa: E501 + budget_duration_sec: Optional[Annotated[int, Field(strict=True, gt=0)]] = Field(default=None, description="Budget duration in seconds (e.g., 86400 for daily, 604800 for weekly)") + max_budget: Optional[Union[Annotated[float, Field(strict=True, ge=0.0)], Annotated[int, Field(strict=True, ge=0)]]] = Field(default=None, description="Maximum spending limit") + __properties: ClassVar[List[str]] = ["budget_duration_sec", "max_budget"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateBudgetRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if budget_duration_sec (nullable) is None + # and model_fields_set contains the field + if self.budget_duration_sec is None and "budget_duration_sec" in self.model_fields_set: + _dict['budget_duration_sec'] = None + + # set to None if max_budget (nullable) is None + # and model_fields_set contains the field + if self.max_budget is None and "max_budget" in self.model_fields_set: + _dict['max_budget'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateBudgetRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "budget_duration_sec": obj.get("budget_duration_sec"), + "max_budget": obj.get("max_budget") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/create_key_request.py b/src/otari/_generated/otari_control_plane/models/create_key_request.py new file mode 100644 index 0000000..114145f --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/create_key_request.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CreateKeyRequest(BaseModel): + """ + Request model for creating a new API key. + """ # noqa: E501 + expires_at: Optional[datetime] = Field(default=None, description="Optional expiration timestamp") + key_name: Optional[StrictStr] = Field(default=None, description="Optional name for the key") + metadata: Optional[Dict[str, Any]] = Field(default=None, description="Optional metadata") + user_id: Optional[StrictStr] = Field(default=None, description="Optional user ID to associate with this key") + __properties: ClassVar[List[str]] = ["expires_at", "key_name", "metadata", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateKeyRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if expires_at (nullable) is None + # and model_fields_set contains the field + if self.expires_at is None and "expires_at" in self.model_fields_set: + _dict['expires_at'] = None + + # set to None if key_name (nullable) is None + # and model_fields_set contains the field + if self.key_name is None and "key_name" in self.model_fields_set: + _dict['key_name'] = None + + # set to None if user_id (nullable) is None + # and model_fields_set contains the field + if self.user_id is None and "user_id" in self.model_fields_set: + _dict['user_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateKeyRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "expires_at": obj.get("expires_at"), + "key_name": obj.get("key_name"), + "metadata": obj.get("metadata"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/create_key_response.py b/src/otari/_generated/otari_control_plane/models/create_key_response.py new file mode 100644 index 0000000..d279801 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/create_key_response.py @@ -0,0 +1,117 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CreateKeyResponse(BaseModel): + """ + Response model for creating a new API key. + """ # noqa: E501 + created_at: StrictStr + expires_at: Optional[StrictStr] + id: StrictStr + is_active: StrictBool + key: StrictStr + key_name: Optional[StrictStr] + metadata: Dict[str, Any] + user_id: Optional[StrictStr] + __properties: ClassVar[List[str]] = ["created_at", "expires_at", "id", "is_active", "key", "key_name", "metadata", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateKeyResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if expires_at (nullable) is None + # and model_fields_set contains the field + if self.expires_at is None and "expires_at" in self.model_fields_set: + _dict['expires_at'] = None + + # set to None if key_name (nullable) is None + # and model_fields_set contains the field + if self.key_name is None and "key_name" in self.model_fields_set: + _dict['key_name'] = None + + # set to None if user_id (nullable) is None + # and model_fields_set contains the field + if self.user_id is None and "user_id" in self.model_fields_set: + _dict['user_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateKeyResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "created_at": obj.get("created_at"), + "expires_at": obj.get("expires_at"), + "id": obj.get("id"), + "is_active": obj.get("is_active"), + "key": obj.get("key"), + "key_name": obj.get("key_name"), + "metadata": obj.get("metadata"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/create_user_request.py b/src/otari/_generated/otari_control_plane/models/create_user_request.py new file mode 100644 index 0000000..1003904 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/create_user_request.py @@ -0,0 +1,106 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CreateUserRequest(BaseModel): + """ + Request model for creating a new user. + """ # noqa: E501 + alias: Optional[StrictStr] = Field(default=None, description="Optional admin-facing alias") + blocked: Optional[StrictBool] = Field(default=False, description="Whether user is blocked") + budget_id: Optional[StrictStr] = Field(default=None, description="Optional budget ID") + metadata: Optional[Dict[str, Any]] = Field(default=None, description="Optional metadata") + user_id: StrictStr = Field(description="Unique user identifier") + __properties: ClassVar[List[str]] = ["alias", "blocked", "budget_id", "metadata", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateUserRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if alias (nullable) is None + # and model_fields_set contains the field + if self.alias is None and "alias" in self.model_fields_set: + _dict['alias'] = None + + # set to None if budget_id (nullable) is None + # and model_fields_set contains the field + if self.budget_id is None and "budget_id" in self.model_fields_set: + _dict['budget_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateUserRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "alias": obj.get("alias"), + "blocked": obj.get("blocked") if obj.get("blocked") is not None else False, + "budget_id": obj.get("budget_id"), + "metadata": obj.get("metadata"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/http_validation_error.py b/src/otari/_generated/otari_control_plane/models/http_validation_error.py new file mode 100644 index 0000000..974e81d --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/http_validation_error.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List, Optional +from otari_control_plane.models.validation_error import ValidationError +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class HTTPValidationError(BaseModel): + """ + HTTPValidationError + """ # noqa: E501 + detail: Optional[List[ValidationError]] = None + __properties: ClassVar[List[str]] = ["detail"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of HTTPValidationError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in detail (list) + _items = [] + if self.detail: + for _item_detail in self.detail: + if _item_detail: + _items.append(_item_detail.to_dict()) + _dict['detail'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of HTTPValidationError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "detail": [ValidationError.from_dict(_item) for _item in obj["detail"]] if obj.get("detail") is not None else None + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/key_info.py b/src/otari/_generated/otari_control_plane/models/key_info.py new file mode 100644 index 0000000..e018dd0 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/key_info.py @@ -0,0 +1,122 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class KeyInfo(BaseModel): + """ + Response model for key information. + """ # noqa: E501 + created_at: StrictStr + expires_at: Optional[StrictStr] + id: StrictStr + is_active: StrictBool + key_name: Optional[StrictStr] + last_used_at: Optional[StrictStr] + metadata: Dict[str, Any] + user_id: Optional[StrictStr] + __properties: ClassVar[List[str]] = ["created_at", "expires_at", "id", "is_active", "key_name", "last_used_at", "metadata", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of KeyInfo from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if expires_at (nullable) is None + # and model_fields_set contains the field + if self.expires_at is None and "expires_at" in self.model_fields_set: + _dict['expires_at'] = None + + # set to None if key_name (nullable) is None + # and model_fields_set contains the field + if self.key_name is None and "key_name" in self.model_fields_set: + _dict['key_name'] = None + + # set to None if last_used_at (nullable) is None + # and model_fields_set contains the field + if self.last_used_at is None and "last_used_at" in self.model_fields_set: + _dict['last_used_at'] = None + + # set to None if user_id (nullable) is None + # and model_fields_set contains the field + if self.user_id is None and "user_id" in self.model_fields_set: + _dict['user_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of KeyInfo from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "created_at": obj.get("created_at"), + "expires_at": obj.get("expires_at"), + "id": obj.get("id"), + "is_active": obj.get("is_active"), + "key_name": obj.get("key_name"), + "last_used_at": obj.get("last_used_at"), + "metadata": obj.get("metadata"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/location_inner.py b/src/otari/_generated/otari_control_plane/models/location_inner.py new file mode 100644 index 0000000..502dd3d --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/location_inner.py @@ -0,0 +1,138 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, ValidationError, field_validator +from typing import Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +LOCATIONINNER_ANY_OF_SCHEMAS = ["int", "str"] + +class LocationInner(BaseModel): + """ + LocationInner + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: int + anyof_schema_2_validator: Optional[StrictInt] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[int, str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "int", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = LocationInner.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: int + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in LocationInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into int + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into LocationInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], int, str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_generated/otari_control_plane/models/pricing_response.py b/src/otari/_generated/otari_control_plane/models/pricing_response.py new file mode 100644 index 0000000..cee74a5 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/pricing_response.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class PricingResponse(BaseModel): + """ + Response model for model pricing. + """ # noqa: E501 + created_at: StrictStr + effective_at: StrictStr + input_price_per_million: Union[StrictFloat, StrictInt] + model_key: StrictStr + output_price_per_million: Union[StrictFloat, StrictInt] + updated_at: StrictStr + __properties: ClassVar[List[str]] = ["created_at", "effective_at", "input_price_per_million", "model_key", "output_price_per_million", "updated_at"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of PricingResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of PricingResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "created_at": obj.get("created_at"), + "effective_at": obj.get("effective_at"), + "input_price_per_million": obj.get("input_price_per_million"), + "model_key": obj.get("model_key"), + "output_price_per_million": obj.get("output_price_per_million"), + "updated_at": obj.get("updated_at") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/set_pricing_request.py b/src/otari/_generated/otari_control_plane/models/set_pricing_request.py new file mode 100644 index 0000000..567e9ef --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/set_pricing_request.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class SetPricingRequest(BaseModel): + """ + Request model for setting model pricing. + """ # noqa: E501 + effective_at: Optional[datetime] = Field(default=None, description="ISO 8601 datetime from which this price applies. Defaults to now if omitted.") + input_price_per_million: Union[Annotated[float, Field(strict=True, ge=0.0)], Annotated[int, Field(strict=True, ge=0)]] = Field(description="Price per 1M input tokens") + model_key: StrictStr = Field(description="Model identifier in format 'provider:model'") + output_price_per_million: Union[Annotated[float, Field(strict=True, ge=0.0)], Annotated[int, Field(strict=True, ge=0)]] = Field(description="Price per 1M output tokens") + __properties: ClassVar[List[str]] = ["effective_at", "input_price_per_million", "model_key", "output_price_per_million"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SetPricingRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if effective_at (nullable) is None + # and model_fields_set contains the field + if self.effective_at is None and "effective_at" in self.model_fields_set: + _dict['effective_at'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SetPricingRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "effective_at": obj.get("effective_at"), + "input_price_per_million": obj.get("input_price_per_million"), + "model_key": obj.get("model_key"), + "output_price_per_million": obj.get("output_price_per_million") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/update_budget_request.py b/src/otari/_generated/otari_control_plane/models/update_budget_request.py new file mode 100644 index 0000000..8fe3968 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/update_budget_request.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UpdateBudgetRequest(BaseModel): + """ + Request model for updating a budget. + """ # noqa: E501 + budget_duration_sec: Optional[Annotated[int, Field(strict=True, gt=0)]] = None + max_budget: Optional[Union[Annotated[float, Field(strict=True, ge=0.0)], Annotated[int, Field(strict=True, ge=0)]]] = None + __properties: ClassVar[List[str]] = ["budget_duration_sec", "max_budget"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateBudgetRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if budget_duration_sec (nullable) is None + # and model_fields_set contains the field + if self.budget_duration_sec is None and "budget_duration_sec" in self.model_fields_set: + _dict['budget_duration_sec'] = None + + # set to None if max_budget (nullable) is None + # and model_fields_set contains the field + if self.max_budget is None and "max_budget" in self.model_fields_set: + _dict['max_budget'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateBudgetRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "budget_duration_sec": obj.get("budget_duration_sec"), + "max_budget": obj.get("max_budget") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/update_key_request.py b/src/otari/_generated/otari_control_plane/models/update_key_request.py new file mode 100644 index 0000000..bf773cb --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/update_key_request.py @@ -0,0 +1,115 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UpdateKeyRequest(BaseModel): + """ + Request model for updating a key. + """ # noqa: E501 + expires_at: Optional[datetime] = None + is_active: Optional[StrictBool] = None + key_name: Optional[StrictStr] = None + metadata: Optional[Dict[str, Any]] = None + __properties: ClassVar[List[str]] = ["expires_at", "is_active", "key_name", "metadata"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateKeyRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if expires_at (nullable) is None + # and model_fields_set contains the field + if self.expires_at is None and "expires_at" in self.model_fields_set: + _dict['expires_at'] = None + + # set to None if is_active (nullable) is None + # and model_fields_set contains the field + if self.is_active is None and "is_active" in self.model_fields_set: + _dict['is_active'] = None + + # set to None if key_name (nullable) is None + # and model_fields_set contains the field + if self.key_name is None and "key_name" in self.model_fields_set: + _dict['key_name'] = None + + # set to None if metadata (nullable) is None + # and model_fields_set contains the field + if self.metadata is None and "metadata" in self.model_fields_set: + _dict['metadata'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateKeyRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "expires_at": obj.get("expires_at"), + "is_active": obj.get("is_active"), + "key_name": obj.get("key_name"), + "metadata": obj.get("metadata") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/update_user_request.py b/src/otari/_generated/otari_control_plane/models/update_user_request.py new file mode 100644 index 0000000..cd3fe41 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/update_user_request.py @@ -0,0 +1,114 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UpdateUserRequest(BaseModel): + """ + Request model for updating a user. + """ # noqa: E501 + alias: Optional[StrictStr] = None + blocked: Optional[StrictBool] = None + budget_id: Optional[StrictStr] = None + metadata: Optional[Dict[str, Any]] = None + __properties: ClassVar[List[str]] = ["alias", "blocked", "budget_id", "metadata"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateUserRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if alias (nullable) is None + # and model_fields_set contains the field + if self.alias is None and "alias" in self.model_fields_set: + _dict['alias'] = None + + # set to None if blocked (nullable) is None + # and model_fields_set contains the field + if self.blocked is None and "blocked" in self.model_fields_set: + _dict['blocked'] = None + + # set to None if budget_id (nullable) is None + # and model_fields_set contains the field + if self.budget_id is None and "budget_id" in self.model_fields_set: + _dict['budget_id'] = None + + # set to None if metadata (nullable) is None + # and model_fields_set contains the field + if self.metadata is None and "metadata" in self.model_fields_set: + _dict['metadata'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateUserRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "alias": obj.get("alias"), + "blocked": obj.get("blocked"), + "budget_id": obj.get("budget_id"), + "metadata": obj.get("metadata") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/usage_entry.py b/src/otari/_generated/otari_control_plane/models/usage_entry.py new file mode 100644 index 0000000..6164329 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/usage_entry.py @@ -0,0 +1,152 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UsageEntry(BaseModel): + """ + A single usage log entry. + """ # noqa: E501 + api_key_id: Optional[StrictStr] + completion_tokens: Optional[StrictInt] + cost: Optional[Union[StrictFloat, StrictInt]] + endpoint: StrictStr + error_message: Optional[StrictStr] + id: StrictStr + model: StrictStr + prompt_tokens: Optional[StrictInt] + provider: Optional[StrictStr] + status: StrictStr + timestamp: StrictStr + total_tokens: Optional[StrictInt] + user_id: Optional[StrictStr] + __properties: ClassVar[List[str]] = ["api_key_id", "completion_tokens", "cost", "endpoint", "error_message", "id", "model", "prompt_tokens", "provider", "status", "timestamp", "total_tokens", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UsageEntry from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if api_key_id (nullable) is None + # and model_fields_set contains the field + if self.api_key_id is None and "api_key_id" in self.model_fields_set: + _dict['api_key_id'] = None + + # set to None if completion_tokens (nullable) is None + # and model_fields_set contains the field + if self.completion_tokens is None and "completion_tokens" in self.model_fields_set: + _dict['completion_tokens'] = None + + # set to None if cost (nullable) is None + # and model_fields_set contains the field + if self.cost is None and "cost" in self.model_fields_set: + _dict['cost'] = None + + # set to None if error_message (nullable) is None + # and model_fields_set contains the field + if self.error_message is None and "error_message" in self.model_fields_set: + _dict['error_message'] = None + + # set to None if prompt_tokens (nullable) is None + # and model_fields_set contains the field + if self.prompt_tokens is None and "prompt_tokens" in self.model_fields_set: + _dict['prompt_tokens'] = None + + # set to None if provider (nullable) is None + # and model_fields_set contains the field + if self.provider is None and "provider" in self.model_fields_set: + _dict['provider'] = None + + # set to None if total_tokens (nullable) is None + # and model_fields_set contains the field + if self.total_tokens is None and "total_tokens" in self.model_fields_set: + _dict['total_tokens'] = None + + # set to None if user_id (nullable) is None + # and model_fields_set contains the field + if self.user_id is None and "user_id" in self.model_fields_set: + _dict['user_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UsageEntry from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "api_key_id": obj.get("api_key_id"), + "completion_tokens": obj.get("completion_tokens"), + "cost": obj.get("cost"), + "endpoint": obj.get("endpoint"), + "error_message": obj.get("error_message"), + "id": obj.get("id"), + "model": obj.get("model"), + "prompt_tokens": obj.get("prompt_tokens"), + "provider": obj.get("provider"), + "status": obj.get("status"), + "timestamp": obj.get("timestamp"), + "total_tokens": obj.get("total_tokens"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/usage_log_response.py b/src/otari/_generated/otari_control_plane/models/usage_log_response.py new file mode 100644 index 0000000..e09b186 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/usage_log_response.py @@ -0,0 +1,152 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UsageLogResponse(BaseModel): + """ + Response model for usage log. + """ # noqa: E501 + api_key_id: Optional[StrictStr] + completion_tokens: Optional[StrictInt] + cost: Optional[Union[StrictFloat, StrictInt]] + endpoint: StrictStr + error_message: Optional[StrictStr] + id: StrictStr + model: StrictStr + prompt_tokens: Optional[StrictInt] + provider: Optional[StrictStr] + status: StrictStr + timestamp: StrictStr + total_tokens: Optional[StrictInt] + user_id: Optional[StrictStr] + __properties: ClassVar[List[str]] = ["api_key_id", "completion_tokens", "cost", "endpoint", "error_message", "id", "model", "prompt_tokens", "provider", "status", "timestamp", "total_tokens", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UsageLogResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if api_key_id (nullable) is None + # and model_fields_set contains the field + if self.api_key_id is None and "api_key_id" in self.model_fields_set: + _dict['api_key_id'] = None + + # set to None if completion_tokens (nullable) is None + # and model_fields_set contains the field + if self.completion_tokens is None and "completion_tokens" in self.model_fields_set: + _dict['completion_tokens'] = None + + # set to None if cost (nullable) is None + # and model_fields_set contains the field + if self.cost is None and "cost" in self.model_fields_set: + _dict['cost'] = None + + # set to None if error_message (nullable) is None + # and model_fields_set contains the field + if self.error_message is None and "error_message" in self.model_fields_set: + _dict['error_message'] = None + + # set to None if prompt_tokens (nullable) is None + # and model_fields_set contains the field + if self.prompt_tokens is None and "prompt_tokens" in self.model_fields_set: + _dict['prompt_tokens'] = None + + # set to None if provider (nullable) is None + # and model_fields_set contains the field + if self.provider is None and "provider" in self.model_fields_set: + _dict['provider'] = None + + # set to None if total_tokens (nullable) is None + # and model_fields_set contains the field + if self.total_tokens is None and "total_tokens" in self.model_fields_set: + _dict['total_tokens'] = None + + # set to None if user_id (nullable) is None + # and model_fields_set contains the field + if self.user_id is None and "user_id" in self.model_fields_set: + _dict['user_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UsageLogResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "api_key_id": obj.get("api_key_id"), + "completion_tokens": obj.get("completion_tokens"), + "cost": obj.get("cost"), + "endpoint": obj.get("endpoint"), + "error_message": obj.get("error_message"), + "id": obj.get("id"), + "model": obj.get("model"), + "prompt_tokens": obj.get("prompt_tokens"), + "provider": obj.get("provider"), + "status": obj.get("status"), + "timestamp": obj.get("timestamp"), + "total_tokens": obj.get("total_tokens"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/user_response.py b/src/otari/_generated/otari_control_plane/models/user_response.py new file mode 100644 index 0000000..b065d87 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/user_response.py @@ -0,0 +1,128 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UserResponse(BaseModel): + """ + Response model for user information. + """ # noqa: E501 + alias: Optional[StrictStr] + blocked: StrictBool + budget_id: Optional[StrictStr] + budget_started_at: Optional[StrictStr] + created_at: StrictStr + metadata: Dict[str, Any] + next_budget_reset_at: Optional[StrictStr] + reserved: Union[StrictFloat, StrictInt] + spend: Union[StrictFloat, StrictInt] + updated_at: StrictStr + user_id: StrictStr + __properties: ClassVar[List[str]] = ["alias", "blocked", "budget_id", "budget_started_at", "created_at", "metadata", "next_budget_reset_at", "reserved", "spend", "updated_at", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UserResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if alias (nullable) is None + # and model_fields_set contains the field + if self.alias is None and "alias" in self.model_fields_set: + _dict['alias'] = None + + # set to None if budget_id (nullable) is None + # and model_fields_set contains the field + if self.budget_id is None and "budget_id" in self.model_fields_set: + _dict['budget_id'] = None + + # set to None if budget_started_at (nullable) is None + # and model_fields_set contains the field + if self.budget_started_at is None and "budget_started_at" in self.model_fields_set: + _dict['budget_started_at'] = None + + # set to None if next_budget_reset_at (nullable) is None + # and model_fields_set contains the field + if self.next_budget_reset_at is None and "next_budget_reset_at" in self.model_fields_set: + _dict['next_budget_reset_at'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UserResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "alias": obj.get("alias"), + "blocked": obj.get("blocked"), + "budget_id": obj.get("budget_id"), + "budget_started_at": obj.get("budget_started_at"), + "created_at": obj.get("created_at"), + "metadata": obj.get("metadata"), + "next_budget_reset_at": obj.get("next_budget_reset_at"), + "reserved": obj.get("reserved"), + "spend": obj.get("spend"), + "updated_at": obj.get("updated_at"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/models/validation_error.py b/src/otari/_generated/otari_control_plane/models/validation_error.py new file mode 100644 index 0000000..ac201a0 --- /dev/null +++ b/src/otari/_generated/otari_control_plane/models/validation_error.py @@ -0,0 +1,109 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from otari_control_plane.models.location_inner import LocationInner +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ValidationError(BaseModel): + """ + ValidationError + """ # noqa: E501 + ctx: Optional[Dict[str, Any]] = None + input: Optional[Any] = None + loc: List[LocationInner] + msg: StrictStr + type: StrictStr + __properties: ClassVar[List[str]] = ["ctx", "input", "loc", "msg", "type"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ValidationError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in loc (list) + _items = [] + if self.loc: + for _item_loc in self.loc: + if _item_loc: + _items.append(_item_loc.to_dict()) + _dict['loc'] = _items + # set to None if input (nullable) is None + # and model_fields_set contains the field + if self.input is None and "input" in self.model_fields_set: + _dict['input'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ValidationError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "ctx": obj.get("ctx"), + "input": obj.get("input"), + "loc": [LocationInner.from_dict(_item) for _item in obj["loc"]] if obj.get("loc") is not None else None, + "msg": obj.get("msg"), + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_generated/otari_control_plane/py.typed b/src/otari/_generated/otari_control_plane/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/otari/_generated/otari_control_plane/rest.py b/src/otari/_generated/otari_control_plane/rest.py new file mode 100644 index 0000000..f4b331b --- /dev/null +++ b/src/otari/_generated/otari_control_plane/rest.py @@ -0,0 +1,263 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import io +import json +import re +import ssl + +import urllib3 + +from otari_control_plane.exceptions import ApiException, ApiValueError + +SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"} +RESTResponseType = urllib3.HTTPResponse + + +def is_socks_proxy_url(url): + if url is None: + return False + split_section = url.split("://") + if len(split_section) < 2: + return False + else: + return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES + + +class RESTResponse(io.IOBase): + + def __init__(self, resp) -> None: + self.response = resp + self.status = resp.status + self.reason = resp.reason + self.data = None + + def read(self): + if self.data is None: + self.data = self.response.data + return self.data + + @property + def headers(self): + """Returns a dictionary of response headers.""" + return self.response.headers + + def getheaders(self): + """Returns a dictionary of the response headers; use ``headers`` instead.""" + return self.response.headers + + def getheader(self, name, default=None): + """Returns a given response header; use ``headers.get()`` instead.""" + return self.response.headers.get(name, default) + + +class RESTClientObject: + + def __init__(self, configuration) -> None: + # urllib3.PoolManager will pass all kw parameters to connectionpool + # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 + # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 + # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501 + + # cert_reqs + if configuration.verify_ssl: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + + pool_args = { + "cert_reqs": cert_reqs, + "ca_certs": configuration.ssl_ca_cert, + "cert_file": configuration.cert_file, + "key_file": configuration.key_file, + "ca_cert_data": configuration.ca_cert_data, + } + if configuration.assert_hostname is not None: + pool_args['assert_hostname'] = ( + configuration.assert_hostname + ) + + if configuration.retries is not None: + pool_args['retries'] = configuration.retries + + if configuration.tls_server_name: + pool_args['server_hostname'] = configuration.tls_server_name + + + if configuration.socket_options is not None: + pool_args['socket_options'] = configuration.socket_options + + if configuration.connection_pool_maxsize is not None: + pool_args['maxsize'] = configuration.connection_pool_maxsize + + # https pool manager + self.pool_manager: urllib3.PoolManager + + if configuration.proxy: + if is_socks_proxy_url(configuration.proxy): + from urllib3.contrib.socks import SOCKSProxyManager + pool_args["proxy_url"] = configuration.proxy + pool_args["headers"] = configuration.proxy_headers + self.pool_manager = SOCKSProxyManager(**pool_args) + else: + pool_args["proxy_url"] = configuration.proxy + pool_args["proxy_headers"] = configuration.proxy_headers + self.pool_manager = urllib3.ProxyManager(**pool_args) + else: + self.pool_manager = urllib3.PoolManager(**pool_args) + + def request( + self, + method, + url, + headers=None, + body=None, + post_params=None, + _request_timeout=None + ): + """Perform requests. + + :param method: http request method + :param url: http request url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, + `application/x-www-form-urlencoded` + and `multipart/form-data` + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + """ + method = method.upper() + assert method in [ + 'GET', + 'HEAD', + 'DELETE', + 'POST', + 'PUT', + 'PATCH', + 'OPTIONS' + ] + + if post_params and body: + raise ApiValueError( + "body parameter cannot be used with post_params parameter." + ) + + post_params = post_params or {} + headers = headers or {} + + timeout = None + if _request_timeout: + if isinstance(_request_timeout, (int, float)): + timeout = urllib3.Timeout(total=_request_timeout) + elif ( + isinstance(_request_timeout, tuple) + and len(_request_timeout) == 2 + ): + timeout = urllib3.Timeout( + connect=_request_timeout[0], + read=_request_timeout[1] + ) + + try: + # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` + if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: + + # no content type provided or payload is json + content_type = headers.get('Content-Type') + if ( + not content_type + or re.search('json', content_type, re.IGNORECASE) + ): + request_body = None + if body is not None: + request_body = json.dumps(body) + r = self.pool_manager.request( + method, + url, + body=request_body, + timeout=timeout, + headers=headers, + preload_content=False + ) + elif content_type == 'application/x-www-form-urlencoded': + r = self.pool_manager.request( + method, + url, + fields=post_params, + encode_multipart=False, + timeout=timeout, + headers=headers, + preload_content=False + ) + elif content_type == 'multipart/form-data': + # must del headers['Content-Type'], or the correct + # Content-Type which generated by urllib3 will be + # overwritten. + del headers['Content-Type'] + # Ensures that dict objects are serialized + post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a,b) for a, b in post_params] + r = self.pool_manager.request( + method, + url, + fields=post_params, + encode_multipart=True, + timeout=timeout, + headers=headers, + preload_content=False + ) + # Pass a `string` parameter directly in the body to support + # other content types than JSON when `body` argument is + # provided in serialized form. + elif isinstance(body, str) or isinstance(body, bytes): + r = self.pool_manager.request( + method, + url, + body=body, + timeout=timeout, + headers=headers, + preload_content=False + ) + elif headers['Content-Type'].startswith('text/') and isinstance(body, bool): + request_body = "true" if body else "false" + r = self.pool_manager.request( + method, + url, + body=request_body, + preload_content=False, + timeout=timeout, + headers=headers) + else: + # Cannot generate the request from given parameters + msg = """Cannot prepare a request message for provided + arguments. Please check that your arguments match + declared content type.""" + raise ApiException(status=0, reason=msg) + # For `GET`, `HEAD` + else: + r = self.pool_manager.request( + method, + url, + fields={}, + timeout=timeout, + headers=headers, + preload_content=False + ) + except urllib3.exceptions.SSLError as e: + msg = "\n".join([type(e).__name__, str(e)]) + raise ApiException(status=0, reason=msg) + + return RESTResponse(r) diff --git a/src/otari/_generated/pyproject.toml b/src/otari/_generated/pyproject.toml new file mode 100644 index 0000000..8191679 --- /dev/null +++ b/src/otari/_generated/pyproject.toml @@ -0,0 +1,94 @@ +[project] +name = "otari_control_plane" +version = "1.0.0" +description = "otari-gateway" +authors = [ + {name = "OpenAPI Generator Community",email = "team@openapitools.org"}, +] +readme = "README.md" +keywords = ["OpenAPI", "OpenAPI-Generator", "otari-gateway"] +requires-python = ">=3.9" + +dependencies = [ + "urllib3 (>=2.1.0,<3.0.0)", + "python-dateutil (>=2.8.2)", + "pydantic (>=2.11)", + "typing-extensions (>=4.7.1)", +] + +[project.urls] +Repository = "https://github.com/GIT_USER_ID/GIT_REPO_ID" + +[tool.poetry] +requires-poetry = ">=2.0" + +[tool.poetry.group.dev.dependencies] +pytest = ">= 7.2.1" +pytest-cov = ">= 2.8.1" +tox = ">= 3.9.0" +flake8 = ">= 4.0.0" +types-python-dateutil = ">= 2.8.19.14" +mypy = ">= 1.5" + + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.pylint.'MESSAGES CONTROL'] +extension-pkg-whitelist = "pydantic" + +[tool.mypy] +files = [ + "otari_control_plane", + #"test", # auto-generated tests + "tests", # hand-written tests +] +# TODO: enable "strict" once all these individual checks are passing +# strict = true + +# List from: https://mypy.readthedocs.io/en/stable/existing_code.html#introduce-stricter-options +warn_unused_configs = true +warn_redundant_casts = true +warn_unused_ignores = true + +## Getting these passing should be easy +strict_equality = true +extra_checks = true + +## Strongly recommend enabling this one as soon as you can +check_untyped_defs = true + +## These shouldn't be too much additional work, but may be tricky to +## get passing if you use a lot of untyped libraries +disallow_subclassing_any = true +disallow_untyped_decorators = true +disallow_any_generics = true + +### These next few are various gradations of forcing use of type annotations +#disallow_untyped_calls = true +#disallow_incomplete_defs = true +#disallow_untyped_defs = true +# +### This one isn't too hard to get passing, but return on investment is lower +#no_implicit_reexport = true +# +### This one can be tricky to get passing if you use a lot of untyped libraries +#warn_return_any = true + +[[tool.mypy.overrides]] +module = [ + "otari_control_plane.configuration", +] +warn_unused_ignores = true +strict_equality = true +extra_checks = true +check_untyped_defs = true +disallow_subclassing_any = true +disallow_untyped_decorators = true +disallow_any_generics = true +disallow_untyped_calls = true +disallow_incomplete_defs = true +disallow_untyped_defs = true +no_implicit_reexport = true +warn_return_any = true diff --git a/src/otari/_generated/requirements.txt b/src/otari/_generated/requirements.txt new file mode 100644 index 0000000..9e2d67a --- /dev/null +++ b/src/otari/_generated/requirements.txt @@ -0,0 +1,4 @@ +urllib3 >= 2.1.0, < 3.0.0 +python_dateutil >= 2.8.2 +pydantic >= 2.11 +typing-extensions >= 4.7.1 diff --git a/src/otari/_generated/setup.cfg b/src/otari/_generated/setup.cfg new file mode 100644 index 0000000..11433ee --- /dev/null +++ b/src/otari/_generated/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +max-line-length=99 diff --git a/src/otari/_generated/setup.py b/src/otari/_generated/setup.py new file mode 100644 index 0000000..4e7e3a7 --- /dev/null +++ b/src/otari/_generated/setup.py @@ -0,0 +1,47 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from setuptools import setup, find_packages # noqa: H301 + +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools +NAME = "otari-control-plane" +VERSION = "1.0.0" +PYTHON_REQUIRES = ">= 3.10" +REQUIRES = [ + "urllib3 >= 2.1.0, < 3.0.0", + "python-dateutil >= 2.8.2", + "pydantic >= 2.11", + "typing-extensions >= 4.7.1", +] + +setup( + name=NAME, + version=VERSION, + description="otari-gateway", + author="OpenAPI Generator community", + author_email="team@openapitools.org", + url="", + keywords=["OpenAPI", "OpenAPI-Generator", "otari-gateway"], + install_requires=REQUIRES, + packages=find_packages(exclude=["test", "tests"]), + include_package_data=True, + long_description_content_type='text/markdown', + long_description="""\ + A clean FastAPI gateway for otari with API key management + """, # noqa: E501 + package_data={"otari_control_plane": ["py.typed"]}, +) diff --git a/src/otari/_generated/test-requirements.txt b/src/otari/_generated/test-requirements.txt new file mode 100644 index 0000000..e98555c --- /dev/null +++ b/src/otari/_generated/test-requirements.txt @@ -0,0 +1,6 @@ +pytest >= 7.2.1 +pytest-cov >= 2.8.1 +tox >= 3.9.0 +flake8 >= 4.0.0 +types-python-dateutil >= 2.8.19.14 +mypy >= 1.5 diff --git a/src/otari/_generated/test/__init__.py b/src/otari/_generated/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/otari/_generated/test/test_budget_response.py b/src/otari/_generated/test/test_budget_response.py new file mode 100644 index 0000000..974a4fb --- /dev/null +++ b/src/otari/_generated/test/test_budget_response.py @@ -0,0 +1,60 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.budget_response import BudgetResponse + +class TestBudgetResponse(unittest.TestCase): + """BudgetResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BudgetResponse: + """Test BudgetResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BudgetResponse` + """ + model = BudgetResponse() + if include_optional: + return BudgetResponse( + budget_duration_sec = 56, + budget_id = '', + created_at = '', + max_budget = 1.337, + updated_at = '' + ) + else: + return BudgetResponse( + budget_duration_sec = 56, + budget_id = '', + created_at = '', + max_budget = 1.337, + updated_at = '', + ) + """ + + def testBudgetResponse(self): + """Test BudgetResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_budgets_api.py b/src/otari/_generated/test/test_budgets_api.py new file mode 100644 index 0000000..a355032 --- /dev/null +++ b/src/otari/_generated/test/test_budgets_api.py @@ -0,0 +1,66 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.api.budgets_api import BudgetsApi + + +class TestBudgetsApi(unittest.TestCase): + """BudgetsApi unit test stubs""" + + def setUp(self) -> None: + self.api = BudgetsApi() + + def tearDown(self) -> None: + pass + + def test_create_budget_v1_budgets_post(self) -> None: + """Test case for create_budget_v1_budgets_post + + Create Budget + """ + pass + + def test_delete_budget_v1_budgets_budget_id_delete(self) -> None: + """Test case for delete_budget_v1_budgets_budget_id_delete + + Delete Budget + """ + pass + + def test_get_budget_v1_budgets_budget_id_get(self) -> None: + """Test case for get_budget_v1_budgets_budget_id_get + + Get Budget + """ + pass + + def test_list_budgets_v1_budgets_get(self) -> None: + """Test case for list_budgets_v1_budgets_get + + List Budgets + """ + pass + + def test_update_budget_v1_budgets_budget_id_patch(self) -> None: + """Test case for update_budget_v1_budgets_budget_id_patch + + Update Budget + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_create_budget_request.py b/src/otari/_generated/test/test_create_budget_request.py new file mode 100644 index 0000000..1142a3a --- /dev/null +++ b/src/otari/_generated/test/test_create_budget_request.py @@ -0,0 +1,52 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.create_budget_request import CreateBudgetRequest + +class TestCreateBudgetRequest(unittest.TestCase): + """CreateBudgetRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> CreateBudgetRequest: + """Test CreateBudgetRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `CreateBudgetRequest` + """ + model = CreateBudgetRequest() + if include_optional: + return CreateBudgetRequest( + budget_duration_sec = 0.0, + max_budget = 0.0 + ) + else: + return CreateBudgetRequest( + ) + """ + + def testCreateBudgetRequest(self): + """Test CreateBudgetRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_create_key_request.py b/src/otari/_generated/test/test_create_key_request.py new file mode 100644 index 0000000..ce21d3c --- /dev/null +++ b/src/otari/_generated/test/test_create_key_request.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.create_key_request import CreateKeyRequest + +class TestCreateKeyRequest(unittest.TestCase): + """CreateKeyRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> CreateKeyRequest: + """Test CreateKeyRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `CreateKeyRequest` + """ + model = CreateKeyRequest() + if include_optional: + return CreateKeyRequest( + expires_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + key_name = '', + metadata = { }, + user_id = '' + ) + else: + return CreateKeyRequest( + ) + """ + + def testCreateKeyRequest(self): + """Test CreateKeyRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_create_key_response.py b/src/otari/_generated/test/test_create_key_response.py new file mode 100644 index 0000000..a6afe64 --- /dev/null +++ b/src/otari/_generated/test/test_create_key_response.py @@ -0,0 +1,66 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.create_key_response import CreateKeyResponse + +class TestCreateKeyResponse(unittest.TestCase): + """CreateKeyResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> CreateKeyResponse: + """Test CreateKeyResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `CreateKeyResponse` + """ + model = CreateKeyResponse() + if include_optional: + return CreateKeyResponse( + created_at = '', + expires_at = '', + id = '', + is_active = True, + key = '', + key_name = '', + metadata = { }, + user_id = '' + ) + else: + return CreateKeyResponse( + created_at = '', + expires_at = '', + id = '', + is_active = True, + key = '', + key_name = '', + metadata = { }, + user_id = '', + ) + """ + + def testCreateKeyResponse(self): + """Test CreateKeyResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_create_user_request.py b/src/otari/_generated/test/test_create_user_request.py new file mode 100644 index 0000000..ddab12d --- /dev/null +++ b/src/otari/_generated/test/test_create_user_request.py @@ -0,0 +1,56 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.create_user_request import CreateUserRequest + +class TestCreateUserRequest(unittest.TestCase): + """CreateUserRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> CreateUserRequest: + """Test CreateUserRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `CreateUserRequest` + """ + model = CreateUserRequest() + if include_optional: + return CreateUserRequest( + alias = '', + blocked = True, + budget_id = '', + metadata = { }, + user_id = '' + ) + else: + return CreateUserRequest( + user_id = '', + ) + """ + + def testCreateUserRequest(self): + """Test CreateUserRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_http_validation_error.py b/src/otari/_generated/test/test_http_validation_error.py new file mode 100644 index 0000000..6f2b4f2 --- /dev/null +++ b/src/otari/_generated/test/test_http_validation_error.py @@ -0,0 +1,60 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.http_validation_error import HTTPValidationError + +class TestHTTPValidationError(unittest.TestCase): + """HTTPValidationError unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> HTTPValidationError: + """Test HTTPValidationError + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `HTTPValidationError` + """ + model = HTTPValidationError() + if include_optional: + return HTTPValidationError( + detail = [ + otari_control_plane.models.validation_error.ValidationError( + ctx = otari_control_plane.models.context.Context(), + input = null, + loc = [ + null + ], + msg = '', + type = '', ) + ] + ) + else: + return HTTPValidationError( + ) + """ + + def testHTTPValidationError(self): + """Test HTTPValidationError""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_key_info.py b/src/otari/_generated/test/test_key_info.py new file mode 100644 index 0000000..3d873e6 --- /dev/null +++ b/src/otari/_generated/test/test_key_info.py @@ -0,0 +1,66 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.key_info import KeyInfo + +class TestKeyInfo(unittest.TestCase): + """KeyInfo unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> KeyInfo: + """Test KeyInfo + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `KeyInfo` + """ + model = KeyInfo() + if include_optional: + return KeyInfo( + created_at = '', + expires_at = '', + id = '', + is_active = True, + key_name = '', + last_used_at = '', + metadata = { }, + user_id = '' + ) + else: + return KeyInfo( + created_at = '', + expires_at = '', + id = '', + is_active = True, + key_name = '', + last_used_at = '', + metadata = { }, + user_id = '', + ) + """ + + def testKeyInfo(self): + """Test KeyInfo""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_keys_api.py b/src/otari/_generated/test/test_keys_api.py new file mode 100644 index 0000000..04f189a --- /dev/null +++ b/src/otari/_generated/test/test_keys_api.py @@ -0,0 +1,66 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.api.keys_api import KeysApi + + +class TestKeysApi(unittest.TestCase): + """KeysApi unit test stubs""" + + def setUp(self) -> None: + self.api = KeysApi() + + def tearDown(self) -> None: + pass + + def test_create_key_v1_keys_post(self) -> None: + """Test case for create_key_v1_keys_post + + Create Key + """ + pass + + def test_delete_key_v1_keys_key_id_delete(self) -> None: + """Test case for delete_key_v1_keys_key_id_delete + + Delete Key + """ + pass + + def test_get_key_v1_keys_key_id_get(self) -> None: + """Test case for get_key_v1_keys_key_id_get + + Get Key + """ + pass + + def test_list_keys_v1_keys_get(self) -> None: + """Test case for list_keys_v1_keys_get + + List Keys + """ + pass + + def test_update_key_v1_keys_key_id_patch(self) -> None: + """Test case for update_key_v1_keys_key_id_patch + + Update Key + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_location_inner.py b/src/otari/_generated/test/test_location_inner.py new file mode 100644 index 0000000..2d170d7 --- /dev/null +++ b/src/otari/_generated/test/test_location_inner.py @@ -0,0 +1,50 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.location_inner import LocationInner + +class TestLocationInner(unittest.TestCase): + """LocationInner unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> LocationInner: + """Test LocationInner + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `LocationInner` + """ + model = LocationInner() + if include_optional: + return LocationInner( + ) + else: + return LocationInner( + ) + """ + + def testLocationInner(self): + """Test LocationInner""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_pricing_api.py b/src/otari/_generated/test/test_pricing_api.py new file mode 100644 index 0000000..1a613fe --- /dev/null +++ b/src/otari/_generated/test/test_pricing_api.py @@ -0,0 +1,66 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.api.pricing_api import PricingApi + + +class TestPricingApi(unittest.TestCase): + """PricingApi unit test stubs""" + + def setUp(self) -> None: + self.api = PricingApi() + + def tearDown(self) -> None: + pass + + def test_delete_pricing_v1_pricing_model_key_delete(self) -> None: + """Test case for delete_pricing_v1_pricing_model_key_delete + + Delete Pricing + """ + pass + + def test_get_pricing_history_v1_pricing_model_key_history_get(self) -> None: + """Test case for get_pricing_history_v1_pricing_model_key_history_get + + Get Pricing History + """ + pass + + def test_get_pricing_v1_pricing_model_key_get(self) -> None: + """Test case for get_pricing_v1_pricing_model_key_get + + Get Pricing + """ + pass + + def test_list_pricing_v1_pricing_get(self) -> None: + """Test case for list_pricing_v1_pricing_get + + List Pricing + """ + pass + + def test_set_pricing_v1_pricing_post(self) -> None: + """Test case for set_pricing_v1_pricing_post + + Set Pricing + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_pricing_response.py b/src/otari/_generated/test/test_pricing_response.py new file mode 100644 index 0000000..a1fab05 --- /dev/null +++ b/src/otari/_generated/test/test_pricing_response.py @@ -0,0 +1,62 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.pricing_response import PricingResponse + +class TestPricingResponse(unittest.TestCase): + """PricingResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> PricingResponse: + """Test PricingResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `PricingResponse` + """ + model = PricingResponse() + if include_optional: + return PricingResponse( + created_at = '', + effective_at = '', + input_price_per_million = 1.337, + model_key = '', + output_price_per_million = 1.337, + updated_at = '' + ) + else: + return PricingResponse( + created_at = '', + effective_at = '', + input_price_per_million = 1.337, + model_key = '', + output_price_per_million = 1.337, + updated_at = '', + ) + """ + + def testPricingResponse(self): + """Test PricingResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_set_pricing_request.py b/src/otari/_generated/test/test_set_pricing_request.py new file mode 100644 index 0000000..fcf3732 --- /dev/null +++ b/src/otari/_generated/test/test_set_pricing_request.py @@ -0,0 +1,57 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.set_pricing_request import SetPricingRequest + +class TestSetPricingRequest(unittest.TestCase): + """SetPricingRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SetPricingRequest: + """Test SetPricingRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SetPricingRequest` + """ + model = SetPricingRequest() + if include_optional: + return SetPricingRequest( + effective_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + input_price_per_million = 0.0, + model_key = '', + output_price_per_million = 0.0 + ) + else: + return SetPricingRequest( + input_price_per_million = 0.0, + model_key = '', + output_price_per_million = 0.0, + ) + """ + + def testSetPricingRequest(self): + """Test SetPricingRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_update_budget_request.py b/src/otari/_generated/test/test_update_budget_request.py new file mode 100644 index 0000000..7ed6d31 --- /dev/null +++ b/src/otari/_generated/test/test_update_budget_request.py @@ -0,0 +1,52 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest + +class TestUpdateBudgetRequest(unittest.TestCase): + """UpdateBudgetRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateBudgetRequest: + """Test UpdateBudgetRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdateBudgetRequest` + """ + model = UpdateBudgetRequest() + if include_optional: + return UpdateBudgetRequest( + budget_duration_sec = 0.0, + max_budget = 0.0 + ) + else: + return UpdateBudgetRequest( + ) + """ + + def testUpdateBudgetRequest(self): + """Test UpdateBudgetRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_update_key_request.py b/src/otari/_generated/test/test_update_key_request.py new file mode 100644 index 0000000..9dda1f0 --- /dev/null +++ b/src/otari/_generated/test/test_update_key_request.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.update_key_request import UpdateKeyRequest + +class TestUpdateKeyRequest(unittest.TestCase): + """UpdateKeyRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateKeyRequest: + """Test UpdateKeyRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdateKeyRequest` + """ + model = UpdateKeyRequest() + if include_optional: + return UpdateKeyRequest( + expires_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + is_active = True, + key_name = '', + metadata = { } + ) + else: + return UpdateKeyRequest( + ) + """ + + def testUpdateKeyRequest(self): + """Test UpdateKeyRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_update_user_request.py b/src/otari/_generated/test/test_update_user_request.py new file mode 100644 index 0000000..f6b5a7a --- /dev/null +++ b/src/otari/_generated/test/test_update_user_request.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.update_user_request import UpdateUserRequest + +class TestUpdateUserRequest(unittest.TestCase): + """UpdateUserRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdateUserRequest: + """Test UpdateUserRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdateUserRequest` + """ + model = UpdateUserRequest() + if include_optional: + return UpdateUserRequest( + alias = '', + blocked = True, + budget_id = '', + metadata = { } + ) + else: + return UpdateUserRequest( + ) + """ + + def testUpdateUserRequest(self): + """Test UpdateUserRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_usage_api.py b/src/otari/_generated/test/test_usage_api.py new file mode 100644 index 0000000..26c3b0e --- /dev/null +++ b/src/otari/_generated/test/test_usage_api.py @@ -0,0 +1,38 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.api.usage_api import UsageApi + + +class TestUsageApi(unittest.TestCase): + """UsageApi unit test stubs""" + + def setUp(self) -> None: + self.api = UsageApi() + + def tearDown(self) -> None: + pass + + def test_list_usage_v1_usage_get(self) -> None: + """Test case for list_usage_v1_usage_get + + List Usage + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_usage_entry.py b/src/otari/_generated/test/test_usage_entry.py new file mode 100644 index 0000000..1201ada --- /dev/null +++ b/src/otari/_generated/test/test_usage_entry.py @@ -0,0 +1,76 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.usage_entry import UsageEntry + +class TestUsageEntry(unittest.TestCase): + """UsageEntry unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UsageEntry: + """Test UsageEntry + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UsageEntry` + """ + model = UsageEntry() + if include_optional: + return UsageEntry( + api_key_id = '', + completion_tokens = 56, + cost = 1.337, + endpoint = '', + error_message = '', + id = '', + model = '', + prompt_tokens = 56, + provider = '', + status = '', + timestamp = '', + total_tokens = 56, + user_id = '' + ) + else: + return UsageEntry( + api_key_id = '', + completion_tokens = 56, + cost = 1.337, + endpoint = '', + error_message = '', + id = '', + model = '', + prompt_tokens = 56, + provider = '', + status = '', + timestamp = '', + total_tokens = 56, + user_id = '', + ) + """ + + def testUsageEntry(self): + """Test UsageEntry""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_usage_log_response.py b/src/otari/_generated/test/test_usage_log_response.py new file mode 100644 index 0000000..d836747 --- /dev/null +++ b/src/otari/_generated/test/test_usage_log_response.py @@ -0,0 +1,76 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.usage_log_response import UsageLogResponse + +class TestUsageLogResponse(unittest.TestCase): + """UsageLogResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UsageLogResponse: + """Test UsageLogResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UsageLogResponse` + """ + model = UsageLogResponse() + if include_optional: + return UsageLogResponse( + api_key_id = '', + completion_tokens = 56, + cost = 1.337, + endpoint = '', + error_message = '', + id = '', + model = '', + prompt_tokens = 56, + provider = '', + status = '', + timestamp = '', + total_tokens = 56, + user_id = '' + ) + else: + return UsageLogResponse( + api_key_id = '', + completion_tokens = 56, + cost = 1.337, + endpoint = '', + error_message = '', + id = '', + model = '', + prompt_tokens = 56, + provider = '', + status = '', + timestamp = '', + total_tokens = 56, + user_id = '', + ) + """ + + def testUsageLogResponse(self): + """Test UsageLogResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_user_response.py b/src/otari/_generated/test/test_user_response.py new file mode 100644 index 0000000..ef4eb5a --- /dev/null +++ b/src/otari/_generated/test/test_user_response.py @@ -0,0 +1,72 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.user_response import UserResponse + +class TestUserResponse(unittest.TestCase): + """UserResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UserResponse: + """Test UserResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UserResponse` + """ + model = UserResponse() + if include_optional: + return UserResponse( + alias = '', + blocked = True, + budget_id = '', + budget_started_at = '', + created_at = '', + metadata = { }, + next_budget_reset_at = '', + reserved = 1.337, + spend = 1.337, + updated_at = '', + user_id = '' + ) + else: + return UserResponse( + alias = '', + blocked = True, + budget_id = '', + budget_started_at = '', + created_at = '', + metadata = { }, + next_budget_reset_at = '', + reserved = 1.337, + spend = 1.337, + updated_at = '', + user_id = '', + ) + """ + + def testUserResponse(self): + """Test UserResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_users_api.py b/src/otari/_generated/test/test_users_api.py new file mode 100644 index 0000000..70524e3 --- /dev/null +++ b/src/otari/_generated/test/test_users_api.py @@ -0,0 +1,73 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.api.users_api import UsersApi + + +class TestUsersApi(unittest.TestCase): + """UsersApi unit test stubs""" + + def setUp(self) -> None: + self.api = UsersApi() + + def tearDown(self) -> None: + pass + + def test_create_user_v1_users_post(self) -> None: + """Test case for create_user_v1_users_post + + Create User + """ + pass + + def test_delete_user_v1_users_user_id_delete(self) -> None: + """Test case for delete_user_v1_users_user_id_delete + + Delete User + """ + pass + + def test_get_user_usage_v1_users_user_id_usage_get(self) -> None: + """Test case for get_user_usage_v1_users_user_id_usage_get + + Get User Usage + """ + pass + + def test_get_user_v1_users_user_id_get(self) -> None: + """Test case for get_user_v1_users_user_id_get + + Get User + """ + pass + + def test_list_users_v1_users_get(self) -> None: + """Test case for list_users_v1_users_get + + List Users + """ + pass + + def test_update_user_v1_users_user_id_patch(self) -> None: + """Test case for update_user_v1_users_user_id_patch + + Update User + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/test/test_validation_error.py b/src/otari/_generated/test/test_validation_error.py new file mode 100644 index 0000000..78410b8 --- /dev/null +++ b/src/otari/_generated/test/test_validation_error.py @@ -0,0 +1,62 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from otari_control_plane.models.validation_error import ValidationError + +class TestValidationError(unittest.TestCase): + """ValidationError unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ValidationError: + """Test ValidationError + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ValidationError` + """ + model = ValidationError() + if include_optional: + return ValidationError( + ctx = otari_control_plane.models.context.Context(), + input = None, + loc = [ + null + ], + msg = '', + type = '' + ) + else: + return ValidationError( + loc = [ + null + ], + msg = '', + type = '', + ) + """ + + def testValidationError(self): + """Test ValidationError""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/src/otari/_generated/tox.ini b/src/otari/_generated/tox.ini new file mode 100644 index 0000000..9dd164c --- /dev/null +++ b/src/otari/_generated/tox.ini @@ -0,0 +1,9 @@ +[tox] +envlist = py3 + +[testenv] +deps=-r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +commands= + pytest --cov=otari_control_plane From ee86b3b3d8bd0e4ed08bb302a5aefe5576cfc2d5 Mon Sep 17 00:00:00 2001 From: njbrake Date: Fri, 5 Jun 2026 17:23:28 +0000 Subject: [PATCH 2/6] Add control-plane integration tests (generated client) Full CRUD lifecycle tests for every control-plane endpoint (keys, users, budgets, pricing, usage) driving the generated client against a real gateway started on SQLite with a master key (no provider creds needed). Verified 22 endpoint operations pass; documents the Bearer-auth requirement and the per-language test pattern. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/integration/README.md | 57 ++++++ .../test_control_plane_generated.py | 193 ++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 tests/integration/README.md create mode 100644 tests/integration/test_control_plane_generated.py diff --git a/tests/integration/README.md b/tests/integration/README.md new file mode 100644 index 0000000..e0e35f8 --- /dev/null +++ b/tests/integration/README.md @@ -0,0 +1,57 @@ +# Control-plane integration tests + +Strategy for verifying each control-plane endpoint (keys, users, budgets, +pricing, usage) end to end against a real gateway. `test_control_plane_generated.py` +is the Python reference; the same shape applies to the TS / Go / Rust SDKs. + +## Why this works without Docker or provider keys + +Control-plane endpoints are pure gateway + DB operations; they never call an LLM +provider. So a test can run the gateway on **SQLite** with just a **master key**: +no Postgres, no provider credentials. The fixture starts `gateway serve +--database-url sqlite:///... --master-key ... --auto-migrate`, waits for +`/health`, and tears it down. + +## Auth (verified) + +Management endpoints authenticate with `Authorization: Bearer `. +The `Otari-Key` header is for the virtual API keys used on inference endpoints +and returns 401 here. The integrated client must send Bearer for control-plane +calls. + +## Per-endpoint coverage + +Each resource is exercised through its full lifecycle, with extra attention on +the create/POST operations (the manually-integrated surface): + +| Resource | create | get | list | update | delete | extra | +|----------|--------|-----|------|--------|--------|-------| +| budgets | ✓ (asserts `budget_id`, `max_budget`) | ✓ | ✓ | ✓ | ✓ → 404 | | +| users | ✓ | ✓ | ✓ | ✓ | ✓ → 404 | `GET .../usage` | +| keys | ✓ (asserts the one-time `key` secret is returned) | ✓ | ✓ | ✓ | ✓ → 404 | | +| pricing | ✓ | ✓ | ✓ | — | ✓ → 404 | `GET .../history` | +| usage | — | — | ✓ | — | — | | + +Identifier fields differ per resource (gateway convention): `id` (keys), +`user_id` (users), `budget_id` (budgets), `model_key` (pricing). + +## Other languages (same pattern) + +- **TypeScript** (vitest): a `beforeAll` spawns the gateway via `child_process`, + polls `/health`; tests use the generated fetch client with an `Authorization` + header; `afterAll` kills it. +- **Go** (`testing`): `TestMain` starts the gateway with `os/exec`, waits on + `/health`; table-driven lifecycle tests per resource; defer cleanup. +- **Rust** (`tokio::test` + a shared harness): spawn the gateway with + `std::process::Command`, await `/health`; reqwest-based generated client. + +## Running + +```bash +# gateway must be importable as a console script (or set OTARI_GATEWAY_CMD) +OTARI_GATEWAY_CMD="gateway" pytest tests/integration/test_control_plane_generated.py -v +``` + +These tests target the generated client at `src/otari/_generated` for now. Once +it is wired into the public client, point the imports at the public surface so +the tests also cover the manual integration layer. diff --git a/tests/integration/test_control_plane_generated.py b/tests/integration/test_control_plane_generated.py new file mode 100644 index 0000000..7df8d8c --- /dev/null +++ b/tests/integration/test_control_plane_generated.py @@ -0,0 +1,193 @@ +"""Integration tests for the generated control-plane client against a live gateway. + +These drive the generated control-plane client through a full CRUD lifecycle for +every management endpoint (keys, users, budgets, pricing, usage). They start a +real gateway on SQLite with a master key, so no provider credentials or database +server are needed: control-plane endpoints never call an LLM provider. + +Run requirements: +- The ``gateway`` console script on PATH (set ``OTARI_GATEWAY_CMD`` to override), + e.g. ``pip install otari-gateway`` in CI. +- The generated client importable (this preview imports it from + ``src/otari/_generated``; once it is wired into the public client, import from + there instead). + +Auth note, verified against the gateway: management endpoints authenticate via +``Authorization: Bearer ``, NOT the ``Otari-Key`` virtual-key header +used for inference. +""" + +from __future__ import annotations + +import contextlib +import os +import socket +import subprocess +import sys +import tempfile +import time +import urllib.error +import urllib.request +from collections.abc import Iterator +from pathlib import Path + +import pytest + +pytestmark = pytest.mark.integration + +MASTER_KEY = "itest-master-key" + +# Preview: import the generated client from where the codegen PR drops it. +_GENERATED = Path(__file__).resolve().parents[2] / "src" / "otari" / "_generated" +if _GENERATED.is_dir(): + sys.path.insert(0, str(_GENERATED)) + +ocp = pytest.importorskip("otari_control_plane", reason="generated control-plane client not present") + +from otari_control_plane.api.budgets_api import BudgetsApi # noqa: E402 +from otari_control_plane.api.keys_api import KeysApi # noqa: E402 +from otari_control_plane.api.pricing_api import PricingApi # noqa: E402 +from otari_control_plane.api.usage_api import UsageApi # noqa: E402 +from otari_control_plane.api.users_api import UsersApi # noqa: E402 +from otari_control_plane.exceptions import NotFoundException # noqa: E402 +from otari_control_plane.models.create_budget_request import CreateBudgetRequest # noqa: E402 +from otari_control_plane.models.create_key_request import CreateKeyRequest # noqa: E402 +from otari_control_plane.models.create_user_request import CreateUserRequest # noqa: E402 +from otari_control_plane.models.set_pricing_request import SetPricingRequest # noqa: E402 +from otari_control_plane.models.update_budget_request import UpdateBudgetRequest # noqa: E402 +from otari_control_plane.models.update_key_request import UpdateKeyRequest # noqa: E402 +from otari_control_plane.models.update_user_request import UpdateUserRequest # noqa: E402 + + +def _free_port() -> int: + with socket.socket() as sock: + sock.bind(("127.0.0.1", 0)) + return int(sock.getsockname()[1]) + + +def _wait_healthy(base_url: str, timeout: float = 30.0) -> None: + deadline = time.time() + timeout + while time.time() < deadline: + with contextlib.suppress(urllib.error.URLError, ConnectionError): + with urllib.request.urlopen(f"{base_url}/health", timeout=2) as resp: + if resp.status == 200: + return + time.sleep(0.3) + raise RuntimeError(f"gateway did not become healthy at {base_url}") + + +@pytest.fixture(scope="module") +def gateway_url() -> Iterator[str]: + cmd = os.environ.get("OTARI_GATEWAY_CMD", "gateway").split() + port = _free_port() + db_path = tempfile.NamedTemporaryFile(suffix=".db", delete=False).name + proc = subprocess.Popen( + [ + *cmd, "serve", + "--database-url", f"sqlite:///{db_path}", + "--master-key", MASTER_KEY, + "--host", "127.0.0.1", "--port", str(port), + "--auto-migrate", "--log-level", "40", + ], + stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, + ) + base_url = f"http://127.0.0.1:{port}" + try: + _wait_healthy(base_url) + yield base_url + finally: + proc.terminate() + with contextlib.suppress(subprocess.TimeoutExpired): + proc.wait(timeout=10) + with contextlib.suppress(FileNotFoundError): + os.unlink(db_path) + + +@pytest.fixture +def api_client(gateway_url: str) -> Iterator[object]: + config = ocp.Configuration(host=gateway_url) + # Management endpoints use Bearer auth with the master key (not Otari-Key). + with ocp.ApiClient(config) as client: + client.set_default_header("Authorization", f"Bearer {MASTER_KEY}") + yield client + + +def test_budgets_lifecycle(api_client: object) -> None: + api = BudgetsApi(api_client) + created = api.create_budget_v1_budgets_post(CreateBudgetRequest(max_budget=100.0, budget_duration_sec=3600)) + assert created.budget_id + assert created.max_budget == 100.0 + bid = created.budget_id + + assert any(b.budget_id == bid for b in api.list_budgets_v1_budgets_get()) + assert api.get_budget_v1_budgets_budget_id_get(bid).budget_id == bid + + updated = api.update_budget_v1_budgets_budget_id_patch(bid, UpdateBudgetRequest(max_budget=250.0)) + assert updated.max_budget == 250.0 + + api.delete_budget_v1_budgets_budget_id_delete(bid) + with pytest.raises(NotFoundException): + api.get_budget_v1_budgets_budget_id_get(bid) + + +def test_users_lifecycle(api_client: object) -> None: + api = UsersApi(api_client) + created = api.create_user_v1_users_post(CreateUserRequest(user_id="itest-user", alias="Alice")) + assert created.user_id == "itest-user" + assert created.alias == "Alice" + + assert any(u.user_id == "itest-user" for u in api.list_users_v1_users_get()) + assert api.get_user_v1_users_user_id_get("itest-user").user_id == "itest-user" + + updated = api.update_user_v1_users_user_id_patch("itest-user", UpdateUserRequest(alias="Alice2")) + assert updated.alias == "Alice2" + + # usage sub-resource is readable for a known user + api.get_user_usage_v1_users_user_id_usage_get("itest-user") + + api.delete_user_v1_users_user_id_delete("itest-user") + with pytest.raises(NotFoundException): + api.get_user_v1_users_user_id_get("itest-user") + + +def test_keys_lifecycle_returns_secret_on_create(api_client: object) -> None: + api = KeysApi(api_client) + created = api.create_key_v1_keys_post(CreateKeyRequest(key_name="itest-key")) + assert created.id + # The one-time key value must be present on create (manually-created surface). + assert getattr(created, "key", None), "create_key must return the key secret" + kid = created.id + + assert any(k.id == kid for k in api.list_keys_v1_keys_get()) + assert api.get_key_v1_keys_key_id_get(kid).id == kid + + updated = api.update_key_v1_keys_key_id_patch(kid, UpdateKeyRequest(key_name="itest-key-renamed")) + assert updated.key_name == "itest-key-renamed" + + api.delete_key_v1_keys_key_id_delete(kid) + with pytest.raises(NotFoundException): + api.get_key_v1_keys_key_id_get(kid) + + +def test_pricing_lifecycle(api_client: object) -> None: + api = PricingApi(api_client) + model_key = "openai:itest-model" + created = api.set_pricing_v1_pricing_post( + SetPricingRequest(model_key=model_key, input_price_per_million=1.0, output_price_per_million=2.0) + ) + assert created.model_key == model_key + + assert any(p.model_key == model_key for p in api.list_pricing_v1_pricing_get()) + assert api.get_pricing_v1_pricing_model_key_get(model_key).model_key == model_key + # history is populated after at least one set + assert api.get_pricing_history_v1_pricing_model_key_history_get(model_key) is not None + + api.delete_pricing_v1_pricing_model_key_delete(model_key) + with pytest.raises(NotFoundException): + api.get_pricing_v1_pricing_model_key_get(model_key) + + +def test_usage_is_readable(api_client: object) -> None: + api = UsageApi(api_client) + # Fresh gateway: usage list is readable (and empty), proving the typed GET works. + assert api.list_usage_v1_usage_get() is not None From 1664bffc95ea77f02775bc0b17ba2df403371ec5 Mon Sep 17 00:00:00 2001 From: njbrake Date: Fri, 5 Jun 2026 17:40:29 +0000 Subject: [PATCH 3/6] Wire generated control-plane client into OtariClient - Regenerate the control-plane client as a clean subpackage (otari._control_plane). - Add OtariClient.control_plane: typed accessors (keys/users/budgets/pricing/usage) sharing one client authed with Authorization: Bearer using an admin credential (admin_key / GATEWAY_ADMIN_KEY / platform_token). Management endpoints require Bearer, not the Otari-Key inference header. - Add admin_key param + ControlPlane facade; export ControlPlane. - Exclude the generated subpackage from ruff/mypy; add its runtime deps. - Integration tests now drive the public control_plane surface end-to-end (full CRUD per endpoint + admin-credential guard); 6 pass against a live gateway on SQLite. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) --- pyproject.toml | 13 + src/otari/__init__.py | 2 + src/otari/_base.py | 14 + src/otari/_control_plane/__init__.py | 90 ++++ src/otari/_control_plane/api/__init__.py | 9 + .../api/budgets_api.py | 12 +- .../api/keys_api.py | 16 +- .../api/pricing_api.py | 10 +- .../api/usage_api.py | 8 +- .../api/users_api.py | 16 +- .../api_client.py | 12 +- .../api_response.py | 0 .../configuration.py | 2 +- .../exceptions.py | 0 src/otari/_control_plane/models/__init__.py | 33 ++ .../models/budget_response.py | 0 .../models/create_budget_request.py | 0 .../models/create_key_request.py | 0 .../models/create_key_response.py | 0 .../models/create_user_request.py | 0 .../models/http_validation_error.py | 2 +- .../models/key_info.py | 0 .../models/location_inner.py | 0 .../models/pricing_response.py | 0 .../models/set_pricing_request.py | 0 .../models/update_budget_request.py | 0 .../models/update_key_request.py | 0 .../models/update_user_request.py | 0 .../models/usage_entry.py | 0 .../models/usage_log_response.py | 0 .../models/user_response.py | 0 .../models/validation_error.py | 2 +- .../py.typed | 0 .../rest.py | 2 +- .../_generated/.github/workflows/python.yml | 34 -- src/otari/_generated/.gitignore | 66 --- src/otari/_generated/.gitlab-ci.yml | 31 -- .../_generated/.openapi-generator-ignore | 23 - src/otari/_generated/.openapi-generator/FILES | 89 ---- .../_generated/.openapi-generator/VERSION | 1 - src/otari/_generated/.travis.yml | 17 - src/otari/_generated/README.md | 143 ------ src/otari/_generated/docs/BudgetResponse.md | 34 -- src/otari/_generated/docs/BudgetsApi.md | 361 --------------- .../_generated/docs/CreateBudgetRequest.md | 31 -- src/otari/_generated/docs/CreateKeyRequest.md | 33 -- .../_generated/docs/CreateKeyResponse.md | 37 -- .../_generated/docs/CreateUserRequest.md | 34 -- .../_generated/docs/HTTPValidationError.md | 29 -- src/otari/_generated/docs/KeyInfo.md | 37 -- src/otari/_generated/docs/KeysApi.md | 374 --------------- src/otari/_generated/docs/LocationInner.md | 28 -- src/otari/_generated/docs/PricingApi.md | 362 --------------- src/otari/_generated/docs/PricingResponse.md | 35 -- .../_generated/docs/SetPricingRequest.md | 33 -- .../_generated/docs/UpdateBudgetRequest.md | 31 -- src/otari/_generated/docs/UpdateKeyRequest.md | 33 -- .../_generated/docs/UpdateUserRequest.md | 33 -- src/otari/_generated/docs/UsageApi.md | 89 ---- src/otari/_generated/docs/UsageEntry.md | 42 -- src/otari/_generated/docs/UsageLogResponse.md | 42 -- src/otari/_generated/docs/UserResponse.md | 40 -- src/otari/_generated/docs/UsersApi.md | 435 ------------------ src/otari/_generated/docs/ValidationError.md | 33 -- src/otari/_generated/git_push.sh | 57 --- .../otari_control_plane/__init__.py | 90 ---- .../otari_control_plane/api/__init__.py | 9 - .../otari_control_plane/models/__init__.py | 33 -- src/otari/_generated/pyproject.toml | 94 ---- src/otari/_generated/requirements.txt | 4 - src/otari/_generated/setup.cfg | 2 - src/otari/_generated/setup.py | 47 -- src/otari/_generated/test-requirements.txt | 6 - src/otari/_generated/test/__init__.py | 0 .../_generated/test/test_budget_response.py | 60 --- src/otari/_generated/test/test_budgets_api.py | 66 --- .../test/test_create_budget_request.py | 52 --- .../test/test_create_key_request.py | 54 --- .../test/test_create_key_response.py | 66 --- .../test/test_create_user_request.py | 56 --- .../test/test_http_validation_error.py | 60 --- src/otari/_generated/test/test_key_info.py | 66 --- src/otari/_generated/test/test_keys_api.py | 66 --- .../_generated/test/test_location_inner.py | 50 -- src/otari/_generated/test/test_pricing_api.py | 66 --- .../_generated/test/test_pricing_response.py | 62 --- .../test/test_set_pricing_request.py | 57 --- .../test/test_update_budget_request.py | 52 --- .../test/test_update_key_request.py | 54 --- .../test/test_update_user_request.py | 54 --- src/otari/_generated/test/test_usage_api.py | 38 -- src/otari/_generated/test/test_usage_entry.py | 76 --- .../test/test_usage_log_response.py | 76 --- .../_generated/test/test_user_response.py | 72 --- src/otari/_generated/test/test_users_api.py | 73 --- .../_generated/test/test_validation_error.py | 62 --- src/otari/_generated/tox.ini | 9 - src/otari/client.py | 21 + src/otari/control_plane.py | 59 +++ .../test_control_plane_generated.py | 93 ++-- 100 files changed, 324 insertions(+), 4391 deletions(-) create mode 100644 src/otari/_control_plane/__init__.py create mode 100644 src/otari/_control_plane/api/__init__.py rename src/otari/{_generated/otari_control_plane => _control_plane}/api/budgets_api.py (99%) rename src/otari/{_generated/otari_control_plane => _control_plane}/api/keys_api.py (99%) rename src/otari/{_generated/otari_control_plane => _control_plane}/api/pricing_api.py (99%) rename src/otari/{_generated/otari_control_plane => _control_plane}/api/usage_api.py (98%) rename src/otari/{_generated/otari_control_plane => _control_plane}/api/users_api.py (99%) rename src/otari/{_generated/otari_control_plane => _control_plane}/api_client.py (98%) rename src/otari/{_generated/otari_control_plane => _control_plane}/api_response.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/configuration.py (99%) rename src/otari/{_generated/otari_control_plane => _control_plane}/exceptions.py (100%) create mode 100644 src/otari/_control_plane/models/__init__.py rename src/otari/{_generated/otari_control_plane => _control_plane}/models/budget_response.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/create_budget_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/create_key_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/create_key_response.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/create_user_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/http_validation_error.py (97%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/key_info.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/location_inner.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/pricing_response.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/set_pricing_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/update_budget_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/update_key_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/update_user_request.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/usage_entry.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/usage_log_response.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/user_response.py (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/models/validation_error.py (97%) rename src/otari/{_generated/otari_control_plane => _control_plane}/py.typed (100%) rename src/otari/{_generated/otari_control_plane => _control_plane}/rest.py (99%) delete mode 100644 src/otari/_generated/.github/workflows/python.yml delete mode 100644 src/otari/_generated/.gitignore delete mode 100644 src/otari/_generated/.gitlab-ci.yml delete mode 100644 src/otari/_generated/.openapi-generator-ignore delete mode 100644 src/otari/_generated/.openapi-generator/FILES delete mode 100644 src/otari/_generated/.openapi-generator/VERSION delete mode 100644 src/otari/_generated/.travis.yml delete mode 100644 src/otari/_generated/README.md delete mode 100644 src/otari/_generated/docs/BudgetResponse.md delete mode 100644 src/otari/_generated/docs/BudgetsApi.md delete mode 100644 src/otari/_generated/docs/CreateBudgetRequest.md delete mode 100644 src/otari/_generated/docs/CreateKeyRequest.md delete mode 100644 src/otari/_generated/docs/CreateKeyResponse.md delete mode 100644 src/otari/_generated/docs/CreateUserRequest.md delete mode 100644 src/otari/_generated/docs/HTTPValidationError.md delete mode 100644 src/otari/_generated/docs/KeyInfo.md delete mode 100644 src/otari/_generated/docs/KeysApi.md delete mode 100644 src/otari/_generated/docs/LocationInner.md delete mode 100644 src/otari/_generated/docs/PricingApi.md delete mode 100644 src/otari/_generated/docs/PricingResponse.md delete mode 100644 src/otari/_generated/docs/SetPricingRequest.md delete mode 100644 src/otari/_generated/docs/UpdateBudgetRequest.md delete mode 100644 src/otari/_generated/docs/UpdateKeyRequest.md delete mode 100644 src/otari/_generated/docs/UpdateUserRequest.md delete mode 100644 src/otari/_generated/docs/UsageApi.md delete mode 100644 src/otari/_generated/docs/UsageEntry.md delete mode 100644 src/otari/_generated/docs/UsageLogResponse.md delete mode 100644 src/otari/_generated/docs/UserResponse.md delete mode 100644 src/otari/_generated/docs/UsersApi.md delete mode 100644 src/otari/_generated/docs/ValidationError.md delete mode 100644 src/otari/_generated/git_push.sh delete mode 100644 src/otari/_generated/otari_control_plane/__init__.py delete mode 100644 src/otari/_generated/otari_control_plane/api/__init__.py delete mode 100644 src/otari/_generated/otari_control_plane/models/__init__.py delete mode 100644 src/otari/_generated/pyproject.toml delete mode 100644 src/otari/_generated/requirements.txt delete mode 100644 src/otari/_generated/setup.cfg delete mode 100644 src/otari/_generated/setup.py delete mode 100644 src/otari/_generated/test-requirements.txt delete mode 100644 src/otari/_generated/test/__init__.py delete mode 100644 src/otari/_generated/test/test_budget_response.py delete mode 100644 src/otari/_generated/test/test_budgets_api.py delete mode 100644 src/otari/_generated/test/test_create_budget_request.py delete mode 100644 src/otari/_generated/test/test_create_key_request.py delete mode 100644 src/otari/_generated/test/test_create_key_response.py delete mode 100644 src/otari/_generated/test/test_create_user_request.py delete mode 100644 src/otari/_generated/test/test_http_validation_error.py delete mode 100644 src/otari/_generated/test/test_key_info.py delete mode 100644 src/otari/_generated/test/test_keys_api.py delete mode 100644 src/otari/_generated/test/test_location_inner.py delete mode 100644 src/otari/_generated/test/test_pricing_api.py delete mode 100644 src/otari/_generated/test/test_pricing_response.py delete mode 100644 src/otari/_generated/test/test_set_pricing_request.py delete mode 100644 src/otari/_generated/test/test_update_budget_request.py delete mode 100644 src/otari/_generated/test/test_update_key_request.py delete mode 100644 src/otari/_generated/test/test_update_user_request.py delete mode 100644 src/otari/_generated/test/test_usage_api.py delete mode 100644 src/otari/_generated/test/test_usage_entry.py delete mode 100644 src/otari/_generated/test/test_usage_log_response.py delete mode 100644 src/otari/_generated/test/test_user_response.py delete mode 100644 src/otari/_generated/test/test_users_api.py delete mode 100644 src/otari/_generated/test/test_validation_error.py delete mode 100644 src/otari/_generated/tox.ini create mode 100644 src/otari/control_plane.py diff --git a/pyproject.toml b/pyproject.toml index 3aaacfd..1a4da5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,10 @@ classifiers = [ dependencies = [ "openai>=1.99.3", "httpx>=0.25.0", + # Runtime deps of the generated control-plane client (otari._control_plane). + "urllib3>=2.1.0", + "python-dateutil>=2.8.2", + "pydantic>=2.0.0", ] [project.urls] @@ -50,6 +54,8 @@ asyncio_mode = "auto" [tool.ruff] target-version = "py311" line-length = 120 +# Generated control-plane client (OpenAPI Generator output) is not hand-linted. +extend-exclude = ["src/otari/_control_plane"] [tool.ruff.lint] select = ["E", "F", "I", "N", "W", "UP", "S", "B", "A", "C4", "DTZ", "T10", "ISC", "ICN", "PIE", "PT", "RSE", "RET", "SIM", "TID", "TCH", "ARG", "PLC", "PLE", "PLW", "TRY", "FLY", "PERF", "RUF"] @@ -63,3 +69,10 @@ python_version = "3.11" strict = true warn_return_any = true warn_unused_configs = true +# Generated control-plane client (OpenAPI Generator output) is not type-checked here. +exclude = ["src/otari/_control_plane/"] + +[[tool.mypy.overrides]] +module = ["otari._control_plane.*"] +ignore_errors = true +ignore_missing_imports = true diff --git a/src/otari/__init__.py b/src/otari/__init__.py index 1fd260f..de5a8e6 100644 --- a/src/otari/__init__.py +++ b/src/otari/__init__.py @@ -20,6 +20,7 @@ from otari.async_client import AsyncOtariClient from otari.client import OtariClient +from otari.control_plane import ControlPlane from otari.errors import ( AuthenticationError, BatchNotCompleteError, @@ -69,6 +70,7 @@ "ChatCompletion", "ChatCompletionChunk", "ChatCompletionMessageParam", + "ControlPlane", "CreateBatchParams", "CreateEmbeddingResponse", "EmbeddingCreateParams", diff --git a/src/otari/_base.py b/src/otari/_base.py index 32bf6b0..b8347e3 100644 --- a/src/otari/_base.py +++ b/src/otari/_base.py @@ -46,6 +46,8 @@ # Matches the gateway server's own alias chain (OTARI_AI_TOKEN preferred). _ENV_PLATFORM_TOKEN = "OTARI_AI_TOKEN" # noqa: S105 _ENV_PLATFORM_TOKEN_LEGACY = "GATEWAY_PLATFORM_TOKEN" # noqa: S105 +# Admin/master credential for the control-plane (management) endpoints. +_ENV_ADMIN_KEY = "GATEWAY_ADMIN_KEY" _STATUS_TO_ERROR: dict[int, type[AuthenticationError] | type[ModelNotFoundError]] = { 401: AuthenticationError, @@ -72,6 +74,7 @@ def __init__( *, api_key: str | None = None, platform_token: str | None = None, + admin_key: str | None = None, default_headers: dict[str, str] | None = None, openai_options: dict[str, Any] | None = None, ) -> None: @@ -149,6 +152,17 @@ def __init__( if default_headers: self._auth_headers.update(default_headers) + # Control-plane (management) auth. Those endpoints expect + # ``Authorization: Bearer ``. In platform mode the + # platform token already serves as that bearer; for a self-hosted + # gateway the caller passes the master key as ``admin_key`` (or via + # ``GATEWAY_ADMIN_KEY``). The control-plane client targets the gateway + # root (the generated paths already include the ``/v1`` prefix). + self._gateway_root_url = api_base_url.removesuffix("/v1") + self._admin_token: str | None = ( + admin_key or os.environ.get(_ENV_ADMIN_KEY) or resolved_platform_token + ) + # -- Error handling ----------------------------------------------------- def _handle_error(self, error: Exception) -> None: diff --git a/src/otari/_control_plane/__init__.py b/src/otari/_control_plane/__init__.py new file mode 100644 index 0000000..ced6b18 --- /dev/null +++ b/src/otari/_control_plane/__init__.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +# flake8: noqa + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +__version__ = "1.0.0" + +# Define package exports +__all__ = [ + "BudgetsApi", + "KeysApi", + "PricingApi", + "UsageApi", + "UsersApi", + "ApiResponse", + "ApiClient", + "Configuration", + "OpenApiException", + "ApiTypeError", + "ApiValueError", + "ApiKeyError", + "ApiAttributeError", + "ApiException", + "BudgetResponse", + "CreateBudgetRequest", + "CreateKeyRequest", + "CreateKeyResponse", + "CreateUserRequest", + "HTTPValidationError", + "KeyInfo", + "LocationInner", + "PricingResponse", + "SetPricingRequest", + "UpdateBudgetRequest", + "UpdateKeyRequest", + "UpdateUserRequest", + "UsageEntry", + "UsageLogResponse", + "UserResponse", + "ValidationError", +] + +# import apis into sdk package +from otari._control_plane.api.budgets_api import BudgetsApi as BudgetsApi +from otari._control_plane.api.keys_api import KeysApi as KeysApi +from otari._control_plane.api.pricing_api import PricingApi as PricingApi +from otari._control_plane.api.usage_api import UsageApi as UsageApi +from otari._control_plane.api.users_api import UsersApi as UsersApi + +# import ApiClient +from otari._control_plane.api_response import ApiResponse as ApiResponse +from otari._control_plane.api_client import ApiClient as ApiClient +from otari._control_plane.configuration import Configuration as Configuration +from otari._control_plane.exceptions import OpenApiException as OpenApiException +from otari._control_plane.exceptions import ApiTypeError as ApiTypeError +from otari._control_plane.exceptions import ApiValueError as ApiValueError +from otari._control_plane.exceptions import ApiKeyError as ApiKeyError +from otari._control_plane.exceptions import ApiAttributeError as ApiAttributeError +from otari._control_plane.exceptions import ApiException as ApiException + +# import models into sdk package +from otari._control_plane.models.budget_response import BudgetResponse as BudgetResponse +from otari._control_plane.models.create_budget_request import CreateBudgetRequest as CreateBudgetRequest +from otari._control_plane.models.create_key_request import CreateKeyRequest as CreateKeyRequest +from otari._control_plane.models.create_key_response import CreateKeyResponse as CreateKeyResponse +from otari._control_plane.models.create_user_request import CreateUserRequest as CreateUserRequest +from otari._control_plane.models.http_validation_error import HTTPValidationError as HTTPValidationError +from otari._control_plane.models.key_info import KeyInfo as KeyInfo +from otari._control_plane.models.location_inner import LocationInner as LocationInner +from otari._control_plane.models.pricing_response import PricingResponse as PricingResponse +from otari._control_plane.models.set_pricing_request import SetPricingRequest as SetPricingRequest +from otari._control_plane.models.update_budget_request import UpdateBudgetRequest as UpdateBudgetRequest +from otari._control_plane.models.update_key_request import UpdateKeyRequest as UpdateKeyRequest +from otari._control_plane.models.update_user_request import UpdateUserRequest as UpdateUserRequest +from otari._control_plane.models.usage_entry import UsageEntry as UsageEntry +from otari._control_plane.models.usage_log_response import UsageLogResponse as UsageLogResponse +from otari._control_plane.models.user_response import UserResponse as UserResponse +from otari._control_plane.models.validation_error import ValidationError as ValidationError + diff --git a/src/otari/_control_plane/api/__init__.py b/src/otari/_control_plane/api/__init__.py new file mode 100644 index 0000000..449fed3 --- /dev/null +++ b/src/otari/_control_plane/api/__init__.py @@ -0,0 +1,9 @@ +# flake8: noqa + +# import apis into api package +from otari._control_plane.api.budgets_api import BudgetsApi +from otari._control_plane.api.keys_api import KeysApi +from otari._control_plane.api.pricing_api import PricingApi +from otari._control_plane.api.usage_api import UsageApi +from otari._control_plane.api.users_api import UsersApi + diff --git a/src/otari/_generated/otari_control_plane/api/budgets_api.py b/src/otari/_control_plane/api/budgets_api.py similarity index 99% rename from src/otari/_generated/otari_control_plane/api/budgets_api.py rename to src/otari/_control_plane/api/budgets_api.py index 374dd38..a1590cb 100644 --- a/src/otari/_generated/otari_control_plane/api/budgets_api.py +++ b/src/otari/_control_plane/api/budgets_api.py @@ -18,13 +18,13 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari_control_plane.models.budget_response import BudgetResponse -from otari_control_plane.models.create_budget_request import CreateBudgetRequest -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest +from otari._control_plane.models.budget_response import BudgetResponse +from otari._control_plane.models.create_budget_request import CreateBudgetRequest +from otari._control_plane.models.update_budget_request import UpdateBudgetRequest -from otari_control_plane.api_client import ApiClient, RequestSerialized -from otari_control_plane.api_response import ApiResponse -from otari_control_plane.rest import RESTResponseType +from otari._control_plane.api_client import ApiClient, RequestSerialized +from otari._control_plane.api_response import ApiResponse +from otari._control_plane.rest import RESTResponseType class BudgetsApi: diff --git a/src/otari/_generated/otari_control_plane/api/keys_api.py b/src/otari/_control_plane/api/keys_api.py similarity index 99% rename from src/otari/_generated/otari_control_plane/api/keys_api.py rename to src/otari/_control_plane/api/keys_api.py index dc61a0f..e95679b 100644 --- a/src/otari/_generated/otari_control_plane/api/keys_api.py +++ b/src/otari/_control_plane/api/keys_api.py @@ -18,14 +18,14 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari_control_plane.models.create_key_request import CreateKeyRequest -from otari_control_plane.models.create_key_response import CreateKeyResponse -from otari_control_plane.models.key_info import KeyInfo -from otari_control_plane.models.update_key_request import UpdateKeyRequest - -from otari_control_plane.api_client import ApiClient, RequestSerialized -from otari_control_plane.api_response import ApiResponse -from otari_control_plane.rest import RESTResponseType +from otari._control_plane.models.create_key_request import CreateKeyRequest +from otari._control_plane.models.create_key_response import CreateKeyResponse +from otari._control_plane.models.key_info import KeyInfo +from otari._control_plane.models.update_key_request import UpdateKeyRequest + +from otari._control_plane.api_client import ApiClient, RequestSerialized +from otari._control_plane.api_response import ApiResponse +from otari._control_plane.rest import RESTResponseType class KeysApi: diff --git a/src/otari/_generated/otari_control_plane/api/pricing_api.py b/src/otari/_control_plane/api/pricing_api.py similarity index 99% rename from src/otari/_generated/otari_control_plane/api/pricing_api.py rename to src/otari/_control_plane/api/pricing_api.py index 2e2bf80..73ec780 100644 --- a/src/otari/_generated/otari_control_plane/api/pricing_api.py +++ b/src/otari/_control_plane/api/pricing_api.py @@ -19,12 +19,12 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari_control_plane.models.pricing_response import PricingResponse -from otari_control_plane.models.set_pricing_request import SetPricingRequest +from otari._control_plane.models.pricing_response import PricingResponse +from otari._control_plane.models.set_pricing_request import SetPricingRequest -from otari_control_plane.api_client import ApiClient, RequestSerialized -from otari_control_plane.api_response import ApiResponse -from otari_control_plane.rest import RESTResponseType +from otari._control_plane.api_client import ApiClient, RequestSerialized +from otari._control_plane.api_response import ApiResponse +from otari._control_plane.rest import RESTResponseType class PricingApi: diff --git a/src/otari/_generated/otari_control_plane/api/usage_api.py b/src/otari/_control_plane/api/usage_api.py similarity index 98% rename from src/otari/_generated/otari_control_plane/api/usage_api.py rename to src/otari/_control_plane/api/usage_api.py index 3406dff..d811abf 100644 --- a/src/otari/_generated/otari_control_plane/api/usage_api.py +++ b/src/otari/_control_plane/api/usage_api.py @@ -19,11 +19,11 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari_control_plane.models.usage_entry import UsageEntry +from otari._control_plane.models.usage_entry import UsageEntry -from otari_control_plane.api_client import ApiClient, RequestSerialized -from otari_control_plane.api_response import ApiResponse -from otari_control_plane.rest import RESTResponseType +from otari._control_plane.api_client import ApiClient, RequestSerialized +from otari._control_plane.api_response import ApiResponse +from otari._control_plane.rest import RESTResponseType class UsageApi: diff --git a/src/otari/_generated/otari_control_plane/api/users_api.py b/src/otari/_control_plane/api/users_api.py similarity index 99% rename from src/otari/_generated/otari_control_plane/api/users_api.py rename to src/otari/_control_plane/api/users_api.py index 5c369d6..26beef2 100644 --- a/src/otari/_generated/otari_control_plane/api/users_api.py +++ b/src/otari/_control_plane/api/users_api.py @@ -18,14 +18,14 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari_control_plane.models.create_user_request import CreateUserRequest -from otari_control_plane.models.update_user_request import UpdateUserRequest -from otari_control_plane.models.usage_log_response import UsageLogResponse -from otari_control_plane.models.user_response import UserResponse - -from otari_control_plane.api_client import ApiClient, RequestSerialized -from otari_control_plane.api_response import ApiResponse -from otari_control_plane.rest import RESTResponseType +from otari._control_plane.models.create_user_request import CreateUserRequest +from otari._control_plane.models.update_user_request import UpdateUserRequest +from otari._control_plane.models.usage_log_response import UsageLogResponse +from otari._control_plane.models.user_response import UserResponse + +from otari._control_plane.api_client import ApiClient, RequestSerialized +from otari._control_plane.api_response import ApiResponse +from otari._control_plane.rest import RESTResponseType class UsersApi: diff --git a/src/otari/_generated/otari_control_plane/api_client.py b/src/otari/_control_plane/api_client.py similarity index 98% rename from src/otari/_generated/otari_control_plane/api_client.py rename to src/otari/_control_plane/api_client.py index 10bf7a6..ade80f9 100644 --- a/src/otari/_generated/otari_control_plane/api_client.py +++ b/src/otari/_control_plane/api_client.py @@ -26,11 +26,11 @@ from typing import Tuple, Optional, List, Dict, Union from pydantic import SecretStr -from otari_control_plane.configuration import Configuration -from otari_control_plane.api_response import ApiResponse, T as ApiResponseT -import otari_control_plane.models -from otari_control_plane import rest -from otari_control_plane.exceptions import ( +from otari._control_plane.configuration import Configuration +from otari._control_plane.api_response import ApiResponse, T as ApiResponseT +import otari._control_plane.models +from otari._control_plane import rest +from otari._control_plane.exceptions import ( ApiValueError, ApiException, BadRequestException, @@ -452,7 +452,7 @@ def __deserialize(self, data, klass): if klass in self.NATIVE_TYPES_MAPPING: klass = self.NATIVE_TYPES_MAPPING[klass] else: - klass = getattr(otari_control_plane.models, klass) + klass = getattr(otari._control_plane.models, klass) if klass in self.PRIMITIVE_TYPES: return self.__deserialize_primitive(data, klass) diff --git a/src/otari/_generated/otari_control_plane/api_response.py b/src/otari/_control_plane/api_response.py similarity index 100% rename from src/otari/_generated/otari_control_plane/api_response.py rename to src/otari/_control_plane/api_response.py diff --git a/src/otari/_generated/otari_control_plane/configuration.py b/src/otari/_control_plane/configuration.py similarity index 99% rename from src/otari/_generated/otari_control_plane/configuration.py rename to src/otari/_control_plane/configuration.py index 5712416..7fd7ba7 100644 --- a/src/otari/_generated/otari_control_plane/configuration.py +++ b/src/otari/_control_plane/configuration.py @@ -256,7 +256,7 @@ def __init__( self.logger = {} """Logging Settings """ - self.logger["package_logger"] = logging.getLogger("otari_control_plane") + self.logger["package_logger"] = logging.getLogger("otari._control_plane") self.logger["urllib3_logger"] = logging.getLogger("urllib3") self.logger_format = '%(asctime)s %(levelname)s %(message)s' """Log format diff --git a/src/otari/_generated/otari_control_plane/exceptions.py b/src/otari/_control_plane/exceptions.py similarity index 100% rename from src/otari/_generated/otari_control_plane/exceptions.py rename to src/otari/_control_plane/exceptions.py diff --git a/src/otari/_control_plane/models/__init__.py b/src/otari/_control_plane/models/__init__.py new file mode 100644 index 0000000..33c553c --- /dev/null +++ b/src/otari/_control_plane/models/__init__.py @@ -0,0 +1,33 @@ +# coding: utf-8 + +# flake8: noqa +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +# import models into model package +from otari._control_plane.models.budget_response import BudgetResponse +from otari._control_plane.models.create_budget_request import CreateBudgetRequest +from otari._control_plane.models.create_key_request import CreateKeyRequest +from otari._control_plane.models.create_key_response import CreateKeyResponse +from otari._control_plane.models.create_user_request import CreateUserRequest +from otari._control_plane.models.http_validation_error import HTTPValidationError +from otari._control_plane.models.key_info import KeyInfo +from otari._control_plane.models.location_inner import LocationInner +from otari._control_plane.models.pricing_response import PricingResponse +from otari._control_plane.models.set_pricing_request import SetPricingRequest +from otari._control_plane.models.update_budget_request import UpdateBudgetRequest +from otari._control_plane.models.update_key_request import UpdateKeyRequest +from otari._control_plane.models.update_user_request import UpdateUserRequest +from otari._control_plane.models.usage_entry import UsageEntry +from otari._control_plane.models.usage_log_response import UsageLogResponse +from otari._control_plane.models.user_response import UserResponse +from otari._control_plane.models.validation_error import ValidationError + diff --git a/src/otari/_generated/otari_control_plane/models/budget_response.py b/src/otari/_control_plane/models/budget_response.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/budget_response.py rename to src/otari/_control_plane/models/budget_response.py diff --git a/src/otari/_generated/otari_control_plane/models/create_budget_request.py b/src/otari/_control_plane/models/create_budget_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/create_budget_request.py rename to src/otari/_control_plane/models/create_budget_request.py diff --git a/src/otari/_generated/otari_control_plane/models/create_key_request.py b/src/otari/_control_plane/models/create_key_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/create_key_request.py rename to src/otari/_control_plane/models/create_key_request.py diff --git a/src/otari/_generated/otari_control_plane/models/create_key_response.py b/src/otari/_control_plane/models/create_key_response.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/create_key_response.py rename to src/otari/_control_plane/models/create_key_response.py diff --git a/src/otari/_generated/otari_control_plane/models/create_user_request.py b/src/otari/_control_plane/models/create_user_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/create_user_request.py rename to src/otari/_control_plane/models/create_user_request.py diff --git a/src/otari/_generated/otari_control_plane/models/http_validation_error.py b/src/otari/_control_plane/models/http_validation_error.py similarity index 97% rename from src/otari/_generated/otari_control_plane/models/http_validation_error.py rename to src/otari/_control_plane/models/http_validation_error.py index 974e81d..afca717 100644 --- a/src/otari/_generated/otari_control_plane/models/http_validation_error.py +++ b/src/otari/_control_plane/models/http_validation_error.py @@ -19,7 +19,7 @@ from pydantic import BaseModel, ConfigDict from typing import Any, ClassVar, Dict, List, Optional -from otari_control_plane.models.validation_error import ValidationError +from otari._control_plane.models.validation_error import ValidationError from typing import Optional, Set from typing_extensions import Self from pydantic_core import to_jsonable_python diff --git a/src/otari/_generated/otari_control_plane/models/key_info.py b/src/otari/_control_plane/models/key_info.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/key_info.py rename to src/otari/_control_plane/models/key_info.py diff --git a/src/otari/_generated/otari_control_plane/models/location_inner.py b/src/otari/_control_plane/models/location_inner.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/location_inner.py rename to src/otari/_control_plane/models/location_inner.py diff --git a/src/otari/_generated/otari_control_plane/models/pricing_response.py b/src/otari/_control_plane/models/pricing_response.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/pricing_response.py rename to src/otari/_control_plane/models/pricing_response.py diff --git a/src/otari/_generated/otari_control_plane/models/set_pricing_request.py b/src/otari/_control_plane/models/set_pricing_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/set_pricing_request.py rename to src/otari/_control_plane/models/set_pricing_request.py diff --git a/src/otari/_generated/otari_control_plane/models/update_budget_request.py b/src/otari/_control_plane/models/update_budget_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/update_budget_request.py rename to src/otari/_control_plane/models/update_budget_request.py diff --git a/src/otari/_generated/otari_control_plane/models/update_key_request.py b/src/otari/_control_plane/models/update_key_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/update_key_request.py rename to src/otari/_control_plane/models/update_key_request.py diff --git a/src/otari/_generated/otari_control_plane/models/update_user_request.py b/src/otari/_control_plane/models/update_user_request.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/update_user_request.py rename to src/otari/_control_plane/models/update_user_request.py diff --git a/src/otari/_generated/otari_control_plane/models/usage_entry.py b/src/otari/_control_plane/models/usage_entry.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/usage_entry.py rename to src/otari/_control_plane/models/usage_entry.py diff --git a/src/otari/_generated/otari_control_plane/models/usage_log_response.py b/src/otari/_control_plane/models/usage_log_response.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/usage_log_response.py rename to src/otari/_control_plane/models/usage_log_response.py diff --git a/src/otari/_generated/otari_control_plane/models/user_response.py b/src/otari/_control_plane/models/user_response.py similarity index 100% rename from src/otari/_generated/otari_control_plane/models/user_response.py rename to src/otari/_control_plane/models/user_response.py diff --git a/src/otari/_generated/otari_control_plane/models/validation_error.py b/src/otari/_control_plane/models/validation_error.py similarity index 97% rename from src/otari/_generated/otari_control_plane/models/validation_error.py rename to src/otari/_control_plane/models/validation_error.py index ac201a0..7bc0d46 100644 --- a/src/otari/_generated/otari_control_plane/models/validation_error.py +++ b/src/otari/_control_plane/models/validation_error.py @@ -19,7 +19,7 @@ from pydantic import BaseModel, ConfigDict, StrictStr from typing import Any, ClassVar, Dict, List, Optional -from otari_control_plane.models.location_inner import LocationInner +from otari._control_plane.models.location_inner import LocationInner from typing import Optional, Set from typing_extensions import Self from pydantic_core import to_jsonable_python diff --git a/src/otari/_generated/otari_control_plane/py.typed b/src/otari/_control_plane/py.typed similarity index 100% rename from src/otari/_generated/otari_control_plane/py.typed rename to src/otari/_control_plane/py.typed diff --git a/src/otari/_generated/otari_control_plane/rest.py b/src/otari/_control_plane/rest.py similarity index 99% rename from src/otari/_generated/otari_control_plane/rest.py rename to src/otari/_control_plane/rest.py index f4b331b..a35c676 100644 --- a/src/otari/_generated/otari_control_plane/rest.py +++ b/src/otari/_control_plane/rest.py @@ -19,7 +19,7 @@ import urllib3 -from otari_control_plane.exceptions import ApiException, ApiValueError +from otari._control_plane.exceptions import ApiException, ApiValueError SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"} RESTResponseType = urllib3.HTTPResponse diff --git a/src/otari/_generated/.github/workflows/python.yml b/src/otari/_generated/.github/workflows/python.yml deleted file mode 100644 index a0af3a0..0000000 --- a/src/otari/_generated/.github/workflows/python.yml +++ /dev/null @@ -1,34 +0,0 @@ -# NOTE: This file is auto generated by OpenAPI Generator. -# URL: https://openapi-generator.tech -# -# ref: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python - -name: otari_control_plane Python package - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] - - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r test-requirements.txt - - name: Test with pytest - run: | - pytest --cov=otari_control_plane diff --git a/src/otari/_generated/.gitignore b/src/otari/_generated/.gitignore deleted file mode 100644 index 65b06b9..0000000 --- a/src/otari/_generated/.gitignore +++ /dev/null @@ -1,66 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ -venv/ -.venv/ -.python-version -.pytest_cache - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Ipython Notebook -.ipynb_checkpoints diff --git a/src/otari/_generated/.gitlab-ci.yml b/src/otari/_generated/.gitlab-ci.yml deleted file mode 100644 index 56c77b7..0000000 --- a/src/otari/_generated/.gitlab-ci.yml +++ /dev/null @@ -1,31 +0,0 @@ -# NOTE: This file is auto generated by OpenAPI Generator. -# URL: https://openapi-generator.tech -# -# ref: https://docs.gitlab.com/ee/ci/README.html -# ref: https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml - -stages: - - test - -.pytest: - stage: test - script: - - pip install -r requirements.txt - - pip install -r test-requirements.txt - - pytest --cov=otari_control_plane - -pytest-3.10: - extends: .pytest - image: python:3.10-alpine -pytest-3.11: - extends: .pytest - image: python:3.11-alpine -pytest-3.12: - extends: .pytest - image: python:3.12-alpine -pytest-3.13: - extends: .pytest - image: python:3.13-alpine -pytest-3.14: - extends: .pytest - image: python:3.14-alpine diff --git a/src/otari/_generated/.openapi-generator-ignore b/src/otari/_generated/.openapi-generator-ignore deleted file mode 100644 index 7484ee5..0000000 --- a/src/otari/_generated/.openapi-generator-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# OpenAPI Generator Ignore -# Generated by openapi-generator https://github.com/openapitools/openapi-generator - -# Use this file to prevent files from being overwritten by the generator. -# The patterns follow closely to .gitignore or .dockerignore. - -# As an example, the C# client generator defines ApiClient.cs. -# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: -#ApiClient.cs - -# You can match any string of characters against a directory, file or extension with a single asterisk (*): -#foo/*/qux -# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux - -# You can recursively match patterns against a directory, file or extension with a double asterisk (**): -#foo/**/qux -# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux - -# You can also negate patterns with an exclamation (!). -# For example, you can ignore all files in a docs folder with the file extension .md: -#docs/*.md -# Then explicitly reverse the ignore rule for a single file: -#!docs/README.md diff --git a/src/otari/_generated/.openapi-generator/FILES b/src/otari/_generated/.openapi-generator/FILES deleted file mode 100644 index 6d0f285..0000000 --- a/src/otari/_generated/.openapi-generator/FILES +++ /dev/null @@ -1,89 +0,0 @@ -.github/workflows/python.yml -.gitignore -.gitlab-ci.yml -.openapi-generator-ignore -.travis.yml -README.md -docs/BudgetResponse.md -docs/BudgetsApi.md -docs/CreateBudgetRequest.md -docs/CreateKeyRequest.md -docs/CreateKeyResponse.md -docs/CreateUserRequest.md -docs/HTTPValidationError.md -docs/KeyInfo.md -docs/KeysApi.md -docs/LocationInner.md -docs/PricingApi.md -docs/PricingResponse.md -docs/SetPricingRequest.md -docs/UpdateBudgetRequest.md -docs/UpdateKeyRequest.md -docs/UpdateUserRequest.md -docs/UsageApi.md -docs/UsageEntry.md -docs/UsageLogResponse.md -docs/UserResponse.md -docs/UsersApi.md -docs/ValidationError.md -git_push.sh -otari_control_plane/__init__.py -otari_control_plane/api/__init__.py -otari_control_plane/api/budgets_api.py -otari_control_plane/api/keys_api.py -otari_control_plane/api/pricing_api.py -otari_control_plane/api/usage_api.py -otari_control_plane/api/users_api.py -otari_control_plane/api_client.py -otari_control_plane/api_response.py -otari_control_plane/configuration.py -otari_control_plane/exceptions.py -otari_control_plane/models/__init__.py -otari_control_plane/models/budget_response.py -otari_control_plane/models/create_budget_request.py -otari_control_plane/models/create_key_request.py -otari_control_plane/models/create_key_response.py -otari_control_plane/models/create_user_request.py -otari_control_plane/models/http_validation_error.py -otari_control_plane/models/key_info.py -otari_control_plane/models/location_inner.py -otari_control_plane/models/pricing_response.py -otari_control_plane/models/set_pricing_request.py -otari_control_plane/models/update_budget_request.py -otari_control_plane/models/update_key_request.py -otari_control_plane/models/update_user_request.py -otari_control_plane/models/usage_entry.py -otari_control_plane/models/usage_log_response.py -otari_control_plane/models/user_response.py -otari_control_plane/models/validation_error.py -otari_control_plane/py.typed -otari_control_plane/rest.py -pyproject.toml -requirements.txt -setup.cfg -setup.py -test-requirements.txt -test/__init__.py -test/test_budget_response.py -test/test_budgets_api.py -test/test_create_budget_request.py -test/test_create_key_request.py -test/test_create_key_response.py -test/test_create_user_request.py -test/test_http_validation_error.py -test/test_key_info.py -test/test_keys_api.py -test/test_location_inner.py -test/test_pricing_api.py -test/test_pricing_response.py -test/test_set_pricing_request.py -test/test_update_budget_request.py -test/test_update_key_request.py -test/test_update_user_request.py -test/test_usage_api.py -test/test_usage_entry.py -test/test_usage_log_response.py -test/test_user_response.py -test/test_users_api.py -test/test_validation_error.py -tox.ini diff --git a/src/otari/_generated/.openapi-generator/VERSION b/src/otari/_generated/.openapi-generator/VERSION deleted file mode 100644 index 696eaac..0000000 --- a/src/otari/_generated/.openapi-generator/VERSION +++ /dev/null @@ -1 +0,0 @@ -7.22.0 diff --git a/src/otari/_generated/.travis.yml b/src/otari/_generated/.travis.yml deleted file mode 100644 index b377cf9..0000000 --- a/src/otari/_generated/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -# ref: https://docs.travis-ci.com/user/languages/python -language: python -python: - - "3.10" - - "3.11" - - "3.12" - - "3.13" - - "3.14" - # uncomment the following if needed - #- "3.14-dev" # 3.14 development branch - #- "nightly" # nightly build -# command to install dependencies -install: - - "pip install -r requirements.txt" - - "pip install -r test-requirements.txt" -# command to run tests -script: pytest --cov=otari_control_plane diff --git a/src/otari/_generated/README.md b/src/otari/_generated/README.md deleted file mode 100644 index ee135e7..0000000 --- a/src/otari/_generated/README.md +++ /dev/null @@ -1,143 +0,0 @@ -# otari-control-plane -A clean FastAPI gateway for otari with API key management - -This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - -- API version: 0.0.0-dev -- Package version: 1.0.0 -- Generator version: 7.22.0 -- Build package: org.openapitools.codegen.languages.PythonClientCodegen - -## Requirements. - -Python 3.10+ - -## Installation & Usage -### pip install - -If the python package is hosted on a repository, you can install directly using: - -```sh -pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git -``` -(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`) - -Then import the package: -```python -import otari_control_plane -``` - -### Setuptools - -Install via [Setuptools](http://pypi.python.org/pypi/setuptools). - -```sh -python setup.py install --user -``` -(or `sudo python setup.py install` to install the package for all users) - -Then import the package: -```python -import otari_control_plane -``` - -### Tests - -Execute `pytest` to run the tests. - -## Getting Started - -Please follow the [installation procedure](#installation--usage) and then run the following: - -```python - -import otari_control_plane -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.BudgetsApi(api_client) - create_budget_request = otari_control_plane.CreateBudgetRequest() # CreateBudgetRequest | - - try: - # Create Budget - api_response = api_instance.create_budget_v1_budgets_post(create_budget_request) - print("The response of BudgetsApi->create_budget_v1_budgets_post:\n") - pprint(api_response) - except ApiException as e: - print("Exception when calling BudgetsApi->create_budget_v1_budgets_post: %s\n" % e) - -``` - -## Documentation for API Endpoints - -All URIs are relative to *http://localhost* - -Class | Method | HTTP request | Description ------------- | ------------- | ------------- | ------------- -*BudgetsApi* | [**create_budget_v1_budgets_post**](docs/BudgetsApi.md#create_budget_v1_budgets_post) | **POST** /v1/budgets | Create Budget -*BudgetsApi* | [**delete_budget_v1_budgets_budget_id_delete**](docs/BudgetsApi.md#delete_budget_v1_budgets_budget_id_delete) | **DELETE** /v1/budgets/{budget_id} | Delete Budget -*BudgetsApi* | [**get_budget_v1_budgets_budget_id_get**](docs/BudgetsApi.md#get_budget_v1_budgets_budget_id_get) | **GET** /v1/budgets/{budget_id} | Get Budget -*BudgetsApi* | [**list_budgets_v1_budgets_get**](docs/BudgetsApi.md#list_budgets_v1_budgets_get) | **GET** /v1/budgets | List Budgets -*BudgetsApi* | [**update_budget_v1_budgets_budget_id_patch**](docs/BudgetsApi.md#update_budget_v1_budgets_budget_id_patch) | **PATCH** /v1/budgets/{budget_id} | Update Budget -*KeysApi* | [**create_key_v1_keys_post**](docs/KeysApi.md#create_key_v1_keys_post) | **POST** /v1/keys | Create Key -*KeysApi* | [**delete_key_v1_keys_key_id_delete**](docs/KeysApi.md#delete_key_v1_keys_key_id_delete) | **DELETE** /v1/keys/{key_id} | Delete Key -*KeysApi* | [**get_key_v1_keys_key_id_get**](docs/KeysApi.md#get_key_v1_keys_key_id_get) | **GET** /v1/keys/{key_id} | Get Key -*KeysApi* | [**list_keys_v1_keys_get**](docs/KeysApi.md#list_keys_v1_keys_get) | **GET** /v1/keys | List Keys -*KeysApi* | [**update_key_v1_keys_key_id_patch**](docs/KeysApi.md#update_key_v1_keys_key_id_patch) | **PATCH** /v1/keys/{key_id} | Update Key -*PricingApi* | [**delete_pricing_v1_pricing_model_key_delete**](docs/PricingApi.md#delete_pricing_v1_pricing_model_key_delete) | **DELETE** /v1/pricing/{model_key} | Delete Pricing -*PricingApi* | [**get_pricing_history_v1_pricing_model_key_history_get**](docs/PricingApi.md#get_pricing_history_v1_pricing_model_key_history_get) | **GET** /v1/pricing/{model_key}/history | Get Pricing History -*PricingApi* | [**get_pricing_v1_pricing_model_key_get**](docs/PricingApi.md#get_pricing_v1_pricing_model_key_get) | **GET** /v1/pricing/{model_key} | Get Pricing -*PricingApi* | [**list_pricing_v1_pricing_get**](docs/PricingApi.md#list_pricing_v1_pricing_get) | **GET** /v1/pricing | List Pricing -*PricingApi* | [**set_pricing_v1_pricing_post**](docs/PricingApi.md#set_pricing_v1_pricing_post) | **POST** /v1/pricing | Set Pricing -*UsageApi* | [**list_usage_v1_usage_get**](docs/UsageApi.md#list_usage_v1_usage_get) | **GET** /v1/usage | List Usage -*UsersApi* | [**create_user_v1_users_post**](docs/UsersApi.md#create_user_v1_users_post) | **POST** /v1/users | Create User -*UsersApi* | [**delete_user_v1_users_user_id_delete**](docs/UsersApi.md#delete_user_v1_users_user_id_delete) | **DELETE** /v1/users/{user_id} | Delete User -*UsersApi* | [**get_user_usage_v1_users_user_id_usage_get**](docs/UsersApi.md#get_user_usage_v1_users_user_id_usage_get) | **GET** /v1/users/{user_id}/usage | Get User Usage -*UsersApi* | [**get_user_v1_users_user_id_get**](docs/UsersApi.md#get_user_v1_users_user_id_get) | **GET** /v1/users/{user_id} | Get User -*UsersApi* | [**list_users_v1_users_get**](docs/UsersApi.md#list_users_v1_users_get) | **GET** /v1/users | List Users -*UsersApi* | [**update_user_v1_users_user_id_patch**](docs/UsersApi.md#update_user_v1_users_user_id_patch) | **PATCH** /v1/users/{user_id} | Update User - - -## Documentation For Models - - - [BudgetResponse](docs/BudgetResponse.md) - - [CreateBudgetRequest](docs/CreateBudgetRequest.md) - - [CreateKeyRequest](docs/CreateKeyRequest.md) - - [CreateKeyResponse](docs/CreateKeyResponse.md) - - [CreateUserRequest](docs/CreateUserRequest.md) - - [HTTPValidationError](docs/HTTPValidationError.md) - - [KeyInfo](docs/KeyInfo.md) - - [LocationInner](docs/LocationInner.md) - - [PricingResponse](docs/PricingResponse.md) - - [SetPricingRequest](docs/SetPricingRequest.md) - - [UpdateBudgetRequest](docs/UpdateBudgetRequest.md) - - [UpdateKeyRequest](docs/UpdateKeyRequest.md) - - [UpdateUserRequest](docs/UpdateUserRequest.md) - - [UsageEntry](docs/UsageEntry.md) - - [UsageLogResponse](docs/UsageLogResponse.md) - - [UserResponse](docs/UserResponse.md) - - [ValidationError](docs/ValidationError.md) - - - -## Documentation For Authorization - -Endpoints do not require authorization. - - -## Author - - - - diff --git a/src/otari/_generated/docs/BudgetResponse.md b/src/otari/_generated/docs/BudgetResponse.md deleted file mode 100644 index 74ab026..0000000 --- a/src/otari/_generated/docs/BudgetResponse.md +++ /dev/null @@ -1,34 +0,0 @@ -# BudgetResponse - -Response model for budget information. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**budget_duration_sec** | **int** | | -**budget_id** | **str** | | -**created_at** | **str** | | -**max_budget** | **float** | | -**updated_at** | **str** | | - -## Example - -```python -from otari_control_plane.models.budget_response import BudgetResponse - -# TODO update the JSON string below -json = "{}" -# create an instance of BudgetResponse from a JSON string -budget_response_instance = BudgetResponse.from_json(json) -# print the JSON string representation of the object -print(BudgetResponse.to_json()) - -# convert the object into a dict -budget_response_dict = budget_response_instance.to_dict() -# create an instance of BudgetResponse from a dict -budget_response_from_dict = BudgetResponse.from_dict(budget_response_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/BudgetsApi.md b/src/otari/_generated/docs/BudgetsApi.md deleted file mode 100644 index e0aee0c..0000000 --- a/src/otari/_generated/docs/BudgetsApi.md +++ /dev/null @@ -1,361 +0,0 @@ -# otari_control_plane.BudgetsApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**create_budget_v1_budgets_post**](BudgetsApi.md#create_budget_v1_budgets_post) | **POST** /v1/budgets | Create Budget -[**delete_budget_v1_budgets_budget_id_delete**](BudgetsApi.md#delete_budget_v1_budgets_budget_id_delete) | **DELETE** /v1/budgets/{budget_id} | Delete Budget -[**get_budget_v1_budgets_budget_id_get**](BudgetsApi.md#get_budget_v1_budgets_budget_id_get) | **GET** /v1/budgets/{budget_id} | Get Budget -[**list_budgets_v1_budgets_get**](BudgetsApi.md#list_budgets_v1_budgets_get) | **GET** /v1/budgets | List Budgets -[**update_budget_v1_budgets_budget_id_patch**](BudgetsApi.md#update_budget_v1_budgets_budget_id_patch) | **PATCH** /v1/budgets/{budget_id} | Update Budget - - -# **create_budget_v1_budgets_post** -> BudgetResponse create_budget_v1_budgets_post(create_budget_request) - -Create Budget - -Create a new budget. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.budget_response import BudgetResponse -from otari_control_plane.models.create_budget_request import CreateBudgetRequest -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.BudgetsApi(api_client) - create_budget_request = otari_control_plane.CreateBudgetRequest() # CreateBudgetRequest | - - try: - # Create Budget - api_response = api_instance.create_budget_v1_budgets_post(create_budget_request) - print("The response of BudgetsApi->create_budget_v1_budgets_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling BudgetsApi->create_budget_v1_budgets_post: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **create_budget_request** | [**CreateBudgetRequest**](CreateBudgetRequest.md)| | - -### Return type - -[**BudgetResponse**](BudgetResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_budget_v1_budgets_budget_id_delete** -> delete_budget_v1_budgets_budget_id_delete(budget_id) - -Delete Budget - -Delete a budget. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.BudgetsApi(api_client) - budget_id = 'budget_id_example' # str | - - try: - # Delete Budget - api_instance.delete_budget_v1_budgets_budget_id_delete(budget_id) - except Exception as e: - print("Exception when calling BudgetsApi->delete_budget_v1_budgets_budget_id_delete: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **budget_id** | **str**| | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**204** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_budget_v1_budgets_budget_id_get** -> BudgetResponse get_budget_v1_budgets_budget_id_get(budget_id) - -Get Budget - -Get details of a specific budget. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.budget_response import BudgetResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.BudgetsApi(api_client) - budget_id = 'budget_id_example' # str | - - try: - # Get Budget - api_response = api_instance.get_budget_v1_budgets_budget_id_get(budget_id) - print("The response of BudgetsApi->get_budget_v1_budgets_budget_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling BudgetsApi->get_budget_v1_budgets_budget_id_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **budget_id** | **str**| | - -### Return type - -[**BudgetResponse**](BudgetResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **list_budgets_v1_budgets_get** -> List[BudgetResponse] list_budgets_v1_budgets_get(skip=skip, limit=limit) - -List Budgets - -List all budgets with pagination. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.budget_response import BudgetResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.BudgetsApi(api_client) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # List Budgets - api_response = api_instance.list_budgets_v1_budgets_get(skip=skip, limit=limit) - print("The response of BudgetsApi->list_budgets_v1_budgets_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling BudgetsApi->list_budgets_v1_budgets_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[BudgetResponse]**](BudgetResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_budget_v1_budgets_budget_id_patch** -> BudgetResponse update_budget_v1_budgets_budget_id_patch(budget_id, update_budget_request) - -Update Budget - -Update a budget. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.budget_response import BudgetResponse -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.BudgetsApi(api_client) - budget_id = 'budget_id_example' # str | - update_budget_request = otari_control_plane.UpdateBudgetRequest() # UpdateBudgetRequest | - - try: - # Update Budget - api_response = api_instance.update_budget_v1_budgets_budget_id_patch(budget_id, update_budget_request) - print("The response of BudgetsApi->update_budget_v1_budgets_budget_id_patch:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling BudgetsApi->update_budget_v1_budgets_budget_id_patch: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **budget_id** | **str**| | - **update_budget_request** | [**UpdateBudgetRequest**](UpdateBudgetRequest.md)| | - -### Return type - -[**BudgetResponse**](BudgetResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/src/otari/_generated/docs/CreateBudgetRequest.md b/src/otari/_generated/docs/CreateBudgetRequest.md deleted file mode 100644 index c07cf07..0000000 --- a/src/otari/_generated/docs/CreateBudgetRequest.md +++ /dev/null @@ -1,31 +0,0 @@ -# CreateBudgetRequest - -Request model for creating a new budget. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**budget_duration_sec** | **int** | Budget duration in seconds (e.g., 86400 for daily, 604800 for weekly) | [optional] -**max_budget** | **float** | Maximum spending limit | [optional] - -## Example - -```python -from otari_control_plane.models.create_budget_request import CreateBudgetRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of CreateBudgetRequest from a JSON string -create_budget_request_instance = CreateBudgetRequest.from_json(json) -# print the JSON string representation of the object -print(CreateBudgetRequest.to_json()) - -# convert the object into a dict -create_budget_request_dict = create_budget_request_instance.to_dict() -# create an instance of CreateBudgetRequest from a dict -create_budget_request_from_dict = CreateBudgetRequest.from_dict(create_budget_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/CreateKeyRequest.md b/src/otari/_generated/docs/CreateKeyRequest.md deleted file mode 100644 index 0100894..0000000 --- a/src/otari/_generated/docs/CreateKeyRequest.md +++ /dev/null @@ -1,33 +0,0 @@ -# CreateKeyRequest - -Request model for creating a new API key. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**expires_at** | **datetime** | Optional expiration timestamp | [optional] -**key_name** | **str** | Optional name for the key | [optional] -**metadata** | **Dict[str, object]** | Optional metadata | [optional] -**user_id** | **str** | Optional user ID to associate with this key | [optional] - -## Example - -```python -from otari_control_plane.models.create_key_request import CreateKeyRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of CreateKeyRequest from a JSON string -create_key_request_instance = CreateKeyRequest.from_json(json) -# print the JSON string representation of the object -print(CreateKeyRequest.to_json()) - -# convert the object into a dict -create_key_request_dict = create_key_request_instance.to_dict() -# create an instance of CreateKeyRequest from a dict -create_key_request_from_dict = CreateKeyRequest.from_dict(create_key_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/CreateKeyResponse.md b/src/otari/_generated/docs/CreateKeyResponse.md deleted file mode 100644 index a05e916..0000000 --- a/src/otari/_generated/docs/CreateKeyResponse.md +++ /dev/null @@ -1,37 +0,0 @@ -# CreateKeyResponse - -Response model for creating a new API key. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**created_at** | **str** | | -**expires_at** | **str** | | -**id** | **str** | | -**is_active** | **bool** | | -**key** | **str** | | -**key_name** | **str** | | -**metadata** | **Dict[str, object]** | | -**user_id** | **str** | | - -## Example - -```python -from otari_control_plane.models.create_key_response import CreateKeyResponse - -# TODO update the JSON string below -json = "{}" -# create an instance of CreateKeyResponse from a JSON string -create_key_response_instance = CreateKeyResponse.from_json(json) -# print the JSON string representation of the object -print(CreateKeyResponse.to_json()) - -# convert the object into a dict -create_key_response_dict = create_key_response_instance.to_dict() -# create an instance of CreateKeyResponse from a dict -create_key_response_from_dict = CreateKeyResponse.from_dict(create_key_response_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/CreateUserRequest.md b/src/otari/_generated/docs/CreateUserRequest.md deleted file mode 100644 index b2dc2a2..0000000 --- a/src/otari/_generated/docs/CreateUserRequest.md +++ /dev/null @@ -1,34 +0,0 @@ -# CreateUserRequest - -Request model for creating a new user. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**alias** | **str** | Optional admin-facing alias | [optional] -**blocked** | **bool** | Whether user is blocked | [optional] [default to False] -**budget_id** | **str** | Optional budget ID | [optional] -**metadata** | **Dict[str, object]** | Optional metadata | [optional] -**user_id** | **str** | Unique user identifier | - -## Example - -```python -from otari_control_plane.models.create_user_request import CreateUserRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of CreateUserRequest from a JSON string -create_user_request_instance = CreateUserRequest.from_json(json) -# print the JSON string representation of the object -print(CreateUserRequest.to_json()) - -# convert the object into a dict -create_user_request_dict = create_user_request_instance.to_dict() -# create an instance of CreateUserRequest from a dict -create_user_request_from_dict = CreateUserRequest.from_dict(create_user_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/HTTPValidationError.md b/src/otari/_generated/docs/HTTPValidationError.md deleted file mode 100644 index 9f3ab89..0000000 --- a/src/otari/_generated/docs/HTTPValidationError.md +++ /dev/null @@ -1,29 +0,0 @@ -# HTTPValidationError - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**detail** | [**List[ValidationError]**](ValidationError.md) | | [optional] - -## Example - -```python -from otari_control_plane.models.http_validation_error import HTTPValidationError - -# TODO update the JSON string below -json = "{}" -# create an instance of HTTPValidationError from a JSON string -http_validation_error_instance = HTTPValidationError.from_json(json) -# print the JSON string representation of the object -print(HTTPValidationError.to_json()) - -# convert the object into a dict -http_validation_error_dict = http_validation_error_instance.to_dict() -# create an instance of HTTPValidationError from a dict -http_validation_error_from_dict = HTTPValidationError.from_dict(http_validation_error_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/KeyInfo.md b/src/otari/_generated/docs/KeyInfo.md deleted file mode 100644 index fe7b646..0000000 --- a/src/otari/_generated/docs/KeyInfo.md +++ /dev/null @@ -1,37 +0,0 @@ -# KeyInfo - -Response model for key information. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**created_at** | **str** | | -**expires_at** | **str** | | -**id** | **str** | | -**is_active** | **bool** | | -**key_name** | **str** | | -**last_used_at** | **str** | | -**metadata** | **Dict[str, object]** | | -**user_id** | **str** | | - -## Example - -```python -from otari_control_plane.models.key_info import KeyInfo - -# TODO update the JSON string below -json = "{}" -# create an instance of KeyInfo from a JSON string -key_info_instance = KeyInfo.from_json(json) -# print the JSON string representation of the object -print(KeyInfo.to_json()) - -# convert the object into a dict -key_info_dict = key_info_instance.to_dict() -# create an instance of KeyInfo from a dict -key_info_from_dict = KeyInfo.from_dict(key_info_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/KeysApi.md b/src/otari/_generated/docs/KeysApi.md deleted file mode 100644 index 78698ce..0000000 --- a/src/otari/_generated/docs/KeysApi.md +++ /dev/null @@ -1,374 +0,0 @@ -# otari_control_plane.KeysApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**create_key_v1_keys_post**](KeysApi.md#create_key_v1_keys_post) | **POST** /v1/keys | Create Key -[**delete_key_v1_keys_key_id_delete**](KeysApi.md#delete_key_v1_keys_key_id_delete) | **DELETE** /v1/keys/{key_id} | Delete Key -[**get_key_v1_keys_key_id_get**](KeysApi.md#get_key_v1_keys_key_id_get) | **GET** /v1/keys/{key_id} | Get Key -[**list_keys_v1_keys_get**](KeysApi.md#list_keys_v1_keys_get) | **GET** /v1/keys | List Keys -[**update_key_v1_keys_key_id_patch**](KeysApi.md#update_key_v1_keys_key_id_patch) | **PATCH** /v1/keys/{key_id} | Update Key - - -# **create_key_v1_keys_post** -> CreateKeyResponse create_key_v1_keys_post(create_key_request) - -Create Key - -Create a new API key. - -Requires master key authentication. - -If user_id is provided, the key will be associated with that user (creates user if it doesn't exist). -If user_id is not provided, a new user will be created automatically and the key will be associated with it. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.create_key_request import CreateKeyRequest -from otari_control_plane.models.create_key_response import CreateKeyResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.KeysApi(api_client) - create_key_request = otari_control_plane.CreateKeyRequest() # CreateKeyRequest | - - try: - # Create Key - api_response = api_instance.create_key_v1_keys_post(create_key_request) - print("The response of KeysApi->create_key_v1_keys_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling KeysApi->create_key_v1_keys_post: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **create_key_request** | [**CreateKeyRequest**](CreateKeyRequest.md)| | - -### Return type - -[**CreateKeyResponse**](CreateKeyResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_key_v1_keys_key_id_delete** -> delete_key_v1_keys_key_id_delete(key_id) - -Delete Key - -Delete (revoke) an API key. - -Requires master key authentication. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.KeysApi(api_client) - key_id = 'key_id_example' # str | - - try: - # Delete Key - api_instance.delete_key_v1_keys_key_id_delete(key_id) - except Exception as e: - print("Exception when calling KeysApi->delete_key_v1_keys_key_id_delete: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **key_id** | **str**| | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**204** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_key_v1_keys_key_id_get** -> KeyInfo get_key_v1_keys_key_id_get(key_id) - -Get Key - -Get details of a specific API key. - -Requires master key authentication. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.key_info import KeyInfo -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.KeysApi(api_client) - key_id = 'key_id_example' # str | - - try: - # Get Key - api_response = api_instance.get_key_v1_keys_key_id_get(key_id) - print("The response of KeysApi->get_key_v1_keys_key_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling KeysApi->get_key_v1_keys_key_id_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **key_id** | **str**| | - -### Return type - -[**KeyInfo**](KeyInfo.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **list_keys_v1_keys_get** -> List[KeyInfo] list_keys_v1_keys_get(skip=skip, limit=limit) - -List Keys - -List all API keys. - -Requires master key authentication. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.key_info import KeyInfo -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.KeysApi(api_client) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # List Keys - api_response = api_instance.list_keys_v1_keys_get(skip=skip, limit=limit) - print("The response of KeysApi->list_keys_v1_keys_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling KeysApi->list_keys_v1_keys_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[KeyInfo]**](KeyInfo.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_key_v1_keys_key_id_patch** -> KeyInfo update_key_v1_keys_key_id_patch(key_id, update_key_request) - -Update Key - -Update an API key. - -Requires master key authentication. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.key_info import KeyInfo -from otari_control_plane.models.update_key_request import UpdateKeyRequest -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.KeysApi(api_client) - key_id = 'key_id_example' # str | - update_key_request = otari_control_plane.UpdateKeyRequest() # UpdateKeyRequest | - - try: - # Update Key - api_response = api_instance.update_key_v1_keys_key_id_patch(key_id, update_key_request) - print("The response of KeysApi->update_key_v1_keys_key_id_patch:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling KeysApi->update_key_v1_keys_key_id_patch: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **key_id** | **str**| | - **update_key_request** | [**UpdateKeyRequest**](UpdateKeyRequest.md)| | - -### Return type - -[**KeyInfo**](KeyInfo.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/src/otari/_generated/docs/LocationInner.md b/src/otari/_generated/docs/LocationInner.md deleted file mode 100644 index a848752..0000000 --- a/src/otari/_generated/docs/LocationInner.md +++ /dev/null @@ -1,28 +0,0 @@ -# LocationInner - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - -## Example - -```python -from otari_control_plane.models.location_inner import LocationInner - -# TODO update the JSON string below -json = "{}" -# create an instance of LocationInner from a JSON string -location_inner_instance = LocationInner.from_json(json) -# print the JSON string representation of the object -print(LocationInner.to_json()) - -# convert the object into a dict -location_inner_dict = location_inner_instance.to_dict() -# create an instance of LocationInner from a dict -location_inner_from_dict = LocationInner.from_dict(location_inner_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/PricingApi.md b/src/otari/_generated/docs/PricingApi.md deleted file mode 100644 index 3deb4fc..0000000 --- a/src/otari/_generated/docs/PricingApi.md +++ /dev/null @@ -1,362 +0,0 @@ -# otari_control_plane.PricingApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**delete_pricing_v1_pricing_model_key_delete**](PricingApi.md#delete_pricing_v1_pricing_model_key_delete) | **DELETE** /v1/pricing/{model_key} | Delete Pricing -[**get_pricing_history_v1_pricing_model_key_history_get**](PricingApi.md#get_pricing_history_v1_pricing_model_key_history_get) | **GET** /v1/pricing/{model_key}/history | Get Pricing History -[**get_pricing_v1_pricing_model_key_get**](PricingApi.md#get_pricing_v1_pricing_model_key_get) | **GET** /v1/pricing/{model_key} | Get Pricing -[**list_pricing_v1_pricing_get**](PricingApi.md#list_pricing_v1_pricing_get) | **GET** /v1/pricing | List Pricing -[**set_pricing_v1_pricing_post**](PricingApi.md#set_pricing_v1_pricing_post) | **POST** /v1/pricing | Set Pricing - - -# **delete_pricing_v1_pricing_model_key_delete** -> delete_pricing_v1_pricing_model_key_delete(model_key, effective_at=effective_at) - -Delete Pricing - -Delete pricing entries for a model. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.PricingApi(api_client) - model_key = 'model_key_example' # str | - effective_at = '2013-10-20T19:20:30+01:00' # datetime | ISO datetime identifying a specific pricing row to delete (optional) - - try: - # Delete Pricing - api_instance.delete_pricing_v1_pricing_model_key_delete(model_key, effective_at=effective_at) - except Exception as e: - print("Exception when calling PricingApi->delete_pricing_v1_pricing_model_key_delete: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **model_key** | **str**| | - **effective_at** | **datetime**| ISO datetime identifying a specific pricing row to delete | [optional] - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**204** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_pricing_history_v1_pricing_model_key_history_get** -> List[PricingResponse] get_pricing_history_v1_pricing_model_key_history_get(model_key) - -Get Pricing History - -Return the full pricing history for a model. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.pricing_response import PricingResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.PricingApi(api_client) - model_key = 'model_key_example' # str | - - try: - # Get Pricing History - api_response = api_instance.get_pricing_history_v1_pricing_model_key_history_get(model_key) - print("The response of PricingApi->get_pricing_history_v1_pricing_model_key_history_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling PricingApi->get_pricing_history_v1_pricing_model_key_history_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **model_key** | **str**| | - -### Return type - -[**List[PricingResponse]**](PricingResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_pricing_v1_pricing_model_key_get** -> PricingResponse get_pricing_v1_pricing_model_key_get(model_key, as_of=as_of) - -Get Pricing - -Get pricing for a specific model as of a timestamp. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.pricing_response import PricingResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.PricingApi(api_client) - model_key = 'model_key_example' # str | - as_of = '2013-10-20T19:20:30+01:00' # datetime | ISO datetime for effective lookup (optional) - - try: - # Get Pricing - api_response = api_instance.get_pricing_v1_pricing_model_key_get(model_key, as_of=as_of) - print("The response of PricingApi->get_pricing_v1_pricing_model_key_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling PricingApi->get_pricing_v1_pricing_model_key_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **model_key** | **str**| | - **as_of** | **datetime**| ISO datetime for effective lookup | [optional] - -### Return type - -[**PricingResponse**](PricingResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **list_pricing_v1_pricing_get** -> List[PricingResponse] list_pricing_v1_pricing_get(skip=skip, limit=limit) - -List Pricing - -List all model pricing. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.pricing_response import PricingResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.PricingApi(api_client) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # List Pricing - api_response = api_instance.list_pricing_v1_pricing_get(skip=skip, limit=limit) - print("The response of PricingApi->list_pricing_v1_pricing_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling PricingApi->list_pricing_v1_pricing_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[PricingResponse]**](PricingResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **set_pricing_v1_pricing_post** -> PricingResponse set_pricing_v1_pricing_post(set_pricing_request) - -Set Pricing - -Set or update pricing for a model. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.pricing_response import PricingResponse -from otari_control_plane.models.set_pricing_request import SetPricingRequest -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.PricingApi(api_client) - set_pricing_request = otari_control_plane.SetPricingRequest() # SetPricingRequest | - - try: - # Set Pricing - api_response = api_instance.set_pricing_v1_pricing_post(set_pricing_request) - print("The response of PricingApi->set_pricing_v1_pricing_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling PricingApi->set_pricing_v1_pricing_post: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **set_pricing_request** | [**SetPricingRequest**](SetPricingRequest.md)| | - -### Return type - -[**PricingResponse**](PricingResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/src/otari/_generated/docs/PricingResponse.md b/src/otari/_generated/docs/PricingResponse.md deleted file mode 100644 index 2e7b67b..0000000 --- a/src/otari/_generated/docs/PricingResponse.md +++ /dev/null @@ -1,35 +0,0 @@ -# PricingResponse - -Response model for model pricing. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**created_at** | **str** | | -**effective_at** | **str** | | -**input_price_per_million** | **float** | | -**model_key** | **str** | | -**output_price_per_million** | **float** | | -**updated_at** | **str** | | - -## Example - -```python -from otari_control_plane.models.pricing_response import PricingResponse - -# TODO update the JSON string below -json = "{}" -# create an instance of PricingResponse from a JSON string -pricing_response_instance = PricingResponse.from_json(json) -# print the JSON string representation of the object -print(PricingResponse.to_json()) - -# convert the object into a dict -pricing_response_dict = pricing_response_instance.to_dict() -# create an instance of PricingResponse from a dict -pricing_response_from_dict = PricingResponse.from_dict(pricing_response_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/SetPricingRequest.md b/src/otari/_generated/docs/SetPricingRequest.md deleted file mode 100644 index 2a0cf9b..0000000 --- a/src/otari/_generated/docs/SetPricingRequest.md +++ /dev/null @@ -1,33 +0,0 @@ -# SetPricingRequest - -Request model for setting model pricing. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**effective_at** | **datetime** | ISO 8601 datetime from which this price applies. Defaults to now if omitted. | [optional] -**input_price_per_million** | **float** | Price per 1M input tokens | -**model_key** | **str** | Model identifier in format 'provider:model' | -**output_price_per_million** | **float** | Price per 1M output tokens | - -## Example - -```python -from otari_control_plane.models.set_pricing_request import SetPricingRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of SetPricingRequest from a JSON string -set_pricing_request_instance = SetPricingRequest.from_json(json) -# print the JSON string representation of the object -print(SetPricingRequest.to_json()) - -# convert the object into a dict -set_pricing_request_dict = set_pricing_request_instance.to_dict() -# create an instance of SetPricingRequest from a dict -set_pricing_request_from_dict = SetPricingRequest.from_dict(set_pricing_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UpdateBudgetRequest.md b/src/otari/_generated/docs/UpdateBudgetRequest.md deleted file mode 100644 index 04c5d1d..0000000 --- a/src/otari/_generated/docs/UpdateBudgetRequest.md +++ /dev/null @@ -1,31 +0,0 @@ -# UpdateBudgetRequest - -Request model for updating a budget. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**budget_duration_sec** | **int** | | [optional] -**max_budget** | **float** | | [optional] - -## Example - -```python -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of UpdateBudgetRequest from a JSON string -update_budget_request_instance = UpdateBudgetRequest.from_json(json) -# print the JSON string representation of the object -print(UpdateBudgetRequest.to_json()) - -# convert the object into a dict -update_budget_request_dict = update_budget_request_instance.to_dict() -# create an instance of UpdateBudgetRequest from a dict -update_budget_request_from_dict = UpdateBudgetRequest.from_dict(update_budget_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UpdateKeyRequest.md b/src/otari/_generated/docs/UpdateKeyRequest.md deleted file mode 100644 index 214348c..0000000 --- a/src/otari/_generated/docs/UpdateKeyRequest.md +++ /dev/null @@ -1,33 +0,0 @@ -# UpdateKeyRequest - -Request model for updating a key. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**expires_at** | **datetime** | | [optional] -**is_active** | **bool** | | [optional] -**key_name** | **str** | | [optional] -**metadata** | **Dict[str, object]** | | [optional] - -## Example - -```python -from otari_control_plane.models.update_key_request import UpdateKeyRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of UpdateKeyRequest from a JSON string -update_key_request_instance = UpdateKeyRequest.from_json(json) -# print the JSON string representation of the object -print(UpdateKeyRequest.to_json()) - -# convert the object into a dict -update_key_request_dict = update_key_request_instance.to_dict() -# create an instance of UpdateKeyRequest from a dict -update_key_request_from_dict = UpdateKeyRequest.from_dict(update_key_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UpdateUserRequest.md b/src/otari/_generated/docs/UpdateUserRequest.md deleted file mode 100644 index ce0a250..0000000 --- a/src/otari/_generated/docs/UpdateUserRequest.md +++ /dev/null @@ -1,33 +0,0 @@ -# UpdateUserRequest - -Request model for updating a user. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**alias** | **str** | | [optional] -**blocked** | **bool** | | [optional] -**budget_id** | **str** | | [optional] -**metadata** | **Dict[str, object]** | | [optional] - -## Example - -```python -from otari_control_plane.models.update_user_request import UpdateUserRequest - -# TODO update the JSON string below -json = "{}" -# create an instance of UpdateUserRequest from a JSON string -update_user_request_instance = UpdateUserRequest.from_json(json) -# print the JSON string representation of the object -print(UpdateUserRequest.to_json()) - -# convert the object into a dict -update_user_request_dict = update_user_request_instance.to_dict() -# create an instance of UpdateUserRequest from a dict -update_user_request_from_dict = UpdateUserRequest.from_dict(update_user_request_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UsageApi.md b/src/otari/_generated/docs/UsageApi.md deleted file mode 100644 index fad891d..0000000 --- a/src/otari/_generated/docs/UsageApi.md +++ /dev/null @@ -1,89 +0,0 @@ -# otari_control_plane.UsageApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**list_usage_v1_usage_get**](UsageApi.md#list_usage_v1_usage_get) | **GET** /v1/usage | List Usage - - -# **list_usage_v1_usage_get** -> List[UsageEntry] list_usage_v1_usage_get(start_date=start_date, end_date=end_date, user_id=user_id, skip=skip, limit=limit) - -List Usage - -List usage logs ordered by timestamp (most recent first). - -Supports optional filters for time range and user. Paginated via skip/limit. -Timestamps accept either ISO 8601 strings or Unix epoch seconds (numeric). - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.usage_entry import UsageEntry -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsageApi(api_client) - start_date = '2013-10-20T19:20:30+01:00' # datetime | Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) (optional) - end_date = '2013-10-20T19:20:30+01:00' # datetime | Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) (optional) - user_id = 'user_id_example' # str | Filter to a single user (optional) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # List Usage - api_response = api_instance.list_usage_v1_usage_get(start_date=start_date, end_date=end_date, user_id=user_id, skip=skip, limit=limit) - print("The response of UsageApi->list_usage_v1_usage_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UsageApi->list_usage_v1_usage_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **start_date** | **datetime**| Return logs with timestamp >= start_date (ISO 8601 or Unix epoch seconds) | [optional] - **end_date** | **datetime**| Return logs with timestamp < end_date (ISO 8601 or Unix epoch seconds) | [optional] - **user_id** | **str**| Filter to a single user | [optional] - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[UsageEntry]**](UsageEntry.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/src/otari/_generated/docs/UsageEntry.md b/src/otari/_generated/docs/UsageEntry.md deleted file mode 100644 index 1616e8f..0000000 --- a/src/otari/_generated/docs/UsageEntry.md +++ /dev/null @@ -1,42 +0,0 @@ -# UsageEntry - -A single usage log entry. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**api_key_id** | **str** | | -**completion_tokens** | **int** | | -**cost** | **float** | | -**endpoint** | **str** | | -**error_message** | **str** | | -**id** | **str** | | -**model** | **str** | | -**prompt_tokens** | **int** | | -**provider** | **str** | | -**status** | **str** | | -**timestamp** | **str** | | -**total_tokens** | **int** | | -**user_id** | **str** | | - -## Example - -```python -from otari_control_plane.models.usage_entry import UsageEntry - -# TODO update the JSON string below -json = "{}" -# create an instance of UsageEntry from a JSON string -usage_entry_instance = UsageEntry.from_json(json) -# print the JSON string representation of the object -print(UsageEntry.to_json()) - -# convert the object into a dict -usage_entry_dict = usage_entry_instance.to_dict() -# create an instance of UsageEntry from a dict -usage_entry_from_dict = UsageEntry.from_dict(usage_entry_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UsageLogResponse.md b/src/otari/_generated/docs/UsageLogResponse.md deleted file mode 100644 index 2096726..0000000 --- a/src/otari/_generated/docs/UsageLogResponse.md +++ /dev/null @@ -1,42 +0,0 @@ -# UsageLogResponse - -Response model for usage log. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**api_key_id** | **str** | | -**completion_tokens** | **int** | | -**cost** | **float** | | -**endpoint** | **str** | | -**error_message** | **str** | | -**id** | **str** | | -**model** | **str** | | -**prompt_tokens** | **int** | | -**provider** | **str** | | -**status** | **str** | | -**timestamp** | **str** | | -**total_tokens** | **int** | | -**user_id** | **str** | | - -## Example - -```python -from otari_control_plane.models.usage_log_response import UsageLogResponse - -# TODO update the JSON string below -json = "{}" -# create an instance of UsageLogResponse from a JSON string -usage_log_response_instance = UsageLogResponse.from_json(json) -# print the JSON string representation of the object -print(UsageLogResponse.to_json()) - -# convert the object into a dict -usage_log_response_dict = usage_log_response_instance.to_dict() -# create an instance of UsageLogResponse from a dict -usage_log_response_from_dict = UsageLogResponse.from_dict(usage_log_response_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UserResponse.md b/src/otari/_generated/docs/UserResponse.md deleted file mode 100644 index a777d32..0000000 --- a/src/otari/_generated/docs/UserResponse.md +++ /dev/null @@ -1,40 +0,0 @@ -# UserResponse - -Response model for user information. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**alias** | **str** | | -**blocked** | **bool** | | -**budget_id** | **str** | | -**budget_started_at** | **str** | | -**created_at** | **str** | | -**metadata** | **Dict[str, object]** | | -**next_budget_reset_at** | **str** | | -**reserved** | **float** | | -**spend** | **float** | | -**updated_at** | **str** | | -**user_id** | **str** | | - -## Example - -```python -from otari_control_plane.models.user_response import UserResponse - -# TODO update the JSON string below -json = "{}" -# create an instance of UserResponse from a JSON string -user_response_instance = UserResponse.from_json(json) -# print the JSON string representation of the object -print(UserResponse.to_json()) - -# convert the object into a dict -user_response_dict = user_response_instance.to_dict() -# create an instance of UserResponse from a dict -user_response_from_dict = UserResponse.from_dict(user_response_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/docs/UsersApi.md b/src/otari/_generated/docs/UsersApi.md deleted file mode 100644 index 9a45b07..0000000 --- a/src/otari/_generated/docs/UsersApi.md +++ /dev/null @@ -1,435 +0,0 @@ -# otari_control_plane.UsersApi - -All URIs are relative to *http://localhost* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**create_user_v1_users_post**](UsersApi.md#create_user_v1_users_post) | **POST** /v1/users | Create User -[**delete_user_v1_users_user_id_delete**](UsersApi.md#delete_user_v1_users_user_id_delete) | **DELETE** /v1/users/{user_id} | Delete User -[**get_user_usage_v1_users_user_id_usage_get**](UsersApi.md#get_user_usage_v1_users_user_id_usage_get) | **GET** /v1/users/{user_id}/usage | Get User Usage -[**get_user_v1_users_user_id_get**](UsersApi.md#get_user_v1_users_user_id_get) | **GET** /v1/users/{user_id} | Get User -[**list_users_v1_users_get**](UsersApi.md#list_users_v1_users_get) | **GET** /v1/users | List Users -[**update_user_v1_users_user_id_patch**](UsersApi.md#update_user_v1_users_user_id_patch) | **PATCH** /v1/users/{user_id} | Update User - - -# **create_user_v1_users_post** -> UserResponse create_user_v1_users_post(create_user_request) - -Create User - -Create a new user. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.create_user_request import CreateUserRequest -from otari_control_plane.models.user_response import UserResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsersApi(api_client) - create_user_request = otari_control_plane.CreateUserRequest() # CreateUserRequest | - - try: - # Create User - api_response = api_instance.create_user_v1_users_post(create_user_request) - print("The response of UsersApi->create_user_v1_users_post:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UsersApi->create_user_v1_users_post: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **create_user_request** | [**CreateUserRequest**](CreateUserRequest.md)| | - -### Return type - -[**UserResponse**](UserResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **delete_user_v1_users_user_id_delete** -> delete_user_v1_users_user_id_delete(user_id) - -Delete User - -Delete a user. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsersApi(api_client) - user_id = 'user_id_example' # str | - - try: - # Delete User - api_instance.delete_user_v1_users_user_id_delete(user_id) - except Exception as e: - print("Exception when calling UsersApi->delete_user_v1_users_user_id_delete: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **user_id** | **str**| | - -### Return type - -void (empty response body) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**204** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_user_usage_v1_users_user_id_usage_get** -> List[UsageLogResponse] get_user_usage_v1_users_user_id_usage_get(user_id, skip=skip, limit=limit) - -Get User Usage - -Get usage history for a specific user. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.usage_log_response import UsageLogResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsersApi(api_client) - user_id = 'user_id_example' # str | - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # Get User Usage - api_response = api_instance.get_user_usage_v1_users_user_id_usage_get(user_id, skip=skip, limit=limit) - print("The response of UsersApi->get_user_usage_v1_users_user_id_usage_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UsersApi->get_user_usage_v1_users_user_id_usage_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **user_id** | **str**| | - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[UsageLogResponse]**](UsageLogResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **get_user_v1_users_user_id_get** -> UserResponse get_user_v1_users_user_id_get(user_id) - -Get User - -Get details of a specific user. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.user_response import UserResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsersApi(api_client) - user_id = 'user_id_example' # str | - - try: - # Get User - api_response = api_instance.get_user_v1_users_user_id_get(user_id) - print("The response of UsersApi->get_user_v1_users_user_id_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UsersApi->get_user_v1_users_user_id_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **user_id** | **str**| | - -### Return type - -[**UserResponse**](UserResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **list_users_v1_users_get** -> List[UserResponse] list_users_v1_users_get(skip=skip, limit=limit) - -List Users - -List all users with pagination. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.user_response import UserResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsersApi(api_client) - skip = 0 # int | (optional) (default to 0) - limit = 100 # int | (optional) (default to 100) - - try: - # List Users - api_response = api_instance.list_users_v1_users_get(skip=skip, limit=limit) - print("The response of UsersApi->list_users_v1_users_get:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UsersApi->list_users_v1_users_get: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **skip** | **int**| | [optional] [default to 0] - **limit** | **int**| | [optional] [default to 100] - -### Return type - -[**List[UserResponse]**](UserResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **update_user_v1_users_user_id_patch** -> UserResponse update_user_v1_users_user_id_patch(user_id, update_user_request) - -Update User - -Update a user. - -### Example - - -```python -import otari_control_plane -from otari_control_plane.models.update_user_request import UpdateUserRequest -from otari_control_plane.models.user_response import UserResponse -from otari_control_plane.rest import ApiException -from pprint import pprint - -# Defining the host is optional and defaults to http://localhost -# See configuration.py for a list of all supported configuration parameters. -configuration = otari_control_plane.Configuration( - host = "http://localhost" -) - - -# Enter a context with an instance of the API client -with otari_control_plane.ApiClient(configuration) as api_client: - # Create an instance of the API class - api_instance = otari_control_plane.UsersApi(api_client) - user_id = 'user_id_example' # str | - update_user_request = otari_control_plane.UpdateUserRequest() # UpdateUserRequest | - - try: - # Update User - api_response = api_instance.update_user_v1_users_user_id_patch(user_id, update_user_request) - print("The response of UsersApi->update_user_v1_users_user_id_patch:\n") - pprint(api_response) - except Exception as e: - print("Exception when calling UsersApi->update_user_v1_users_user_id_patch: %s\n" % e) -``` - - - -### Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **user_id** | **str**| | - **update_user_request** | [**UpdateUserRequest**](UpdateUserRequest.md)| | - -### Return type - -[**UserResponse**](UserResponse.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -### HTTP response details - -| Status code | Description | Response headers | -|-------------|-------------|------------------| -**200** | Successful Response | - | -**422** | Validation Error | - | - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - diff --git a/src/otari/_generated/docs/ValidationError.md b/src/otari/_generated/docs/ValidationError.md deleted file mode 100644 index af05c07..0000000 --- a/src/otari/_generated/docs/ValidationError.md +++ /dev/null @@ -1,33 +0,0 @@ -# ValidationError - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**ctx** | **object** | | [optional] -**input** | **object** | | [optional] -**loc** | [**List[LocationInner]**](LocationInner.md) | | -**msg** | **str** | | -**type** | **str** | | - -## Example - -```python -from otari_control_plane.models.validation_error import ValidationError - -# TODO update the JSON string below -json = "{}" -# create an instance of ValidationError from a JSON string -validation_error_instance = ValidationError.from_json(json) -# print the JSON string representation of the object -print(ValidationError.to_json()) - -# convert the object into a dict -validation_error_dict = validation_error_instance.to_dict() -# create an instance of ValidationError from a dict -validation_error_from_dict = ValidationError.from_dict(validation_error_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/src/otari/_generated/git_push.sh b/src/otari/_generated/git_push.sh deleted file mode 100644 index f53a75d..0000000 --- a/src/otari/_generated/git_push.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh -# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ -# -# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" - -git_user_id=$1 -git_repo_id=$2 -release_note=$3 -git_host=$4 - -if [ "$git_host" = "" ]; then - git_host="github.com" - echo "[INFO] No command line input provided. Set \$git_host to $git_host" -fi - -if [ "$git_user_id" = "" ]; then - git_user_id="GIT_USER_ID" - echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" -fi - -if [ "$git_repo_id" = "" ]; then - git_repo_id="GIT_REPO_ID" - echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" -fi - -if [ "$release_note" = "" ]; then - release_note="Minor update" - echo "[INFO] No command line input provided. Set \$release_note to $release_note" -fi - -# Initialize the local directory as a Git repository -git init - -# Adds the files in the local repository and stages them for commit. -git add . - -# Commits the tracked changes and prepares them to be pushed to a remote repository. -git commit -m "$release_note" - -# Sets the new remote -git_remote=$(git remote) -if [ "$git_remote" = "" ]; then # git remote not defined - - if [ "$GIT_TOKEN" = "" ]; then - echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." - git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git - else - git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git - fi - -fi - -git pull origin master - -# Pushes (Forces) the changes in the local repository up to the remote repository -echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" -git push origin master 2>&1 | grep -v 'To https' diff --git a/src/otari/_generated/otari_control_plane/__init__.py b/src/otari/_generated/otari_control_plane/__init__.py deleted file mode 100644 index b70f9cc..0000000 --- a/src/otari/_generated/otari_control_plane/__init__.py +++ /dev/null @@ -1,90 +0,0 @@ -# coding: utf-8 - -# flake8: noqa - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -__version__ = "1.0.0" - -# Define package exports -__all__ = [ - "BudgetsApi", - "KeysApi", - "PricingApi", - "UsageApi", - "UsersApi", - "ApiResponse", - "ApiClient", - "Configuration", - "OpenApiException", - "ApiTypeError", - "ApiValueError", - "ApiKeyError", - "ApiAttributeError", - "ApiException", - "BudgetResponse", - "CreateBudgetRequest", - "CreateKeyRequest", - "CreateKeyResponse", - "CreateUserRequest", - "HTTPValidationError", - "KeyInfo", - "LocationInner", - "PricingResponse", - "SetPricingRequest", - "UpdateBudgetRequest", - "UpdateKeyRequest", - "UpdateUserRequest", - "UsageEntry", - "UsageLogResponse", - "UserResponse", - "ValidationError", -] - -# import apis into sdk package -from otari_control_plane.api.budgets_api import BudgetsApi as BudgetsApi -from otari_control_plane.api.keys_api import KeysApi as KeysApi -from otari_control_plane.api.pricing_api import PricingApi as PricingApi -from otari_control_plane.api.usage_api import UsageApi as UsageApi -from otari_control_plane.api.users_api import UsersApi as UsersApi - -# import ApiClient -from otari_control_plane.api_response import ApiResponse as ApiResponse -from otari_control_plane.api_client import ApiClient as ApiClient -from otari_control_plane.configuration import Configuration as Configuration -from otari_control_plane.exceptions import OpenApiException as OpenApiException -from otari_control_plane.exceptions import ApiTypeError as ApiTypeError -from otari_control_plane.exceptions import ApiValueError as ApiValueError -from otari_control_plane.exceptions import ApiKeyError as ApiKeyError -from otari_control_plane.exceptions import ApiAttributeError as ApiAttributeError -from otari_control_plane.exceptions import ApiException as ApiException - -# import models into sdk package -from otari_control_plane.models.budget_response import BudgetResponse as BudgetResponse -from otari_control_plane.models.create_budget_request import CreateBudgetRequest as CreateBudgetRequest -from otari_control_plane.models.create_key_request import CreateKeyRequest as CreateKeyRequest -from otari_control_plane.models.create_key_response import CreateKeyResponse as CreateKeyResponse -from otari_control_plane.models.create_user_request import CreateUserRequest as CreateUserRequest -from otari_control_plane.models.http_validation_error import HTTPValidationError as HTTPValidationError -from otari_control_plane.models.key_info import KeyInfo as KeyInfo -from otari_control_plane.models.location_inner import LocationInner as LocationInner -from otari_control_plane.models.pricing_response import PricingResponse as PricingResponse -from otari_control_plane.models.set_pricing_request import SetPricingRequest as SetPricingRequest -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest as UpdateBudgetRequest -from otari_control_plane.models.update_key_request import UpdateKeyRequest as UpdateKeyRequest -from otari_control_plane.models.update_user_request import UpdateUserRequest as UpdateUserRequest -from otari_control_plane.models.usage_entry import UsageEntry as UsageEntry -from otari_control_plane.models.usage_log_response import UsageLogResponse as UsageLogResponse -from otari_control_plane.models.user_response import UserResponse as UserResponse -from otari_control_plane.models.validation_error import ValidationError as ValidationError - diff --git a/src/otari/_generated/otari_control_plane/api/__init__.py b/src/otari/_generated/otari_control_plane/api/__init__.py deleted file mode 100644 index 897ef54..0000000 --- a/src/otari/_generated/otari_control_plane/api/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# flake8: noqa - -# import apis into api package -from otari_control_plane.api.budgets_api import BudgetsApi -from otari_control_plane.api.keys_api import KeysApi -from otari_control_plane.api.pricing_api import PricingApi -from otari_control_plane.api.usage_api import UsageApi -from otari_control_plane.api.users_api import UsersApi - diff --git a/src/otari/_generated/otari_control_plane/models/__init__.py b/src/otari/_generated/otari_control_plane/models/__init__.py deleted file mode 100644 index 8630750..0000000 --- a/src/otari/_generated/otari_control_plane/models/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# coding: utf-8 - -# flake8: noqa -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - -# import models into model package -from otari_control_plane.models.budget_response import BudgetResponse -from otari_control_plane.models.create_budget_request import CreateBudgetRequest -from otari_control_plane.models.create_key_request import CreateKeyRequest -from otari_control_plane.models.create_key_response import CreateKeyResponse -from otari_control_plane.models.create_user_request import CreateUserRequest -from otari_control_plane.models.http_validation_error import HTTPValidationError -from otari_control_plane.models.key_info import KeyInfo -from otari_control_plane.models.location_inner import LocationInner -from otari_control_plane.models.pricing_response import PricingResponse -from otari_control_plane.models.set_pricing_request import SetPricingRequest -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest -from otari_control_plane.models.update_key_request import UpdateKeyRequest -from otari_control_plane.models.update_user_request import UpdateUserRequest -from otari_control_plane.models.usage_entry import UsageEntry -from otari_control_plane.models.usage_log_response import UsageLogResponse -from otari_control_plane.models.user_response import UserResponse -from otari_control_plane.models.validation_error import ValidationError - diff --git a/src/otari/_generated/pyproject.toml b/src/otari/_generated/pyproject.toml deleted file mode 100644 index 8191679..0000000 --- a/src/otari/_generated/pyproject.toml +++ /dev/null @@ -1,94 +0,0 @@ -[project] -name = "otari_control_plane" -version = "1.0.0" -description = "otari-gateway" -authors = [ - {name = "OpenAPI Generator Community",email = "team@openapitools.org"}, -] -readme = "README.md" -keywords = ["OpenAPI", "OpenAPI-Generator", "otari-gateway"] -requires-python = ">=3.9" - -dependencies = [ - "urllib3 (>=2.1.0,<3.0.0)", - "python-dateutil (>=2.8.2)", - "pydantic (>=2.11)", - "typing-extensions (>=4.7.1)", -] - -[project.urls] -Repository = "https://github.com/GIT_USER_ID/GIT_REPO_ID" - -[tool.poetry] -requires-poetry = ">=2.0" - -[tool.poetry.group.dev.dependencies] -pytest = ">= 7.2.1" -pytest-cov = ">= 2.8.1" -tox = ">= 3.9.0" -flake8 = ">= 4.0.0" -types-python-dateutil = ">= 2.8.19.14" -mypy = ">= 1.5" - - -[build-system] -requires = ["setuptools"] -build-backend = "setuptools.build_meta" - -[tool.pylint.'MESSAGES CONTROL'] -extension-pkg-whitelist = "pydantic" - -[tool.mypy] -files = [ - "otari_control_plane", - #"test", # auto-generated tests - "tests", # hand-written tests -] -# TODO: enable "strict" once all these individual checks are passing -# strict = true - -# List from: https://mypy.readthedocs.io/en/stable/existing_code.html#introduce-stricter-options -warn_unused_configs = true -warn_redundant_casts = true -warn_unused_ignores = true - -## Getting these passing should be easy -strict_equality = true -extra_checks = true - -## Strongly recommend enabling this one as soon as you can -check_untyped_defs = true - -## These shouldn't be too much additional work, but may be tricky to -## get passing if you use a lot of untyped libraries -disallow_subclassing_any = true -disallow_untyped_decorators = true -disallow_any_generics = true - -### These next few are various gradations of forcing use of type annotations -#disallow_untyped_calls = true -#disallow_incomplete_defs = true -#disallow_untyped_defs = true -# -### This one isn't too hard to get passing, but return on investment is lower -#no_implicit_reexport = true -# -### This one can be tricky to get passing if you use a lot of untyped libraries -#warn_return_any = true - -[[tool.mypy.overrides]] -module = [ - "otari_control_plane.configuration", -] -warn_unused_ignores = true -strict_equality = true -extra_checks = true -check_untyped_defs = true -disallow_subclassing_any = true -disallow_untyped_decorators = true -disallow_any_generics = true -disallow_untyped_calls = true -disallow_incomplete_defs = true -disallow_untyped_defs = true -no_implicit_reexport = true -warn_return_any = true diff --git a/src/otari/_generated/requirements.txt b/src/otari/_generated/requirements.txt deleted file mode 100644 index 9e2d67a..0000000 --- a/src/otari/_generated/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -urllib3 >= 2.1.0, < 3.0.0 -python_dateutil >= 2.8.2 -pydantic >= 2.11 -typing-extensions >= 4.7.1 diff --git a/src/otari/_generated/setup.cfg b/src/otari/_generated/setup.cfg deleted file mode 100644 index 11433ee..0000000 --- a/src/otari/_generated/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length=99 diff --git a/src/otari/_generated/setup.py b/src/otari/_generated/setup.py deleted file mode 100644 index 4e7e3a7..0000000 --- a/src/otari/_generated/setup.py +++ /dev/null @@ -1,47 +0,0 @@ -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from setuptools import setup, find_packages # noqa: H301 - -# To install the library, run the following -# -# python setup.py install -# -# prerequisite: setuptools -# http://pypi.python.org/pypi/setuptools -NAME = "otari-control-plane" -VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" -REQUIRES = [ - "urllib3 >= 2.1.0, < 3.0.0", - "python-dateutil >= 2.8.2", - "pydantic >= 2.11", - "typing-extensions >= 4.7.1", -] - -setup( - name=NAME, - version=VERSION, - description="otari-gateway", - author="OpenAPI Generator community", - author_email="team@openapitools.org", - url="", - keywords=["OpenAPI", "OpenAPI-Generator", "otari-gateway"], - install_requires=REQUIRES, - packages=find_packages(exclude=["test", "tests"]), - include_package_data=True, - long_description_content_type='text/markdown', - long_description="""\ - A clean FastAPI gateway for otari with API key management - """, # noqa: E501 - package_data={"otari_control_plane": ["py.typed"]}, -) diff --git a/src/otari/_generated/test-requirements.txt b/src/otari/_generated/test-requirements.txt deleted file mode 100644 index e98555c..0000000 --- a/src/otari/_generated/test-requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -pytest >= 7.2.1 -pytest-cov >= 2.8.1 -tox >= 3.9.0 -flake8 >= 4.0.0 -types-python-dateutil >= 2.8.19.14 -mypy >= 1.5 diff --git a/src/otari/_generated/test/__init__.py b/src/otari/_generated/test/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/otari/_generated/test/test_budget_response.py b/src/otari/_generated/test/test_budget_response.py deleted file mode 100644 index 974a4fb..0000000 --- a/src/otari/_generated/test/test_budget_response.py +++ /dev/null @@ -1,60 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.budget_response import BudgetResponse - -class TestBudgetResponse(unittest.TestCase): - """BudgetResponse unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> BudgetResponse: - """Test BudgetResponse - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `BudgetResponse` - """ - model = BudgetResponse() - if include_optional: - return BudgetResponse( - budget_duration_sec = 56, - budget_id = '', - created_at = '', - max_budget = 1.337, - updated_at = '' - ) - else: - return BudgetResponse( - budget_duration_sec = 56, - budget_id = '', - created_at = '', - max_budget = 1.337, - updated_at = '', - ) - """ - - def testBudgetResponse(self): - """Test BudgetResponse""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_budgets_api.py b/src/otari/_generated/test/test_budgets_api.py deleted file mode 100644 index a355032..0000000 --- a/src/otari/_generated/test/test_budgets_api.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.api.budgets_api import BudgetsApi - - -class TestBudgetsApi(unittest.TestCase): - """BudgetsApi unit test stubs""" - - def setUp(self) -> None: - self.api = BudgetsApi() - - def tearDown(self) -> None: - pass - - def test_create_budget_v1_budgets_post(self) -> None: - """Test case for create_budget_v1_budgets_post - - Create Budget - """ - pass - - def test_delete_budget_v1_budgets_budget_id_delete(self) -> None: - """Test case for delete_budget_v1_budgets_budget_id_delete - - Delete Budget - """ - pass - - def test_get_budget_v1_budgets_budget_id_get(self) -> None: - """Test case for get_budget_v1_budgets_budget_id_get - - Get Budget - """ - pass - - def test_list_budgets_v1_budgets_get(self) -> None: - """Test case for list_budgets_v1_budgets_get - - List Budgets - """ - pass - - def test_update_budget_v1_budgets_budget_id_patch(self) -> None: - """Test case for update_budget_v1_budgets_budget_id_patch - - Update Budget - """ - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_create_budget_request.py b/src/otari/_generated/test/test_create_budget_request.py deleted file mode 100644 index 1142a3a..0000000 --- a/src/otari/_generated/test/test_create_budget_request.py +++ /dev/null @@ -1,52 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.create_budget_request import CreateBudgetRequest - -class TestCreateBudgetRequest(unittest.TestCase): - """CreateBudgetRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> CreateBudgetRequest: - """Test CreateBudgetRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `CreateBudgetRequest` - """ - model = CreateBudgetRequest() - if include_optional: - return CreateBudgetRequest( - budget_duration_sec = 0.0, - max_budget = 0.0 - ) - else: - return CreateBudgetRequest( - ) - """ - - def testCreateBudgetRequest(self): - """Test CreateBudgetRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_create_key_request.py b/src/otari/_generated/test/test_create_key_request.py deleted file mode 100644 index ce21d3c..0000000 --- a/src/otari/_generated/test/test_create_key_request.py +++ /dev/null @@ -1,54 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.create_key_request import CreateKeyRequest - -class TestCreateKeyRequest(unittest.TestCase): - """CreateKeyRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> CreateKeyRequest: - """Test CreateKeyRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `CreateKeyRequest` - """ - model = CreateKeyRequest() - if include_optional: - return CreateKeyRequest( - expires_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), - key_name = '', - metadata = { }, - user_id = '' - ) - else: - return CreateKeyRequest( - ) - """ - - def testCreateKeyRequest(self): - """Test CreateKeyRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_create_key_response.py b/src/otari/_generated/test/test_create_key_response.py deleted file mode 100644 index a6afe64..0000000 --- a/src/otari/_generated/test/test_create_key_response.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.create_key_response import CreateKeyResponse - -class TestCreateKeyResponse(unittest.TestCase): - """CreateKeyResponse unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> CreateKeyResponse: - """Test CreateKeyResponse - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `CreateKeyResponse` - """ - model = CreateKeyResponse() - if include_optional: - return CreateKeyResponse( - created_at = '', - expires_at = '', - id = '', - is_active = True, - key = '', - key_name = '', - metadata = { }, - user_id = '' - ) - else: - return CreateKeyResponse( - created_at = '', - expires_at = '', - id = '', - is_active = True, - key = '', - key_name = '', - metadata = { }, - user_id = '', - ) - """ - - def testCreateKeyResponse(self): - """Test CreateKeyResponse""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_create_user_request.py b/src/otari/_generated/test/test_create_user_request.py deleted file mode 100644 index ddab12d..0000000 --- a/src/otari/_generated/test/test_create_user_request.py +++ /dev/null @@ -1,56 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.create_user_request import CreateUserRequest - -class TestCreateUserRequest(unittest.TestCase): - """CreateUserRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> CreateUserRequest: - """Test CreateUserRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `CreateUserRequest` - """ - model = CreateUserRequest() - if include_optional: - return CreateUserRequest( - alias = '', - blocked = True, - budget_id = '', - metadata = { }, - user_id = '' - ) - else: - return CreateUserRequest( - user_id = '', - ) - """ - - def testCreateUserRequest(self): - """Test CreateUserRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_http_validation_error.py b/src/otari/_generated/test/test_http_validation_error.py deleted file mode 100644 index 6f2b4f2..0000000 --- a/src/otari/_generated/test/test_http_validation_error.py +++ /dev/null @@ -1,60 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.http_validation_error import HTTPValidationError - -class TestHTTPValidationError(unittest.TestCase): - """HTTPValidationError unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> HTTPValidationError: - """Test HTTPValidationError - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `HTTPValidationError` - """ - model = HTTPValidationError() - if include_optional: - return HTTPValidationError( - detail = [ - otari_control_plane.models.validation_error.ValidationError( - ctx = otari_control_plane.models.context.Context(), - input = null, - loc = [ - null - ], - msg = '', - type = '', ) - ] - ) - else: - return HTTPValidationError( - ) - """ - - def testHTTPValidationError(self): - """Test HTTPValidationError""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_key_info.py b/src/otari/_generated/test/test_key_info.py deleted file mode 100644 index 3d873e6..0000000 --- a/src/otari/_generated/test/test_key_info.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.key_info import KeyInfo - -class TestKeyInfo(unittest.TestCase): - """KeyInfo unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> KeyInfo: - """Test KeyInfo - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `KeyInfo` - """ - model = KeyInfo() - if include_optional: - return KeyInfo( - created_at = '', - expires_at = '', - id = '', - is_active = True, - key_name = '', - last_used_at = '', - metadata = { }, - user_id = '' - ) - else: - return KeyInfo( - created_at = '', - expires_at = '', - id = '', - is_active = True, - key_name = '', - last_used_at = '', - metadata = { }, - user_id = '', - ) - """ - - def testKeyInfo(self): - """Test KeyInfo""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_keys_api.py b/src/otari/_generated/test/test_keys_api.py deleted file mode 100644 index 04f189a..0000000 --- a/src/otari/_generated/test/test_keys_api.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.api.keys_api import KeysApi - - -class TestKeysApi(unittest.TestCase): - """KeysApi unit test stubs""" - - def setUp(self) -> None: - self.api = KeysApi() - - def tearDown(self) -> None: - pass - - def test_create_key_v1_keys_post(self) -> None: - """Test case for create_key_v1_keys_post - - Create Key - """ - pass - - def test_delete_key_v1_keys_key_id_delete(self) -> None: - """Test case for delete_key_v1_keys_key_id_delete - - Delete Key - """ - pass - - def test_get_key_v1_keys_key_id_get(self) -> None: - """Test case for get_key_v1_keys_key_id_get - - Get Key - """ - pass - - def test_list_keys_v1_keys_get(self) -> None: - """Test case for list_keys_v1_keys_get - - List Keys - """ - pass - - def test_update_key_v1_keys_key_id_patch(self) -> None: - """Test case for update_key_v1_keys_key_id_patch - - Update Key - """ - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_location_inner.py b/src/otari/_generated/test/test_location_inner.py deleted file mode 100644 index 2d170d7..0000000 --- a/src/otari/_generated/test/test_location_inner.py +++ /dev/null @@ -1,50 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.location_inner import LocationInner - -class TestLocationInner(unittest.TestCase): - """LocationInner unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> LocationInner: - """Test LocationInner - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `LocationInner` - """ - model = LocationInner() - if include_optional: - return LocationInner( - ) - else: - return LocationInner( - ) - """ - - def testLocationInner(self): - """Test LocationInner""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_pricing_api.py b/src/otari/_generated/test/test_pricing_api.py deleted file mode 100644 index 1a613fe..0000000 --- a/src/otari/_generated/test/test_pricing_api.py +++ /dev/null @@ -1,66 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.api.pricing_api import PricingApi - - -class TestPricingApi(unittest.TestCase): - """PricingApi unit test stubs""" - - def setUp(self) -> None: - self.api = PricingApi() - - def tearDown(self) -> None: - pass - - def test_delete_pricing_v1_pricing_model_key_delete(self) -> None: - """Test case for delete_pricing_v1_pricing_model_key_delete - - Delete Pricing - """ - pass - - def test_get_pricing_history_v1_pricing_model_key_history_get(self) -> None: - """Test case for get_pricing_history_v1_pricing_model_key_history_get - - Get Pricing History - """ - pass - - def test_get_pricing_v1_pricing_model_key_get(self) -> None: - """Test case for get_pricing_v1_pricing_model_key_get - - Get Pricing - """ - pass - - def test_list_pricing_v1_pricing_get(self) -> None: - """Test case for list_pricing_v1_pricing_get - - List Pricing - """ - pass - - def test_set_pricing_v1_pricing_post(self) -> None: - """Test case for set_pricing_v1_pricing_post - - Set Pricing - """ - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_pricing_response.py b/src/otari/_generated/test/test_pricing_response.py deleted file mode 100644 index a1fab05..0000000 --- a/src/otari/_generated/test/test_pricing_response.py +++ /dev/null @@ -1,62 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.pricing_response import PricingResponse - -class TestPricingResponse(unittest.TestCase): - """PricingResponse unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> PricingResponse: - """Test PricingResponse - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `PricingResponse` - """ - model = PricingResponse() - if include_optional: - return PricingResponse( - created_at = '', - effective_at = '', - input_price_per_million = 1.337, - model_key = '', - output_price_per_million = 1.337, - updated_at = '' - ) - else: - return PricingResponse( - created_at = '', - effective_at = '', - input_price_per_million = 1.337, - model_key = '', - output_price_per_million = 1.337, - updated_at = '', - ) - """ - - def testPricingResponse(self): - """Test PricingResponse""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_set_pricing_request.py b/src/otari/_generated/test/test_set_pricing_request.py deleted file mode 100644 index fcf3732..0000000 --- a/src/otari/_generated/test/test_set_pricing_request.py +++ /dev/null @@ -1,57 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.set_pricing_request import SetPricingRequest - -class TestSetPricingRequest(unittest.TestCase): - """SetPricingRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> SetPricingRequest: - """Test SetPricingRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `SetPricingRequest` - """ - model = SetPricingRequest() - if include_optional: - return SetPricingRequest( - effective_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), - input_price_per_million = 0.0, - model_key = '', - output_price_per_million = 0.0 - ) - else: - return SetPricingRequest( - input_price_per_million = 0.0, - model_key = '', - output_price_per_million = 0.0, - ) - """ - - def testSetPricingRequest(self): - """Test SetPricingRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_update_budget_request.py b/src/otari/_generated/test/test_update_budget_request.py deleted file mode 100644 index 7ed6d31..0000000 --- a/src/otari/_generated/test/test_update_budget_request.py +++ /dev/null @@ -1,52 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest - -class TestUpdateBudgetRequest(unittest.TestCase): - """UpdateBudgetRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> UpdateBudgetRequest: - """Test UpdateBudgetRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `UpdateBudgetRequest` - """ - model = UpdateBudgetRequest() - if include_optional: - return UpdateBudgetRequest( - budget_duration_sec = 0.0, - max_budget = 0.0 - ) - else: - return UpdateBudgetRequest( - ) - """ - - def testUpdateBudgetRequest(self): - """Test UpdateBudgetRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_update_key_request.py b/src/otari/_generated/test/test_update_key_request.py deleted file mode 100644 index 9dda1f0..0000000 --- a/src/otari/_generated/test/test_update_key_request.py +++ /dev/null @@ -1,54 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.update_key_request import UpdateKeyRequest - -class TestUpdateKeyRequest(unittest.TestCase): - """UpdateKeyRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> UpdateKeyRequest: - """Test UpdateKeyRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `UpdateKeyRequest` - """ - model = UpdateKeyRequest() - if include_optional: - return UpdateKeyRequest( - expires_at = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), - is_active = True, - key_name = '', - metadata = { } - ) - else: - return UpdateKeyRequest( - ) - """ - - def testUpdateKeyRequest(self): - """Test UpdateKeyRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_update_user_request.py b/src/otari/_generated/test/test_update_user_request.py deleted file mode 100644 index f6b5a7a..0000000 --- a/src/otari/_generated/test/test_update_user_request.py +++ /dev/null @@ -1,54 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.update_user_request import UpdateUserRequest - -class TestUpdateUserRequest(unittest.TestCase): - """UpdateUserRequest unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> UpdateUserRequest: - """Test UpdateUserRequest - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `UpdateUserRequest` - """ - model = UpdateUserRequest() - if include_optional: - return UpdateUserRequest( - alias = '', - blocked = True, - budget_id = '', - metadata = { } - ) - else: - return UpdateUserRequest( - ) - """ - - def testUpdateUserRequest(self): - """Test UpdateUserRequest""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_usage_api.py b/src/otari/_generated/test/test_usage_api.py deleted file mode 100644 index 26c3b0e..0000000 --- a/src/otari/_generated/test/test_usage_api.py +++ /dev/null @@ -1,38 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.api.usage_api import UsageApi - - -class TestUsageApi(unittest.TestCase): - """UsageApi unit test stubs""" - - def setUp(self) -> None: - self.api = UsageApi() - - def tearDown(self) -> None: - pass - - def test_list_usage_v1_usage_get(self) -> None: - """Test case for list_usage_v1_usage_get - - List Usage - """ - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_usage_entry.py b/src/otari/_generated/test/test_usage_entry.py deleted file mode 100644 index 1201ada..0000000 --- a/src/otari/_generated/test/test_usage_entry.py +++ /dev/null @@ -1,76 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.usage_entry import UsageEntry - -class TestUsageEntry(unittest.TestCase): - """UsageEntry unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> UsageEntry: - """Test UsageEntry - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `UsageEntry` - """ - model = UsageEntry() - if include_optional: - return UsageEntry( - api_key_id = '', - completion_tokens = 56, - cost = 1.337, - endpoint = '', - error_message = '', - id = '', - model = '', - prompt_tokens = 56, - provider = '', - status = '', - timestamp = '', - total_tokens = 56, - user_id = '' - ) - else: - return UsageEntry( - api_key_id = '', - completion_tokens = 56, - cost = 1.337, - endpoint = '', - error_message = '', - id = '', - model = '', - prompt_tokens = 56, - provider = '', - status = '', - timestamp = '', - total_tokens = 56, - user_id = '', - ) - """ - - def testUsageEntry(self): - """Test UsageEntry""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_usage_log_response.py b/src/otari/_generated/test/test_usage_log_response.py deleted file mode 100644 index d836747..0000000 --- a/src/otari/_generated/test/test_usage_log_response.py +++ /dev/null @@ -1,76 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.usage_log_response import UsageLogResponse - -class TestUsageLogResponse(unittest.TestCase): - """UsageLogResponse unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> UsageLogResponse: - """Test UsageLogResponse - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `UsageLogResponse` - """ - model = UsageLogResponse() - if include_optional: - return UsageLogResponse( - api_key_id = '', - completion_tokens = 56, - cost = 1.337, - endpoint = '', - error_message = '', - id = '', - model = '', - prompt_tokens = 56, - provider = '', - status = '', - timestamp = '', - total_tokens = 56, - user_id = '' - ) - else: - return UsageLogResponse( - api_key_id = '', - completion_tokens = 56, - cost = 1.337, - endpoint = '', - error_message = '', - id = '', - model = '', - prompt_tokens = 56, - provider = '', - status = '', - timestamp = '', - total_tokens = 56, - user_id = '', - ) - """ - - def testUsageLogResponse(self): - """Test UsageLogResponse""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_user_response.py b/src/otari/_generated/test/test_user_response.py deleted file mode 100644 index ef4eb5a..0000000 --- a/src/otari/_generated/test/test_user_response.py +++ /dev/null @@ -1,72 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.user_response import UserResponse - -class TestUserResponse(unittest.TestCase): - """UserResponse unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> UserResponse: - """Test UserResponse - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `UserResponse` - """ - model = UserResponse() - if include_optional: - return UserResponse( - alias = '', - blocked = True, - budget_id = '', - budget_started_at = '', - created_at = '', - metadata = { }, - next_budget_reset_at = '', - reserved = 1.337, - spend = 1.337, - updated_at = '', - user_id = '' - ) - else: - return UserResponse( - alias = '', - blocked = True, - budget_id = '', - budget_started_at = '', - created_at = '', - metadata = { }, - next_budget_reset_at = '', - reserved = 1.337, - spend = 1.337, - updated_at = '', - user_id = '', - ) - """ - - def testUserResponse(self): - """Test UserResponse""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_users_api.py b/src/otari/_generated/test/test_users_api.py deleted file mode 100644 index 70524e3..0000000 --- a/src/otari/_generated/test/test_users_api.py +++ /dev/null @@ -1,73 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.api.users_api import UsersApi - - -class TestUsersApi(unittest.TestCase): - """UsersApi unit test stubs""" - - def setUp(self) -> None: - self.api = UsersApi() - - def tearDown(self) -> None: - pass - - def test_create_user_v1_users_post(self) -> None: - """Test case for create_user_v1_users_post - - Create User - """ - pass - - def test_delete_user_v1_users_user_id_delete(self) -> None: - """Test case for delete_user_v1_users_user_id_delete - - Delete User - """ - pass - - def test_get_user_usage_v1_users_user_id_usage_get(self) -> None: - """Test case for get_user_usage_v1_users_user_id_usage_get - - Get User Usage - """ - pass - - def test_get_user_v1_users_user_id_get(self) -> None: - """Test case for get_user_v1_users_user_id_get - - Get User - """ - pass - - def test_list_users_v1_users_get(self) -> None: - """Test case for list_users_v1_users_get - - List Users - """ - pass - - def test_update_user_v1_users_user_id_patch(self) -> None: - """Test case for update_user_v1_users_user_id_patch - - Update User - """ - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/test/test_validation_error.py b/src/otari/_generated/test/test_validation_error.py deleted file mode 100644 index 78410b8..0000000 --- a/src/otari/_generated/test/test_validation_error.py +++ /dev/null @@ -1,62 +0,0 @@ -# coding: utf-8 - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -import unittest - -from otari_control_plane.models.validation_error import ValidationError - -class TestValidationError(unittest.TestCase): - """ValidationError unit test stubs""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def make_instance(self, include_optional) -> ValidationError: - """Test ValidationError - include_optional is a boolean, when False only required - params are included, when True both required and - optional params are included """ - # uncomment below to create an instance of `ValidationError` - """ - model = ValidationError() - if include_optional: - return ValidationError( - ctx = otari_control_plane.models.context.Context(), - input = None, - loc = [ - null - ], - msg = '', - type = '' - ) - else: - return ValidationError( - loc = [ - null - ], - msg = '', - type = '', - ) - """ - - def testValidationError(self): - """Test ValidationError""" - # inst_req_only = self.make_instance(include_optional=False) - # inst_req_and_optional = self.make_instance(include_optional=True) - -if __name__ == '__main__': - unittest.main() diff --git a/src/otari/_generated/tox.ini b/src/otari/_generated/tox.ini deleted file mode 100644 index 9dd164c..0000000 --- a/src/otari/_generated/tox.ini +++ /dev/null @@ -1,9 +0,0 @@ -[tox] -envlist = py3 - -[testenv] -deps=-r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt - -commands= - pytest --cov=otari_control_plane diff --git a/src/otari/client.py b/src/otari/client.py index c8f4da5..738a846 100644 --- a/src/otari/client.py +++ b/src/otari/client.py @@ -22,12 +22,15 @@ from __future__ import annotations +from functools import cached_property from typing import TYPE_CHECKING, Any, overload import httpx from openai import OpenAI from otari._base import _BaseOtariClient, _url_encode +from otari.control_plane import ControlPlane +from otari.errors import OtariError if TYPE_CHECKING: from openai import Stream @@ -98,6 +101,7 @@ def __init__( *, api_key: str | None = None, platform_token: str | None = None, + admin_key: str | None = None, default_headers: dict[str, str] | None = None, openai_options: dict[str, Any] | None = None, ) -> None: @@ -105,6 +109,7 @@ def __init__( api_base, api_key=api_key, platform_token=platform_token, + admin_key=admin_key, default_headers=default_headers, openai_options=openai_options, ) @@ -117,6 +122,22 @@ def __init__( # httpx client for raw HTTP calls (batch, etc.) self._http = httpx.Client() + @cached_property + def control_plane(self) -> ControlPlane: + """Typed client for the management endpoints (keys, users, budgets, pricing, usage). + + Requires an admin credential: pass ``admin_key`` (the gateway master key), + set ``GATEWAY_ADMIN_KEY``, or use ``platform_token`` (which doubles as the + control-plane bearer in platform mode). + """ + if not self._admin_token: + msg = ( + "control-plane management requires an admin credential; pass " + "admin_key=... (the gateway master key) or use platform_token=..." + ) + raise OtariError(msg) + return ControlPlane(self._gateway_root_url, self._admin_token) + # -- Chat completions --------------------------------------------------- @overload diff --git a/src/otari/control_plane.py b/src/otari/control_plane.py new file mode 100644 index 0000000..f2fde6d --- /dev/null +++ b/src/otari/control_plane.py @@ -0,0 +1,59 @@ +"""Typed client for the gateway control-plane (management) endpoints. + +Wraps the generated :mod:`otari._control_plane` client. The control-plane +endpoints (API keys, users, budgets, pricing, usage) authenticate with +``Authorization: Bearer ``, which is distinct from the +``Otari-Key`` virtual key used for inference. Obtain an instance via +:attr:`otari.OtariClient.control_plane`. +""" + +from __future__ import annotations + +from functools import cached_property +from typing import Any, cast + +from otari import _control_plane as _cp +from otari._control_plane.api.budgets_api import BudgetsApi +from otari._control_plane.api.keys_api import KeysApi +from otari._control_plane.api.pricing_api import PricingApi +from otari._control_plane.api.usage_api import UsageApi +from otari._control_plane.api.users_api import UsersApi + + +class ControlPlane: + """Accessors for the gateway management endpoints, sharing one authenticated client. + + Method names on the underlying API objects are generator-derived (for + example ``keys.create_key_v1_keys_post(...)``); friendlier aliases are a + planned follow-up. + """ + + def __init__(self, base_url: str, bearer_token: str) -> None: + config = _cp.Configuration(host=base_url) + # The generated client is intentionally not type-checked here; treat it + # as ``Any`` so strict mypy does not flag its untyped methods. + self._api_client = cast("Any", _cp.ApiClient(config)) + self._api_client.set_default_header("Authorization", f"Bearer {bearer_token}") + + @cached_property + def keys(self) -> KeysApi: + return KeysApi(self._api_client) + + @cached_property + def users(self) -> UsersApi: + return UsersApi(self._api_client) + + @cached_property + def budgets(self) -> BudgetsApi: + return BudgetsApi(self._api_client) + + @cached_property + def pricing(self) -> PricingApi: + return PricingApi(self._api_client) + + @cached_property + def usage(self) -> UsageApi: + return UsageApi(self._api_client) + + def close(self) -> None: + self._api_client.__exit__(None, None, None) diff --git a/tests/integration/test_control_plane_generated.py b/tests/integration/test_control_plane_generated.py index 7df8d8c..465d9fd 100644 --- a/tests/integration/test_control_plane_generated.py +++ b/tests/integration/test_control_plane_generated.py @@ -1,20 +1,18 @@ -"""Integration tests for the generated control-plane client against a live gateway. +"""Integration tests for the control-plane surface against a live gateway. -These drive the generated control-plane client through a full CRUD lifecycle for -every management endpoint (keys, users, budgets, pricing, usage). They start a -real gateway on SQLite with a master key, so no provider credentials or database -server are needed: control-plane endpoints never call an LLM provider. +These drive ``OtariClient.control_plane`` through a full CRUD lifecycle for every +management endpoint (keys, users, budgets, pricing, usage), exercising the manual +wiring (Bearer auth + the generated client) end to end. They start a real gateway +on SQLite with a master key, so no provider credentials or database server are +needed: control-plane endpoints never call an LLM provider. Run requirements: - The ``gateway`` console script on PATH (set ``OTARI_GATEWAY_CMD`` to override), e.g. ``pip install otari-gateway`` in CI. -- The generated client importable (this preview imports it from - ``src/otari/_generated``; once it is wired into the public client, import from - there instead). Auth note, verified against the gateway: management endpoints authenticate via ``Authorization: Bearer ``, NOT the ``Otari-Key`` virtual-key header -used for inference. +used for inference. ``OtariClient`` sends the former when given ``admin_key``. """ from __future__ import annotations @@ -23,7 +21,6 @@ import os import socket import subprocess -import sys import tempfile import time import urllib.error @@ -33,31 +30,20 @@ import pytest +from otari import OtariClient +from otari._control_plane.exceptions import NotFoundException +from otari._control_plane.models.create_budget_request import CreateBudgetRequest +from otari._control_plane.models.create_key_request import CreateKeyRequest +from otari._control_plane.models.create_user_request import CreateUserRequest +from otari._control_plane.models.set_pricing_request import SetPricingRequest +from otari._control_plane.models.update_budget_request import UpdateBudgetRequest +from otari._control_plane.models.update_key_request import UpdateKeyRequest +from otari._control_plane.models.update_user_request import UpdateUserRequest + pytestmark = pytest.mark.integration MASTER_KEY = "itest-master-key" -# Preview: import the generated client from where the codegen PR drops it. -_GENERATED = Path(__file__).resolve().parents[2] / "src" / "otari" / "_generated" -if _GENERATED.is_dir(): - sys.path.insert(0, str(_GENERATED)) - -ocp = pytest.importorskip("otari_control_plane", reason="generated control-plane client not present") - -from otari_control_plane.api.budgets_api import BudgetsApi # noqa: E402 -from otari_control_plane.api.keys_api import KeysApi # noqa: E402 -from otari_control_plane.api.pricing_api import PricingApi # noqa: E402 -from otari_control_plane.api.usage_api import UsageApi # noqa: E402 -from otari_control_plane.api.users_api import UsersApi # noqa: E402 -from otari_control_plane.exceptions import NotFoundException # noqa: E402 -from otari_control_plane.models.create_budget_request import CreateBudgetRequest # noqa: E402 -from otari_control_plane.models.create_key_request import CreateKeyRequest # noqa: E402 -from otari_control_plane.models.create_user_request import CreateUserRequest # noqa: E402 -from otari_control_plane.models.set_pricing_request import SetPricingRequest # noqa: E402 -from otari_control_plane.models.update_budget_request import UpdateBudgetRequest # noqa: E402 -from otari_control_plane.models.update_key_request import UpdateKeyRequest # noqa: E402 -from otari_control_plane.models.update_user_request import UpdateUserRequest # noqa: E402 - def _free_port() -> int: with socket.socket() as sock: @@ -104,16 +90,16 @@ def gateway_url() -> Iterator[str]: @pytest.fixture -def api_client(gateway_url: str) -> Iterator[object]: - config = ocp.Configuration(host=gateway_url) - # Management endpoints use Bearer auth with the master key (not Otari-Key). - with ocp.ApiClient(config) as client: - client.set_default_header("Authorization", f"Bearer {MASTER_KEY}") - yield client +def client(gateway_url: str) -> Iterator[OtariClient]: + otari = OtariClient(api_base=gateway_url, admin_key=MASTER_KEY) + try: + yield otari + finally: + otari.control_plane.close() -def test_budgets_lifecycle(api_client: object) -> None: - api = BudgetsApi(api_client) +def test_budgets_lifecycle(client: OtariClient) -> None: + api = client.control_plane.budgets created = api.create_budget_v1_budgets_post(CreateBudgetRequest(max_budget=100.0, budget_duration_sec=3600)) assert created.budget_id assert created.max_budget == 100.0 @@ -130,8 +116,8 @@ def test_budgets_lifecycle(api_client: object) -> None: api.get_budget_v1_budgets_budget_id_get(bid) -def test_users_lifecycle(api_client: object) -> None: - api = UsersApi(api_client) +def test_users_lifecycle(client: OtariClient) -> None: + api = client.control_plane.users created = api.create_user_v1_users_post(CreateUserRequest(user_id="itest-user", alias="Alice")) assert created.user_id == "itest-user" assert created.alias == "Alice" @@ -142,7 +128,6 @@ def test_users_lifecycle(api_client: object) -> None: updated = api.update_user_v1_users_user_id_patch("itest-user", UpdateUserRequest(alias="Alice2")) assert updated.alias == "Alice2" - # usage sub-resource is readable for a known user api.get_user_usage_v1_users_user_id_usage_get("itest-user") api.delete_user_v1_users_user_id_delete("itest-user") @@ -150,8 +135,8 @@ def test_users_lifecycle(api_client: object) -> None: api.get_user_v1_users_user_id_get("itest-user") -def test_keys_lifecycle_returns_secret_on_create(api_client: object) -> None: - api = KeysApi(api_client) +def test_keys_lifecycle_returns_secret_on_create(client: OtariClient) -> None: + api = client.control_plane.keys created = api.create_key_v1_keys_post(CreateKeyRequest(key_name="itest-key")) assert created.id # The one-time key value must be present on create (manually-created surface). @@ -169,8 +154,8 @@ def test_keys_lifecycle_returns_secret_on_create(api_client: object) -> None: api.get_key_v1_keys_key_id_get(kid) -def test_pricing_lifecycle(api_client: object) -> None: - api = PricingApi(api_client) +def test_pricing_lifecycle(client: OtariClient) -> None: + api = client.control_plane.pricing model_key = "openai:itest-model" created = api.set_pricing_v1_pricing_post( SetPricingRequest(model_key=model_key, input_price_per_million=1.0, output_price_per_million=2.0) @@ -179,7 +164,6 @@ def test_pricing_lifecycle(api_client: object) -> None: assert any(p.model_key == model_key for p in api.list_pricing_v1_pricing_get()) assert api.get_pricing_v1_pricing_model_key_get(model_key).model_key == model_key - # history is populated after at least one set assert api.get_pricing_history_v1_pricing_model_key_history_get(model_key) is not None api.delete_pricing_v1_pricing_model_key_delete(model_key) @@ -187,7 +171,14 @@ def test_pricing_lifecycle(api_client: object) -> None: api.get_pricing_v1_pricing_model_key_get(model_key) -def test_usage_is_readable(api_client: object) -> None: - api = UsageApi(api_client) - # Fresh gateway: usage list is readable (and empty), proving the typed GET works. - assert api.list_usage_v1_usage_get() is not None +def test_usage_is_readable(client: OtariClient) -> None: + # Fresh gateway: usage list is readable, proving the typed GET works through the client. + assert client.control_plane.usage.list_usage_v1_usage_get() is not None + + +def test_control_plane_requires_admin_credential(gateway_url: str) -> None: + from otari import OtariError + + no_admin = OtariClient(api_base=gateway_url, api_key="some-virtual-key") + with pytest.raises(OtariError): + _ = no_admin.control_plane From 5a13bacb96406fdb0c4ebb1a242d5fddf09f006b Mon Sep 17 00:00:00 2001 From: njbrake Date: Sat, 6 Jun 2026 01:46:02 +0000 Subject: [PATCH 4/6] Add PR CI and make control-plane integration tests skip without a gateway - Add .github/workflows/ci.yml: ruff + mypy + pytest on push/PR across Python 3.11-3.13 (the repo previously only ran checks on release). - Integration tests skip cleanly when no gateway is on PATH (set OTARI_GATEWAY_CMD to run them), so CI is green without a gateway and passes with one. - Register the 'integration' marker; per-file-ignore the subprocess/URL audit rules for the test harness. Part of mozilla-ai/otari#96 Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 37 +++++++++++++++++++ pyproject.toml | 8 ++++ .../test_control_plane_generated.py | 4 +- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fca696c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11", "3.12", "3.13"] + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: uv sync --extra dev + + - name: Lint + run: uv run ruff check . + + - name: Type check + run: uv run mypy src/ + + - name: Test + # Integration tests skip automatically when no gateway is on PATH. + run: uv run pytest diff --git a/pyproject.toml b/pyproject.toml index 1a4da5e..aaa0736 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,9 @@ packages = ["src/otari"] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" +markers = [ + "integration: tests that require a running gateway (skipped if none is available)", +] [tool.ruff] target-version = "py311" @@ -61,6 +64,11 @@ extend-exclude = ["src/otari/_control_plane"] select = ["E", "F", "I", "N", "W", "UP", "S", "B", "A", "C4", "DTZ", "T10", "ISC", "ICN", "PIE", "PT", "RSE", "RET", "SIM", "TID", "TCH", "ARG", "PLC", "PLE", "PLW", "TRY", "FLY", "PERF", "RUF"] ignore = ["S101", "TRY003", "PLW0603"] +[tool.ruff.lint.per-file-ignores] +# Integration tests spawn the gateway subprocess and poll it over HTTP; the +# subprocess/URL/temp-file audit rules don't apply to that test harness. +"tests/integration/*" = ["S603", "S310", "SIM115", "SIM117", "PLC0415", "TC003"] + [tool.ruff.lint.isort] known-first-party = ["otari"] diff --git a/tests/integration/test_control_plane_generated.py b/tests/integration/test_control_plane_generated.py index 465d9fd..0481c5f 100644 --- a/tests/integration/test_control_plane_generated.py +++ b/tests/integration/test_control_plane_generated.py @@ -19,6 +19,7 @@ import contextlib import os +import shutil import socket import subprocess import tempfile @@ -26,7 +27,6 @@ import urllib.error import urllib.request from collections.abc import Iterator -from pathlib import Path import pytest @@ -65,6 +65,8 @@ def _wait_healthy(base_url: str, timeout: float = 30.0) -> None: @pytest.fixture(scope="module") def gateway_url() -> Iterator[str]: cmd = os.environ.get("OTARI_GATEWAY_CMD", "gateway").split() + if shutil.which(cmd[0]) is None: + pytest.skip(f"gateway command '{cmd[0]}' not found; set OTARI_GATEWAY_CMD (e.g. pip install the gateway)") port = _free_port() db_path = tempfile.NamedTemporaryFile(suffix=".db", delete=False).name proc = subprocess.Popen( From 197d9b3d6cbe628a5a168008b7be956e968b389e Mon Sep 17 00:00:00 2001 From: njbrake Date: Sat, 6 Jun 2026 02:56:17 +0000 Subject: [PATCH 5/6] Option C: rebuild SDK as a thin shell over the generated typed core Replace the OpenAI-SDK delegation with a hand-written shell over the OpenAPI-generated core (otari._client), generated from the otari spec. The gateway is only OpenAI-compatible and has endpoints (notably the Anthropic-shaped /messages) the OpenAI SDK cannot represent; generating from the otari spec models the real contract. Core (unmodified generator output) replaces the old _control_plane subpackage and covers every endpoint with typed request/response models. Shell (the real work): - Auth modes preserved: platform -> Authorization: Bearer ; non-platform -> Otari-Key: Bearer ; control-plane -> Authorization: Bearer . Fed into the generated ApiClient default headers and the streaming shim's httpx requests. - Ergonomic methods keep the existing public names/signatures (completion/response/embedding/moderation/rerank/list_models/batches) and add message(...) for the previously-missing /messages endpoint. control_plane accessor now backed by _client. - SSE streaming shim (_streaming.py): the generated core buffers and cannot stream, so stream=True does a raw httpx streaming POST, parses text/event-stream framing, terminates on [DONE], and yields typed ChatCompletionChunk (chat) / parsed JSON (responses, messages). - Typed error mapping: generated ApiException (.status/.body) -> the errors.py hierarchy (Authentication 401/403, InsufficientFunds 402, ModelNotFound 404, BatchNotComplete 409, RateLimit 429, GatewayTimeout 504, UpstreamProvider 502/5xx, UnsupportedCapability cross-mode, generic OtariError). The streaming path adapts failed responses through the same mapper. - Async client wraps the sync generated core via asyncio.to_thread and streams natively over httpx.AsyncClient. Drop the openai dependency from inference. Update ruff/mypy excludes to src/otari/_client. Rewrite unit tests to mock the generated transport (RESTClientObject.request) and respx for SSE; control-plane integration tests updated to import from _client and verified green against a live gateway. Note: chat streaming cannot be live-verified in this sandbox (no provider key on the gateway); the SSE shim is unit-tested over mocked chunk bytes. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 15 + pyproject.toml | 15 +- src/otari/__init__.py | 24 +- src/otari/_base.py | 308 ++-- src/otari/_client/__init__.py | 400 +++++ src/otari/_client/api/__init__.py | 20 + src/otari/_client/api/audio_api.py | 685 ++++++++ src/otari/_client/api/batches_api.py | 1458 +++++++++++++++++ .../api/budgets_api.py | 12 +- src/otari/_client/api/chat_api.py | 312 ++++ src/otari/_client/api/embeddings_api.py | 312 ++++ src/otari/_client/api/health_api.py | 771 +++++++++ src/otari/_client/api/images_api.py | 312 ++++ .../api/keys_api.py | 16 +- src/otari/_client/api/messages_api.py | 312 ++++ src/otari/_client/api/models_api.py | 567 +++++++ src/otari/_client/api/moderations_api.py | 331 ++++ .../api/pricing_api.py | 10 +- src/otari/_client/api/rerank_api.py | 312 ++++ src/otari/_client/api/responses_api.py | 312 ++++ .../api/usage_api.py | 8 +- .../api/users_api.py | 16 +- .../{_control_plane => _client}/api_client.py | 12 +- .../api_response.py | 0 .../configuration.py | 2 +- .../{_control_plane => _client}/exceptions.py | 0 src/otari/_client/models/__init__.py | 177 ++ .../_client/models/audio_speech_request.py | 120 ++ .../_client/models/batch_request_item.py | 90 + .../models/budget_response.py | 0 src/otari/_client/models/caller.py | 155 ++ .../models/cc_chat_completion_audio.py | 107 ++ .../models/cc_chat_completion_message.py | 177 ++ ...hat_completion_message_custom_tool_call.py | 116 ++ ...t_completion_message_function_tool_call.py | 116 ++ ...hat_completion_message_tool_calls_inner.py | 134 ++ .../cc_chat_completion_token_logprob.py | 120 ++ src/otari/_client/models/cc_choice.py | 127 ++ .../_client/models/cc_choice_logprobs.py | 128 ++ .../models/cc_completion_tokens_details.py | 127 ++ .../_client/models/cc_completion_usage.py | 127 ++ src/otari/_client/models/cc_custom.py | 103 ++ src/otari/_client/models/cc_function.py | 103 ++ src/otari/_client/models/cc_function_call.py | 103 ++ .../models/cc_prompt_tokens_details.py | 113 ++ src/otari/_client/models/cc_reasoning.py | 88 + src/otari/_client/models/cc_top_logprob.py | 110 ++ .../cck_chat_completion_token_logprob.py | 120 ++ src/otari/_client/models/cck_choice_delta.py | 167 ++ .../models/cck_choice_delta_function_call.py | 113 ++ .../models/cck_choice_delta_tool_call.py | 136 ++ .../cck_choice_delta_tool_call_function.py | 113 ++ .../_client/models/cck_choice_logprobs.py | 128 ++ src/otari/_client/models/cck_chunk_choice.py | 135 ++ .../models/cck_completion_tokens_details.py | 127 ++ .../_client/models/cck_completion_usage.py | 127 ++ .../models/cck_prompt_tokens_details.py | 113 ++ src/otari/_client/models/cck_reasoning.py | 88 + src/otari/_client/models/cck_top_logprob.py | 110 ++ src/otari/_client/models/chat_completion.py | 149 ++ .../_client/models/chat_completion_chunk.py | 149 ++ .../_client/models/chat_completion_request.py | 220 +++ .../_client/models/chat_message_input.py | 194 +++ src/otari/_client/models/content.py | 145 ++ src/otari/_client/models/content1.py | 139 ++ src/otari/_client/models/content2.py | 139 ++ .../_client/models/content2_any_of_inner.py | 164 ++ src/otari/_client/models/content3.py | 134 ++ src/otari/_client/models/content4.py | 149 ++ src/otari/_client/models/content5.py | 164 ++ src/otari/_client/models/content6.py | 134 ++ src/otari/_client/models/content7.py | 134 ++ src/otari/_client/models/content8.py | 137 ++ src/otari/_client/models/content9_inner.py | 284 ++++ .../_client/models/content_any_of_inner.py | 134 ++ .../_client/models/create_batch_request.py | 108 ++ .../models/create_budget_request.py | 0 .../models/create_embedding_response.py | 126 ++ .../models/create_key_request.py | 0 .../models/create_key_response.py | 0 .../models/create_user_request.py | 0 src/otari/_client/models/emb_embedding.py | 112 ++ src/otari/_client/models/emb_usage.py | 103 ++ src/otari/_client/models/embedding_request.py | 115 ++ src/otari/_client/models/guardrail_config.py | 123 ++ .../models/http_validation_error.py | 2 +- .../models/image_generation_request.py | 132 ++ src/otari/_client/models/input.py | 138 ++ src/otari/_client/models/input1.py | 155 ++ .../models/key_info.py | 0 .../models/location_inner.py | 0 src/otari/_client/models/mcp_server_config.py | 112 ++ src/otari/_client/models/message_response.py | 187 +++ src/otari/_client/models/messages_request.py | 221 +++ src/otari/_client/models/model.py | 138 ++ .../_client/models/model_list_response.py | 98 ++ src/otari/_client/models/model_object.py | 105 ++ .../_client/models/model_pricing_info.py | 90 + .../_client/models/moderation_request.py | 101 ++ .../_client/models/moderation_response.py | 100 ++ src/otari/_client/models/moderation_result.py | 106 ++ .../_client/models/mr_base64_pdf_source.py | 119 ++ .../mr_bash_code_execution_output_block.py | 110 ++ .../mr_bash_code_execution_result_block.py | 124 ++ ...r_bash_code_execution_tool_result_block.py | 116 ++ ...r_bash_code_execution_tool_result_error.py | 117 ++ src/otari/_client/models/mr_cache_creation.py | 103 ++ .../models/mr_citation_char_location.py | 130 ++ .../mr_citation_content_block_location.py | 130 ++ .../models/mr_citation_page_location.py | 130 ++ .../_client/models/mr_citations_config.py | 101 ++ .../mr_citations_search_result_location.py | 125 ++ ...mr_citations_web_search_result_location.py | 121 ++ .../models/mr_code_execution_output_block.py | 110 ++ .../models/mr_code_execution_result_block.py | 124 ++ .../mr_code_execution_tool_result_block.py | 116 ++ .../mr_code_execution_tool_result_error.py | 117 ++ src/otari/_client/models/mr_container.py | 104 ++ .../models/mr_container_upload_block.py | 110 ++ src/otari/_client/models/mr_direct_caller.py | 108 ++ src/otari/_client/models/mr_document_block.py | 132 ++ ...r_encrypted_code_execution_result_block.py | 124 ++ .../_client/models/mr_plain_text_source.py | 119 ++ .../models/mr_redacted_thinking_block.py | 110 ++ .../_client/models/mr_refusal_stop_details.py | 132 ++ .../_client/models/mr_server_tool_caller.py | 110 ++ .../models/mr_server_tool_caller20260120.py | 110 ++ .../_client/models/mr_server_tool_usage.py | 103 ++ .../models/mr_server_tool_use_block.py | 132 ++ src/otari/_client/models/mr_text_block.py | 125 ++ .../models/mr_text_block_citations_inner.py | 179 ++ ...itor_code_execution_create_result_block.py | 110 ++ ...code_execution_str_replace_result_block.py | 143 ++ ...editor_code_execution_tool_result_block.py | 116 ++ ...editor_code_execution_tool_result_error.py | 124 ++ ...editor_code_execution_view_result_block.py | 140 ++ src/otari/_client/models/mr_thinking_block.py | 112 ++ .../_client/models/mr_tool_reference_block.py | 110 ++ .../mr_tool_search_tool_result_block.py | 116 ++ .../mr_tool_search_tool_result_error.py | 124 ++ ...mr_tool_search_tool_search_result_block.py | 118 ++ src/otari/_client/models/mr_tool_use_block.py | 125 ++ src/otari/_client/models/mr_usage.py | 163 ++ .../_client/models/mr_web_fetch_block.py | 123 ++ .../models/mr_web_fetch_tool_result_block.py | 127 ++ .../mr_web_fetch_tool_result_error_block.py | 117 ++ .../models/mr_web_search_result_block.py | 121 ++ .../models/mr_web_search_tool_result_block.py | 127 ++ .../models/mr_web_search_tool_result_error.py | 117 ++ src/otari/_client/models/msg_audio.py | 88 + ...chat_completion_assistant_message_param.py | 147 ++ ...hat_completion_content_part_image_param.py | 101 ++ ...mpletion_content_part_input_audio_param.py | 101 ++ ...t_completion_content_part_refusal_param.py | 97 ++ ...chat_completion_content_part_text_param.py | 97 ++ ...chat_completion_developer_message_param.py | 103 ++ ..._chat_completion_function_message_param.py | 104 ++ ...mpletion_message_custom_tool_call_param.py | 103 ++ ...letion_message_function_tool_call_param.py | 103 ++ ...sg_chat_completion_system_message_param.py | 103 ++ .../msg_chat_completion_tool_message_param.py | 103 ++ .../msg_chat_completion_user_message_param.py | 103 ++ src/otari/_client/models/msg_custom.py | 90 + src/otari/_client/models/msg_file.py | 101 ++ src/otari/_client/models/msg_file_file.py | 92 ++ src/otari/_client/models/msg_function.py | 90 + src/otari/_client/models/msg_function_call.py | 90 + src/otari/_client/models/msg_image_url.py | 100 ++ src/otari/_client/models/msg_input_audio.py | 97 ++ .../models/pricing_response.py | 0 src/otari/_client/models/rerank_request.py | 114 ++ src/otari/_client/models/rerank_response.py | 125 ++ src/otari/_client/models/responses_request.py | 177 ++ src/otari/_client/models/rr_rerank_meta.py | 100 ++ src/otari/_client/models/rr_rerank_result.py | 90 + src/otari/_client/models/rr_rerank_usage.py | 93 ++ .../models/set_pricing_request.py | 0 src/otari/_client/models/source.py | 134 ++ src/otari/_client/models/system.py | 144 ++ src/otari/_client/models/tool_calls_inner.py | 134 ++ src/otari/_client/models/tool_choice.py | 144 ++ .../models/update_budget_request.py | 0 .../models/update_key_request.py | 0 .../models/update_user_request.py | 0 .../models/usage_entry.py | 0 .../models/usage_log_response.py | 0 .../models/user_response.py | 0 .../models/validation_error.py | 2 +- .../{_control_plane => _client}/py.typed | 0 src/otari/{_control_plane => _client}/rest.py | 2 +- src/otari/_control_plane/__init__.py | 90 - src/otari/_control_plane/api/__init__.py | 9 - src/otari/_control_plane/models/__init__.py | 33 - src/otari/_streaming.py | 107 ++ src/otari/async_client.py | 453 +++-- src/otari/client.py | 438 +++-- src/otari/control_plane.py | 17 +- src/otari/types.py | 45 +- .../test_control_plane_generated.py | 16 +- tests/unit/conftest.py | 108 ++ tests/unit/test_async_client.py | 852 ++-------- tests/unit/test_client.py | 887 ++++------ 202 files changed, 25369 insertions(+), 2183 deletions(-) create mode 100644 src/otari/_client/__init__.py create mode 100644 src/otari/_client/api/__init__.py create mode 100644 src/otari/_client/api/audio_api.py create mode 100644 src/otari/_client/api/batches_api.py rename src/otari/{_control_plane => _client}/api/budgets_api.py (99%) create mode 100644 src/otari/_client/api/chat_api.py create mode 100644 src/otari/_client/api/embeddings_api.py create mode 100644 src/otari/_client/api/health_api.py create mode 100644 src/otari/_client/api/images_api.py rename src/otari/{_control_plane => _client}/api/keys_api.py (99%) create mode 100644 src/otari/_client/api/messages_api.py create mode 100644 src/otari/_client/api/models_api.py create mode 100644 src/otari/_client/api/moderations_api.py rename src/otari/{_control_plane => _client}/api/pricing_api.py (99%) create mode 100644 src/otari/_client/api/rerank_api.py create mode 100644 src/otari/_client/api/responses_api.py rename src/otari/{_control_plane => _client}/api/usage_api.py (98%) rename src/otari/{_control_plane => _client}/api/users_api.py (99%) rename src/otari/{_control_plane => _client}/api_client.py (98%) rename src/otari/{_control_plane => _client}/api_response.py (100%) rename src/otari/{_control_plane => _client}/configuration.py (99%) rename src/otari/{_control_plane => _client}/exceptions.py (100%) create mode 100644 src/otari/_client/models/__init__.py create mode 100644 src/otari/_client/models/audio_speech_request.py create mode 100644 src/otari/_client/models/batch_request_item.py rename src/otari/{_control_plane => _client}/models/budget_response.py (100%) create mode 100644 src/otari/_client/models/caller.py create mode 100644 src/otari/_client/models/cc_chat_completion_audio.py create mode 100644 src/otari/_client/models/cc_chat_completion_message.py create mode 100644 src/otari/_client/models/cc_chat_completion_message_custom_tool_call.py create mode 100644 src/otari/_client/models/cc_chat_completion_message_function_tool_call.py create mode 100644 src/otari/_client/models/cc_chat_completion_message_tool_calls_inner.py create mode 100644 src/otari/_client/models/cc_chat_completion_token_logprob.py create mode 100644 src/otari/_client/models/cc_choice.py create mode 100644 src/otari/_client/models/cc_choice_logprobs.py create mode 100644 src/otari/_client/models/cc_completion_tokens_details.py create mode 100644 src/otari/_client/models/cc_completion_usage.py create mode 100644 src/otari/_client/models/cc_custom.py create mode 100644 src/otari/_client/models/cc_function.py create mode 100644 src/otari/_client/models/cc_function_call.py create mode 100644 src/otari/_client/models/cc_prompt_tokens_details.py create mode 100644 src/otari/_client/models/cc_reasoning.py create mode 100644 src/otari/_client/models/cc_top_logprob.py create mode 100644 src/otari/_client/models/cck_chat_completion_token_logprob.py create mode 100644 src/otari/_client/models/cck_choice_delta.py create mode 100644 src/otari/_client/models/cck_choice_delta_function_call.py create mode 100644 src/otari/_client/models/cck_choice_delta_tool_call.py create mode 100644 src/otari/_client/models/cck_choice_delta_tool_call_function.py create mode 100644 src/otari/_client/models/cck_choice_logprobs.py create mode 100644 src/otari/_client/models/cck_chunk_choice.py create mode 100644 src/otari/_client/models/cck_completion_tokens_details.py create mode 100644 src/otari/_client/models/cck_completion_usage.py create mode 100644 src/otari/_client/models/cck_prompt_tokens_details.py create mode 100644 src/otari/_client/models/cck_reasoning.py create mode 100644 src/otari/_client/models/cck_top_logprob.py create mode 100644 src/otari/_client/models/chat_completion.py create mode 100644 src/otari/_client/models/chat_completion_chunk.py create mode 100644 src/otari/_client/models/chat_completion_request.py create mode 100644 src/otari/_client/models/chat_message_input.py create mode 100644 src/otari/_client/models/content.py create mode 100644 src/otari/_client/models/content1.py create mode 100644 src/otari/_client/models/content2.py create mode 100644 src/otari/_client/models/content2_any_of_inner.py create mode 100644 src/otari/_client/models/content3.py create mode 100644 src/otari/_client/models/content4.py create mode 100644 src/otari/_client/models/content5.py create mode 100644 src/otari/_client/models/content6.py create mode 100644 src/otari/_client/models/content7.py create mode 100644 src/otari/_client/models/content8.py create mode 100644 src/otari/_client/models/content9_inner.py create mode 100644 src/otari/_client/models/content_any_of_inner.py create mode 100644 src/otari/_client/models/create_batch_request.py rename src/otari/{_control_plane => _client}/models/create_budget_request.py (100%) create mode 100644 src/otari/_client/models/create_embedding_response.py rename src/otari/{_control_plane => _client}/models/create_key_request.py (100%) rename src/otari/{_control_plane => _client}/models/create_key_response.py (100%) rename src/otari/{_control_plane => _client}/models/create_user_request.py (100%) create mode 100644 src/otari/_client/models/emb_embedding.py create mode 100644 src/otari/_client/models/emb_usage.py create mode 100644 src/otari/_client/models/embedding_request.py create mode 100644 src/otari/_client/models/guardrail_config.py rename src/otari/{_control_plane => _client}/models/http_validation_error.py (97%) create mode 100644 src/otari/_client/models/image_generation_request.py create mode 100644 src/otari/_client/models/input.py create mode 100644 src/otari/_client/models/input1.py rename src/otari/{_control_plane => _client}/models/key_info.py (100%) rename src/otari/{_control_plane => _client}/models/location_inner.py (100%) create mode 100644 src/otari/_client/models/mcp_server_config.py create mode 100644 src/otari/_client/models/message_response.py create mode 100644 src/otari/_client/models/messages_request.py create mode 100644 src/otari/_client/models/model.py create mode 100644 src/otari/_client/models/model_list_response.py create mode 100644 src/otari/_client/models/model_object.py create mode 100644 src/otari/_client/models/model_pricing_info.py create mode 100644 src/otari/_client/models/moderation_request.py create mode 100644 src/otari/_client/models/moderation_response.py create mode 100644 src/otari/_client/models/moderation_result.py create mode 100644 src/otari/_client/models/mr_base64_pdf_source.py create mode 100644 src/otari/_client/models/mr_bash_code_execution_output_block.py create mode 100644 src/otari/_client/models/mr_bash_code_execution_result_block.py create mode 100644 src/otari/_client/models/mr_bash_code_execution_tool_result_block.py create mode 100644 src/otari/_client/models/mr_bash_code_execution_tool_result_error.py create mode 100644 src/otari/_client/models/mr_cache_creation.py create mode 100644 src/otari/_client/models/mr_citation_char_location.py create mode 100644 src/otari/_client/models/mr_citation_content_block_location.py create mode 100644 src/otari/_client/models/mr_citation_page_location.py create mode 100644 src/otari/_client/models/mr_citations_config.py create mode 100644 src/otari/_client/models/mr_citations_search_result_location.py create mode 100644 src/otari/_client/models/mr_citations_web_search_result_location.py create mode 100644 src/otari/_client/models/mr_code_execution_output_block.py create mode 100644 src/otari/_client/models/mr_code_execution_result_block.py create mode 100644 src/otari/_client/models/mr_code_execution_tool_result_block.py create mode 100644 src/otari/_client/models/mr_code_execution_tool_result_error.py create mode 100644 src/otari/_client/models/mr_container.py create mode 100644 src/otari/_client/models/mr_container_upload_block.py create mode 100644 src/otari/_client/models/mr_direct_caller.py create mode 100644 src/otari/_client/models/mr_document_block.py create mode 100644 src/otari/_client/models/mr_encrypted_code_execution_result_block.py create mode 100644 src/otari/_client/models/mr_plain_text_source.py create mode 100644 src/otari/_client/models/mr_redacted_thinking_block.py create mode 100644 src/otari/_client/models/mr_refusal_stop_details.py create mode 100644 src/otari/_client/models/mr_server_tool_caller.py create mode 100644 src/otari/_client/models/mr_server_tool_caller20260120.py create mode 100644 src/otari/_client/models/mr_server_tool_usage.py create mode 100644 src/otari/_client/models/mr_server_tool_use_block.py create mode 100644 src/otari/_client/models/mr_text_block.py create mode 100644 src/otari/_client/models/mr_text_block_citations_inner.py create mode 100644 src/otari/_client/models/mr_text_editor_code_execution_create_result_block.py create mode 100644 src/otari/_client/models/mr_text_editor_code_execution_str_replace_result_block.py create mode 100644 src/otari/_client/models/mr_text_editor_code_execution_tool_result_block.py create mode 100644 src/otari/_client/models/mr_text_editor_code_execution_tool_result_error.py create mode 100644 src/otari/_client/models/mr_text_editor_code_execution_view_result_block.py create mode 100644 src/otari/_client/models/mr_thinking_block.py create mode 100644 src/otari/_client/models/mr_tool_reference_block.py create mode 100644 src/otari/_client/models/mr_tool_search_tool_result_block.py create mode 100644 src/otari/_client/models/mr_tool_search_tool_result_error.py create mode 100644 src/otari/_client/models/mr_tool_search_tool_search_result_block.py create mode 100644 src/otari/_client/models/mr_tool_use_block.py create mode 100644 src/otari/_client/models/mr_usage.py create mode 100644 src/otari/_client/models/mr_web_fetch_block.py create mode 100644 src/otari/_client/models/mr_web_fetch_tool_result_block.py create mode 100644 src/otari/_client/models/mr_web_fetch_tool_result_error_block.py create mode 100644 src/otari/_client/models/mr_web_search_result_block.py create mode 100644 src/otari/_client/models/mr_web_search_tool_result_block.py create mode 100644 src/otari/_client/models/mr_web_search_tool_result_error.py create mode 100644 src/otari/_client/models/msg_audio.py create mode 100644 src/otari/_client/models/msg_chat_completion_assistant_message_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_content_part_image_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_content_part_input_audio_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_content_part_refusal_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_content_part_text_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_developer_message_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_function_message_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_message_custom_tool_call_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_message_function_tool_call_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_system_message_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_tool_message_param.py create mode 100644 src/otari/_client/models/msg_chat_completion_user_message_param.py create mode 100644 src/otari/_client/models/msg_custom.py create mode 100644 src/otari/_client/models/msg_file.py create mode 100644 src/otari/_client/models/msg_file_file.py create mode 100644 src/otari/_client/models/msg_function.py create mode 100644 src/otari/_client/models/msg_function_call.py create mode 100644 src/otari/_client/models/msg_image_url.py create mode 100644 src/otari/_client/models/msg_input_audio.py rename src/otari/{_control_plane => _client}/models/pricing_response.py (100%) create mode 100644 src/otari/_client/models/rerank_request.py create mode 100644 src/otari/_client/models/rerank_response.py create mode 100644 src/otari/_client/models/responses_request.py create mode 100644 src/otari/_client/models/rr_rerank_meta.py create mode 100644 src/otari/_client/models/rr_rerank_result.py create mode 100644 src/otari/_client/models/rr_rerank_usage.py rename src/otari/{_control_plane => _client}/models/set_pricing_request.py (100%) create mode 100644 src/otari/_client/models/source.py create mode 100644 src/otari/_client/models/system.py create mode 100644 src/otari/_client/models/tool_calls_inner.py create mode 100644 src/otari/_client/models/tool_choice.py rename src/otari/{_control_plane => _client}/models/update_budget_request.py (100%) rename src/otari/{_control_plane => _client}/models/update_key_request.py (100%) rename src/otari/{_control_plane => _client}/models/update_user_request.py (100%) rename src/otari/{_control_plane => _client}/models/usage_entry.py (100%) rename src/otari/{_control_plane => _client}/models/usage_log_response.py (100%) rename src/otari/{_control_plane => _client}/models/user_response.py (100%) rename src/otari/{_control_plane => _client}/models/validation_error.py (97%) rename src/otari/{_control_plane => _client}/py.typed (100%) rename src/otari/{_control_plane => _client}/rest.py (99%) delete mode 100644 src/otari/_control_plane/__init__.py delete mode 100644 src/otari/_control_plane/api/__init__.py delete mode 100644 src/otari/_control_plane/models/__init__.py create mode 100644 src/otari/_streaming.py create mode 100644 tests/unit/conftest.py diff --git a/README.md b/README.md index a36110f..873a29f 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,21 @@ response = client.response( print(response.output_text) ``` +### Messages API (Anthropic-shaped) + +The gateway's `/messages` endpoint (Anthropic message shape) is exposed via +`message(...)`. Set `stream=True` to iterate raw message-stream event dicts. + +```python +message = client.message( + model="anthropic:claude-3-5-sonnet", + messages=[{"role": "user", "content": "Hello!"}], + max_tokens=256, +) + +print(message.content) +``` + ### Embeddings ```python diff --git a/pyproject.toml b/pyproject.toml index aaa0736..cf4bf3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,9 +22,9 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "openai>=1.99.3", + # Streaming shim (raw SSE over httpx); the generated core cannot stream. "httpx>=0.25.0", - # Runtime deps of the generated control-plane client (otari._control_plane). + # Runtime deps of the OpenAPI-generated core (otari._client). "urllib3>=2.1.0", "python-dateutil>=2.8.2", "pydantic>=2.0.0", @@ -40,6 +40,7 @@ Issues = "https://github.com/mozilla-ai/otari-sdk-python/issues" dev = [ "pytest>=8.0", "pytest-asyncio>=0.24", + "respx>=0.21", "ruff>=0.8", "mypy>=1.13", ] @@ -57,8 +58,8 @@ markers = [ [tool.ruff] target-version = "py311" line-length = 120 -# Generated control-plane client (OpenAPI Generator output) is not hand-linted. -extend-exclude = ["src/otari/_control_plane"] +# Generated core client (OpenAPI Generator output) is not hand-linted. +extend-exclude = ["src/otari/_client"] [tool.ruff.lint] select = ["E", "F", "I", "N", "W", "UP", "S", "B", "A", "C4", "DTZ", "T10", "ISC", "ICN", "PIE", "PT", "RSE", "RET", "SIM", "TID", "TCH", "ARG", "PLC", "PLE", "PLW", "TRY", "FLY", "PERF", "RUF"] @@ -77,10 +78,10 @@ python_version = "3.11" strict = true warn_return_any = true warn_unused_configs = true -# Generated control-plane client (OpenAPI Generator output) is not type-checked here. -exclude = ["src/otari/_control_plane/"] +# Generated core client (OpenAPI Generator output) is not type-checked here. +exclude = ["src/otari/_client/"] [[tool.mypy.overrides]] -module = ["otari._control_plane.*"] +module = ["otari._client.*"] ignore_errors = true ignore_missing_imports = true diff --git a/src/otari/__init__.py b/src/otari/__init__.py index de5a8e6..f6e9895 100644 --- a/src/otari/__init__.py +++ b/src/otari/__init__.py @@ -9,7 +9,7 @@ platform_token="your-token-here", ) - response = await client.completion( + response = client.completion( model="openai:gpt-4o-mini", messages=[{"role": "user", "content": "Hello!"}], ) @@ -33,23 +33,20 @@ UpstreamProviderError, ) from otari.types import ( - AsyncStream, BatchRequestItem, BatchResult, BatchResultError, BatchResultItem, ChatCompletion, ChatCompletionChunk, - ChatCompletionMessageParam, CreateBatchParams, CreateEmbeddingResponse, - EmbeddingCreateParams, ListBatchesOptions, - Model, + MessageResponse, + ModelObject, + ModerationResponse, OtariClientOptions, - Response, - ResponseStreamEvent, - Stream, + RerankResponse, ) try: @@ -60,7 +57,6 @@ __all__ = [ "AsyncOtariClient", - "AsyncStream", "AuthenticationError", "BatchNotCompleteError", "BatchRequestItem", @@ -69,23 +65,21 @@ "BatchResultItem", "ChatCompletion", "ChatCompletionChunk", - "ChatCompletionMessageParam", "ControlPlane", "CreateBatchParams", "CreateEmbeddingResponse", - "EmbeddingCreateParams", "GatewayTimeoutError", "InsufficientFundsError", "ListBatchesOptions", - "Model", + "MessageResponse", "ModelNotFoundError", + "ModelObject", + "ModerationResponse", "OtariClient", "OtariClientOptions", "OtariError", "RateLimitError", - "Response", - "ResponseStreamEvent", - "Stream", + "RerankResponse", "UnsupportedCapabilityError", "UpstreamProviderError", ] diff --git a/src/otari/_base.py b/src/otari/_base.py index b8347e3..86e7b58 100644 --- a/src/otari/_base.py +++ b/src/otari/_base.py @@ -4,19 +4,24 @@ synchronous or asynchronous: auth-mode resolution, base-URL normalization, header building, and error mapping. The concrete clients (:class:`~otari.client.OtariClient` and -:class:`~otari.async_client.AsyncOtariClient`) construct their own OpenAI and -httpx clients and implement the I/O methods on top of this base. +:class:`~otari.async_client.AsyncOtariClient`) construct their own generated +``_client`` and httpx clients and implement the I/O methods on top of this base. + +Option C: the inference path is a thin shell over the OpenAPI-generated core in +:mod:`otari._client` (typed models + per-endpoint API classes). The generated +``ApiException`` is the single error type all generated calls raise; this module +maps it to the typed otari exception hierarchy in :mod:`otari.errors`. """ from __future__ import annotations +import json import os import re import urllib.parse -from typing import TYPE_CHECKING, Any - -import openai +from typing import TYPE_CHECKING, Any, Protocol, TypeVar, cast +from otari._client.exceptions import ApiException from otari.errors import ( AuthenticationError, BatchNotCompleteError, @@ -49,20 +54,14 @@ # Admin/master credential for the control-plane (management) endpoints. _ENV_ADMIN_KEY = "GATEWAY_ADMIN_KEY" -_STATUS_TO_ERROR: dict[int, type[AuthenticationError] | type[ModelNotFoundError]] = { - 401: AuthenticationError, - 403: AuthenticationError, - 404: ModelNotFoundError, -} - class _BaseOtariClient: """Transport-agnostic base for the otari gateway clients. - Subclasses are responsible for constructing the underlying OpenAI client - (``OpenAI`` or ``AsyncOpenAI``) and the httpx client (``httpx.Client`` or - ``httpx.AsyncClient``) using the resolved configuration attributes set up - here. + Subclasses are responsible for constructing the generated ``_client`` + ``ApiClient`` (seeded with the default headers assembled here) and an httpx + client (``httpx.Client`` or ``httpx.AsyncClient``) for the SSE streaming + shim, using the resolved configuration attributes set up here. """ platform_mode: bool @@ -76,7 +75,6 @@ def __init__( platform_token: str | None = None, admin_key: str | None = None, default_headers: dict[str, str] | None = None, - openai_options: dict[str, Any] | None = None, ) -> None: # Canonical OTARI_AI_TOKEN wins over the legacy GATEWAY_PLATFORM_TOKEN. resolved_platform_token = ( @@ -114,217 +112,201 @@ def __init__( api_base_url = cleaned if cleaned.endswith("/v1") else f"{cleaned}/v1" self._base_url = api_base_url + # The generated core's operation paths already include the ``/v1`` + # prefix, so the generated ``Configuration.host`` is the gateway root. + self._gateway_root_url = api_base_url.removesuffix("/v1") headers: dict[str, str] = {**(default_headers or {})} # Auth resolution (same logic as TS SDK / Python GatewayProvider): - # 1. Explicit platform_token -> platform mode + # 1. Explicit platform_token -> platform mode (Bearer Authorization) # 2. OTARI_AI_TOKEN (or legacy GATEWAY_PLATFORM_TOKEN) env + no api_key # option -> platform mode - # 3. Otherwise -> non-platform mode + # 3. Otherwise -> non-platform mode (Otari-Key header) if resolved_platform_token and not api_key: self.platform_mode = True self._platform_token: str | None = resolved_platform_token self._api_key: str | None = None - # In platform mode the OpenAI client carries the Bearer token. - self._openai_api_key = resolved_platform_token + headers["Authorization"] = f"Bearer {resolved_platform_token}" else: self.platform_mode = False self._platform_token = None self._api_key = resolved_api_key or None if resolved_api_key: headers[GATEWAY_HEADER_NAME] = f"Bearer {resolved_api_key}" - # In non-platform mode we still need to pass *some* API key to the - # OpenAI client (it validates the field). - self._openai_api_key = resolved_api_key or "unused" - # Configuration the concrete client uses to build its OpenAI client. - self._openai_base_url = api_base_url - self._openai_default_headers = headers or None - self._openai_extra_kwargs: dict[str, Any] = {**(openai_options or {})} - - # Store auth headers for batch/raw HTTP calls. - self._auth_headers: dict[str, str] = {} - if resolved_platform_token and not api_key: - self._auth_headers["Authorization"] = f"Bearer {resolved_platform_token}" - elif resolved_api_key: - self._auth_headers[GATEWAY_HEADER_NAME] = f"Bearer {resolved_api_key}" - if default_headers: - self._auth_headers.update(default_headers) + # Default headers fed into the generated ApiClient and the streaming + # shim's httpx requests. Includes the auth header for the active mode. + self._default_headers: dict[str, str] = headers # Control-plane (management) auth. Those endpoints expect - # ``Authorization: Bearer ``. In platform mode the + # ``Authorization: Bearer ``, distinct from the + # ``Otari-Key`` virtual key used for inference. In platform mode the # platform token already serves as that bearer; for a self-hosted # gateway the caller passes the master key as ``admin_key`` (or via - # ``GATEWAY_ADMIN_KEY``). The control-plane client targets the gateway - # root (the generated paths already include the ``/v1`` prefix). - self._gateway_root_url = api_base_url.removesuffix("/v1") + # ``GATEWAY_ADMIN_KEY``). self._admin_token: str | None = ( admin_key or os.environ.get(_ENV_ADMIN_KEY) or resolved_platform_token ) # -- Error handling ----------------------------------------------------- - def _handle_error(self, error: Exception) -> None: - """Convert ``openai.APIStatusError`` to typed otari exceptions. + def _map_api_exception(self, error: ApiException) -> OtariError: + """Map a generated ``ApiException`` to a typed otari exception. - Most mappings only apply in platform mode; in non-platform mode the - original error propagates unchanged. The one exception is - :class:`UnsupportedCapabilityError`, which surfaces in both modes. - """ - if not isinstance(error, openai.APIStatusError): - return + ``ApiException`` carries ``.status`` (int) and ``.body`` (the raw JSON + string the gateway returned) plus ``.headers``. The gateway encodes the + human-readable reason under the ``detail`` key (FastAPI convention). - status = error.status_code - headers = error.response.headers - correlation_id = headers.get("x-correlation-id") - retry_after = headers.get("retry-after") + Most status mappings only apply in platform mode; in non-platform mode + the generic :class:`OtariError` is raised so the caller still gets a + single SDK exception type. The one cross-mode case is + :class:`UnsupportedCapabilityError`, surfaced in both modes. + """ + status = error.status if isinstance(error.status, int) else 0 + headers = error.headers or {} + detail = self._extract_detail(error) + correlation_id = _header_get(headers, "x-correlation-id") + retry_after = _header_get(headers, "retry-after") - detail = str(getattr(error, "message", str(error))) - if correlation_id: - detail = f"{detail} (correlation_id={correlation_id})" + full = f"{detail} (correlation_id={correlation_id})" if correlation_id else detail # Unsupported-capability is surfaced regardless of mode. if status == 400 and _UNSUPPORTED_MODERATION_RE.search(detail): provider = _parse_unsupported_provider(detail) capability = "multimodal_moderation" if "multimodal" in detail else "moderation" - raise UnsupportedCapabilityError( - detail, + return UnsupportedCapabilityError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME, provider=provider, capability=capability, - ) from error - - # The rest of the mappings only apply in platform mode. - if not self.platform_mode: - return - - if (error_cls := _STATUS_TO_ERROR.get(status)) is not None: - raise error_cls( - detail, - status_code=status, - original_error=error, - provider_name=PROVIDER_NAME, - ) from error + ) + if status in (401, 403): + return AuthenticationError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME + ) if status == 402: - raise InsufficientFundsError( - detail, + return InsufficientFundsError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME + ) + if status == 404: + return ModelNotFoundError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME + ) + if status == 409: + return BatchNotCompleteError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME, - ) from error - + batch_id=_extract_batch_id(detail), + batch_status=_extract_status(detail), + ) if status == 429: - raise RateLimitError( - detail, + return RateLimitError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME, retry_after=retry_after, - ) from error - - if status == 502: - raise UpstreamProviderError( - detail, - status_code=status, - original_error=error, - provider_name=PROVIDER_NAME, - ) from error - + ) if status == 504: - raise GatewayTimeoutError( - detail, - status_code=status, - original_error=error, - provider_name=PROVIDER_NAME, - ) from error - - # Unrecognized status: let the original error propagate. - - def _build_batch_headers(self) -> dict[str, str]: - """Build the headers used for raw batch HTTP requests.""" - return { - "Content-Type": "application/json", - **self._auth_headers, - } + return GatewayTimeoutError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME + ) + # 502 and any other 5xx are upstream-provider failures. + if status == 502 or 500 <= status < 600: + return UpstreamProviderError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME + ) - def _map_batch_error(self, response: httpx.Response) -> None: - """Map a failed batch HTTP response to a typed SDK error. + return OtariError( + full, status_code=status, original_error=error, provider_name=PROVIDER_NAME + ) - ``response.json()`` is read synchronously, so this works for both the - sync and async clients (the async client has already received the full - body by the time it calls this). + @staticmethod + def _extract_detail(error: ApiException) -> str: + """Pull the gateway's human-readable detail from an ``ApiException`` body.""" + body = error.body + if isinstance(body, (bytes, bytearray)): + body = body.decode("utf-8", "replace") + if isinstance(body, str) and body: + try: + parsed = json.loads(body) + except (ValueError, TypeError): + return body + if isinstance(parsed, dict): + detail = parsed.get("detail") or parsed.get("message") or parsed.get("error") + if isinstance(detail, str): + return detail + if detail is not None: + return str(detail) + return body + return error.reason or "An error occurred" + + def _map_streaming_response(self, response: httpx.Response, body: bytes) -> OtariError: + """Map a failed raw streaming response to a typed otari exception. + + The SSE shim issues raw httpx requests, so it never goes through the + generated client and never raises ``ApiException``. To keep one mapping + path, adapt the failed response into an ``ApiException`` and reuse + :meth:`_map_api_exception`. """ - try: - data = response.json() - detail = data.get("detail", response.reason_phrase) - except Exception: - detail = response.reason_phrase or "" - - message = detail if isinstance(detail, str) else (response.reason_phrase or "") - correlation_id = response.headers.get("x-correlation-id") - full_message = f"{message} (correlation_id={correlation_id})" if correlation_id else message - - status = response.status_code + exc = ApiException( + status=response.status_code, + reason=response.reason_phrase, + body=body.decode("utf-8", "replace"), + ) + exc.headers = dict(response.headers) + return self._map_api_exception(exc) - if status in (401, 403): - raise AuthenticationError( - full_message, - status_code=status, - provider_name=PROVIDER_NAME, - ) - if status == 404: - msg = ( - full_message - if "not found" in full_message.lower() - else f"This gateway does not support batch operations. Upgrade your gateway. ({full_message})" - ) - raise OtariError(msg, status_code=404, provider_name=PROVIDER_NAME) +# --------------------------------------------------------------------------- +# Module-level helpers +# --------------------------------------------------------------------------- - if status == 409: - raise BatchNotCompleteError( - full_message, - status_code=409, - provider_name=PROVIDER_NAME, - batch_id=_extract_batch_id(message), - batch_status=_extract_status(message), - ) - if status == 422: - raise OtariError(full_message, status_code=422, provider_name=PROVIDER_NAME) +class _FromDict(Protocol): + """Structural type for the generated request models' ``from_dict`` classmethod.""" - if status == 429: - raise RateLimitError( - full_message, - status_code=429, - provider_name=PROVIDER_NAME, - retry_after=response.headers.get("retry-after"), - ) + @classmethod + def from_dict(cls, obj: dict[str, Any] | None) -> Any: ... - if status == 502: - raise UpstreamProviderError( - full_message, - status_code=502, - provider_name=PROVIDER_NAME, - ) - if status == 504: - raise GatewayTimeoutError( - full_message, - status_code=504, - provider_name=PROVIDER_NAME, - ) +_M = TypeVar("_M", bound=_FromDict) - raise OtariError(full_message, status_code=status, provider_name=PROVIDER_NAME) +def build_request(model: type[_M], body: dict[str, Any]) -> _M: + """Build a generated request model from ``body``, narrowing the ``Optional``. -# --------------------------------------------------------------------------- -# Module-level helpers -# --------------------------------------------------------------------------- + The generated ``from_dict`` is typed ``-> Optional[Self]`` (it returns ``None`` + only for ``None`` input); we always pass a real dict, so the result is never + ``None``. This wrapper keeps that fact in one place instead of scattering + ``# type: ignore`` across every ergonomic method. + """ + return cast("_M", model.from_dict(body)) + + +def _header_get(headers: Any, name: str) -> str | None: + """Case-insensitively read a header from a dict or HTTPHeaderDict.""" + if headers is None: + return None + getter = getattr(headers, "get", None) + if getter is not None: + value = getter(name) + if value is not None: + return str(value) + lowered = name.lower() + try: + for key, value in dict(headers).items(): + if str(key).lower() == lowered: + return str(value) + except (TypeError, ValueError): + return None + return None def _parse_unsupported_provider(detail: str) -> str: diff --git a/src/otari/_client/__init__.py b/src/otari/_client/__init__.py new file mode 100644 index 0000000..c5d554b --- /dev/null +++ b/src/otari/_client/__init__.py @@ -0,0 +1,400 @@ +# coding: utf-8 + +# flake8: noqa + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +__version__ = "1.0.0" + +# Define package exports +__all__ = [ + "AudioApi", + "BatchesApi", + "BudgetsApi", + "ChatApi", + "EmbeddingsApi", + "HealthApi", + "ImagesApi", + "KeysApi", + "MessagesApi", + "ModelsApi", + "ModerationsApi", + "PricingApi", + "RerankApi", + "ResponsesApi", + "UsageApi", + "UsersApi", + "ApiResponse", + "ApiClient", + "Configuration", + "OpenApiException", + "ApiTypeError", + "ApiValueError", + "ApiKeyError", + "ApiAttributeError", + "ApiException", + "AudioSpeechRequest", + "BatchRequestItem", + "BudgetResponse", + "CCChatCompletionAudio", + "CCChatCompletionMessage", + "CCChatCompletionMessageCustomToolCall", + "CCChatCompletionMessageFunctionToolCall", + "CCChatCompletionMessageToolCallsInner", + "CCChatCompletionTokenLogprob", + "CCChoice", + "CCChoiceLogprobs", + "CCCompletionTokensDetails", + "CCCompletionUsage", + "CCCustom", + "CCFunction", + "CCFunctionCall", + "CCKChatCompletionTokenLogprob", + "CCKChoiceDelta", + "CCKChoiceDeltaFunctionCall", + "CCKChoiceDeltaToolCall", + "CCKChoiceDeltaToolCallFunction", + "CCKChoiceLogprobs", + "CCKChunkChoice", + "CCKCompletionTokensDetails", + "CCKCompletionUsage", + "CCKPromptTokensDetails", + "CCKReasoning", + "CCKTopLogprob", + "CCPromptTokensDetails", + "CCReasoning", + "CCTopLogprob", + "Caller", + "ChatCompletion", + "ChatCompletionChunk", + "ChatCompletionRequest", + "ChatMessageInput", + "Content", + "Content1", + "Content2", + "Content2AnyOfInner", + "Content3", + "Content4", + "Content5", + "Content6", + "Content7", + "Content8", + "Content9Inner", + "ContentAnyOfInner", + "CreateBatchRequest", + "CreateBudgetRequest", + "CreateEmbeddingResponse", + "CreateKeyRequest", + "CreateKeyResponse", + "CreateUserRequest", + "EMBEmbedding", + "EMBUsage", + "EmbeddingRequest", + "GuardrailConfig", + "HTTPValidationError", + "ImageGenerationRequest", + "Input", + "Input1", + "KeyInfo", + "LocationInner", + "MRBase64PDFSource", + "MRBashCodeExecutionOutputBlock", + "MRBashCodeExecutionResultBlock", + "MRBashCodeExecutionToolResultBlock", + "MRBashCodeExecutionToolResultError", + "MRCacheCreation", + "MRCitationCharLocation", + "MRCitationContentBlockLocation", + "MRCitationPageLocation", + "MRCitationsConfig", + "MRCitationsSearchResultLocation", + "MRCitationsWebSearchResultLocation", + "MRCodeExecutionOutputBlock", + "MRCodeExecutionResultBlock", + "MRCodeExecutionToolResultBlock", + "MRCodeExecutionToolResultError", + "MRContainer", + "MRContainerUploadBlock", + "MRDirectCaller", + "MRDocumentBlock", + "MREncryptedCodeExecutionResultBlock", + "MRPlainTextSource", + "MRRedactedThinkingBlock", + "MRRefusalStopDetails", + "MRServerToolCaller", + "MRServerToolCaller20260120", + "MRServerToolUsage", + "MRServerToolUseBlock", + "MRTextBlock", + "MRTextBlockCitationsInner", + "MRTextEditorCodeExecutionCreateResultBlock", + "MRTextEditorCodeExecutionStrReplaceResultBlock", + "MRTextEditorCodeExecutionToolResultBlock", + "MRTextEditorCodeExecutionToolResultError", + "MRTextEditorCodeExecutionViewResultBlock", + "MRThinkingBlock", + "MRToolReferenceBlock", + "MRToolSearchToolResultBlock", + "MRToolSearchToolResultError", + "MRToolSearchToolSearchResultBlock", + "MRToolUseBlock", + "MRUsage", + "MRWebFetchBlock", + "MRWebFetchToolResultBlock", + "MRWebFetchToolResultErrorBlock", + "MRWebSearchResultBlock", + "MRWebSearchToolResultBlock", + "MRWebSearchToolResultError", + "MSGAudio", + "MSGChatCompletionAssistantMessageParam", + "MSGChatCompletionContentPartImageParam", + "MSGChatCompletionContentPartInputAudioParam", + "MSGChatCompletionContentPartRefusalParam", + "MSGChatCompletionContentPartTextParam", + "MSGChatCompletionDeveloperMessageParam", + "MSGChatCompletionFunctionMessageParam", + "MSGChatCompletionMessageCustomToolCallParam", + "MSGChatCompletionMessageFunctionToolCallParam", + "MSGChatCompletionSystemMessageParam", + "MSGChatCompletionToolMessageParam", + "MSGChatCompletionUserMessageParam", + "MSGCustom", + "MSGFile", + "MSGFileFile", + "MSGFunction", + "MSGFunctionCall", + "MSGImageURL", + "MSGInputAudio", + "McpServerConfig", + "MessageResponse", + "MessagesRequest", + "Model", + "ModelListResponse", + "ModelObject", + "ModelPricingInfo", + "ModerationRequest", + "ModerationResponse", + "ModerationResult", + "PricingResponse", + "RRRerankMeta", + "RRRerankResult", + "RRRerankUsage", + "RerankRequest", + "RerankResponse", + "ResponsesRequest", + "SetPricingRequest", + "Source", + "System", + "ToolCallsInner", + "ToolChoice", + "UpdateBudgetRequest", + "UpdateKeyRequest", + "UpdateUserRequest", + "UsageEntry", + "UsageLogResponse", + "UserResponse", + "ValidationError", +] + +# import apis into sdk package +from otari._client.api.audio_api import AudioApi as AudioApi +from otari._client.api.batches_api import BatchesApi as BatchesApi +from otari._client.api.budgets_api import BudgetsApi as BudgetsApi +from otari._client.api.chat_api import ChatApi as ChatApi +from otari._client.api.embeddings_api import EmbeddingsApi as EmbeddingsApi +from otari._client.api.health_api import HealthApi as HealthApi +from otari._client.api.images_api import ImagesApi as ImagesApi +from otari._client.api.keys_api import KeysApi as KeysApi +from otari._client.api.messages_api import MessagesApi as MessagesApi +from otari._client.api.models_api import ModelsApi as ModelsApi +from otari._client.api.moderations_api import ModerationsApi as ModerationsApi +from otari._client.api.pricing_api import PricingApi as PricingApi +from otari._client.api.rerank_api import RerankApi as RerankApi +from otari._client.api.responses_api import ResponsesApi as ResponsesApi +from otari._client.api.usage_api import UsageApi as UsageApi +from otari._client.api.users_api import UsersApi as UsersApi + +# import ApiClient +from otari._client.api_response import ApiResponse as ApiResponse +from otari._client.api_client import ApiClient as ApiClient +from otari._client.configuration import Configuration as Configuration +from otari._client.exceptions import OpenApiException as OpenApiException +from otari._client.exceptions import ApiTypeError as ApiTypeError +from otari._client.exceptions import ApiValueError as ApiValueError +from otari._client.exceptions import ApiKeyError as ApiKeyError +from otari._client.exceptions import ApiAttributeError as ApiAttributeError +from otari._client.exceptions import ApiException as ApiException + +# import models into sdk package +from otari._client.models.audio_speech_request import AudioSpeechRequest as AudioSpeechRequest +from otari._client.models.batch_request_item import BatchRequestItem as BatchRequestItem +from otari._client.models.budget_response import BudgetResponse as BudgetResponse +from otari._client.models.cc_chat_completion_audio import CCChatCompletionAudio as CCChatCompletionAudio +from otari._client.models.cc_chat_completion_message import CCChatCompletionMessage as CCChatCompletionMessage +from otari._client.models.cc_chat_completion_message_custom_tool_call import CCChatCompletionMessageCustomToolCall as CCChatCompletionMessageCustomToolCall +from otari._client.models.cc_chat_completion_message_function_tool_call import CCChatCompletionMessageFunctionToolCall as CCChatCompletionMessageFunctionToolCall +from otari._client.models.cc_chat_completion_message_tool_calls_inner import CCChatCompletionMessageToolCallsInner as CCChatCompletionMessageToolCallsInner +from otari._client.models.cc_chat_completion_token_logprob import CCChatCompletionTokenLogprob as CCChatCompletionTokenLogprob +from otari._client.models.cc_choice import CCChoice as CCChoice +from otari._client.models.cc_choice_logprobs import CCChoiceLogprobs as CCChoiceLogprobs +from otari._client.models.cc_completion_tokens_details import CCCompletionTokensDetails as CCCompletionTokensDetails +from otari._client.models.cc_completion_usage import CCCompletionUsage as CCCompletionUsage +from otari._client.models.cc_custom import CCCustom as CCCustom +from otari._client.models.cc_function import CCFunction as CCFunction +from otari._client.models.cc_function_call import CCFunctionCall as CCFunctionCall +from otari._client.models.cck_chat_completion_token_logprob import CCKChatCompletionTokenLogprob as CCKChatCompletionTokenLogprob +from otari._client.models.cck_choice_delta import CCKChoiceDelta as CCKChoiceDelta +from otari._client.models.cck_choice_delta_function_call import CCKChoiceDeltaFunctionCall as CCKChoiceDeltaFunctionCall +from otari._client.models.cck_choice_delta_tool_call import CCKChoiceDeltaToolCall as CCKChoiceDeltaToolCall +from otari._client.models.cck_choice_delta_tool_call_function import CCKChoiceDeltaToolCallFunction as CCKChoiceDeltaToolCallFunction +from otari._client.models.cck_choice_logprobs import CCKChoiceLogprobs as CCKChoiceLogprobs +from otari._client.models.cck_chunk_choice import CCKChunkChoice as CCKChunkChoice +from otari._client.models.cck_completion_tokens_details import CCKCompletionTokensDetails as CCKCompletionTokensDetails +from otari._client.models.cck_completion_usage import CCKCompletionUsage as CCKCompletionUsage +from otari._client.models.cck_prompt_tokens_details import CCKPromptTokensDetails as CCKPromptTokensDetails +from otari._client.models.cck_reasoning import CCKReasoning as CCKReasoning +from otari._client.models.cck_top_logprob import CCKTopLogprob as CCKTopLogprob +from otari._client.models.cc_prompt_tokens_details import CCPromptTokensDetails as CCPromptTokensDetails +from otari._client.models.cc_reasoning import CCReasoning as CCReasoning +from otari._client.models.cc_top_logprob import CCTopLogprob as CCTopLogprob +from otari._client.models.caller import Caller as Caller +from otari._client.models.chat_completion import ChatCompletion as ChatCompletion +from otari._client.models.chat_completion_chunk import ChatCompletionChunk as ChatCompletionChunk +from otari._client.models.chat_completion_request import ChatCompletionRequest as ChatCompletionRequest +from otari._client.models.chat_message_input import ChatMessageInput as ChatMessageInput +from otari._client.models.content import Content as Content +from otari._client.models.content1 import Content1 as Content1 +from otari._client.models.content2 import Content2 as Content2 +from otari._client.models.content2_any_of_inner import Content2AnyOfInner as Content2AnyOfInner +from otari._client.models.content3 import Content3 as Content3 +from otari._client.models.content4 import Content4 as Content4 +from otari._client.models.content5 import Content5 as Content5 +from otari._client.models.content6 import Content6 as Content6 +from otari._client.models.content7 import Content7 as Content7 +from otari._client.models.content8 import Content8 as Content8 +from otari._client.models.content9_inner import Content9Inner as Content9Inner +from otari._client.models.content_any_of_inner import ContentAnyOfInner as ContentAnyOfInner +from otari._client.models.create_batch_request import CreateBatchRequest as CreateBatchRequest +from otari._client.models.create_budget_request import CreateBudgetRequest as CreateBudgetRequest +from otari._client.models.create_embedding_response import CreateEmbeddingResponse as CreateEmbeddingResponse +from otari._client.models.create_key_request import CreateKeyRequest as CreateKeyRequest +from otari._client.models.create_key_response import CreateKeyResponse as CreateKeyResponse +from otari._client.models.create_user_request import CreateUserRequest as CreateUserRequest +from otari._client.models.emb_embedding import EMBEmbedding as EMBEmbedding +from otari._client.models.emb_usage import EMBUsage as EMBUsage +from otari._client.models.embedding_request import EmbeddingRequest as EmbeddingRequest +from otari._client.models.guardrail_config import GuardrailConfig as GuardrailConfig +from otari._client.models.http_validation_error import HTTPValidationError as HTTPValidationError +from otari._client.models.image_generation_request import ImageGenerationRequest as ImageGenerationRequest +from otari._client.models.input import Input as Input +from otari._client.models.input1 import Input1 as Input1 +from otari._client.models.key_info import KeyInfo as KeyInfo +from otari._client.models.location_inner import LocationInner as LocationInner +from otari._client.models.mr_base64_pdf_source import MRBase64PDFSource as MRBase64PDFSource +from otari._client.models.mr_bash_code_execution_output_block import MRBashCodeExecutionOutputBlock as MRBashCodeExecutionOutputBlock +from otari._client.models.mr_bash_code_execution_result_block import MRBashCodeExecutionResultBlock as MRBashCodeExecutionResultBlock +from otari._client.models.mr_bash_code_execution_tool_result_block import MRBashCodeExecutionToolResultBlock as MRBashCodeExecutionToolResultBlock +from otari._client.models.mr_bash_code_execution_tool_result_error import MRBashCodeExecutionToolResultError as MRBashCodeExecutionToolResultError +from otari._client.models.mr_cache_creation import MRCacheCreation as MRCacheCreation +from otari._client.models.mr_citation_char_location import MRCitationCharLocation as MRCitationCharLocation +from otari._client.models.mr_citation_content_block_location import MRCitationContentBlockLocation as MRCitationContentBlockLocation +from otari._client.models.mr_citation_page_location import MRCitationPageLocation as MRCitationPageLocation +from otari._client.models.mr_citations_config import MRCitationsConfig as MRCitationsConfig +from otari._client.models.mr_citations_search_result_location import MRCitationsSearchResultLocation as MRCitationsSearchResultLocation +from otari._client.models.mr_citations_web_search_result_location import MRCitationsWebSearchResultLocation as MRCitationsWebSearchResultLocation +from otari._client.models.mr_code_execution_output_block import MRCodeExecutionOutputBlock as MRCodeExecutionOutputBlock +from otari._client.models.mr_code_execution_result_block import MRCodeExecutionResultBlock as MRCodeExecutionResultBlock +from otari._client.models.mr_code_execution_tool_result_block import MRCodeExecutionToolResultBlock as MRCodeExecutionToolResultBlock +from otari._client.models.mr_code_execution_tool_result_error import MRCodeExecutionToolResultError as MRCodeExecutionToolResultError +from otari._client.models.mr_container import MRContainer as MRContainer +from otari._client.models.mr_container_upload_block import MRContainerUploadBlock as MRContainerUploadBlock +from otari._client.models.mr_direct_caller import MRDirectCaller as MRDirectCaller +from otari._client.models.mr_document_block import MRDocumentBlock as MRDocumentBlock +from otari._client.models.mr_encrypted_code_execution_result_block import MREncryptedCodeExecutionResultBlock as MREncryptedCodeExecutionResultBlock +from otari._client.models.mr_plain_text_source import MRPlainTextSource as MRPlainTextSource +from otari._client.models.mr_redacted_thinking_block import MRRedactedThinkingBlock as MRRedactedThinkingBlock +from otari._client.models.mr_refusal_stop_details import MRRefusalStopDetails as MRRefusalStopDetails +from otari._client.models.mr_server_tool_caller import MRServerToolCaller as MRServerToolCaller +from otari._client.models.mr_server_tool_caller20260120 import MRServerToolCaller20260120 as MRServerToolCaller20260120 +from otari._client.models.mr_server_tool_usage import MRServerToolUsage as MRServerToolUsage +from otari._client.models.mr_server_tool_use_block import MRServerToolUseBlock as MRServerToolUseBlock +from otari._client.models.mr_text_block import MRTextBlock as MRTextBlock +from otari._client.models.mr_text_block_citations_inner import MRTextBlockCitationsInner as MRTextBlockCitationsInner +from otari._client.models.mr_text_editor_code_execution_create_result_block import MRTextEditorCodeExecutionCreateResultBlock as MRTextEditorCodeExecutionCreateResultBlock +from otari._client.models.mr_text_editor_code_execution_str_replace_result_block import MRTextEditorCodeExecutionStrReplaceResultBlock as MRTextEditorCodeExecutionStrReplaceResultBlock +from otari._client.models.mr_text_editor_code_execution_tool_result_block import MRTextEditorCodeExecutionToolResultBlock as MRTextEditorCodeExecutionToolResultBlock +from otari._client.models.mr_text_editor_code_execution_tool_result_error import MRTextEditorCodeExecutionToolResultError as MRTextEditorCodeExecutionToolResultError +from otari._client.models.mr_text_editor_code_execution_view_result_block import MRTextEditorCodeExecutionViewResultBlock as MRTextEditorCodeExecutionViewResultBlock +from otari._client.models.mr_thinking_block import MRThinkingBlock as MRThinkingBlock +from otari._client.models.mr_tool_reference_block import MRToolReferenceBlock as MRToolReferenceBlock +from otari._client.models.mr_tool_search_tool_result_block import MRToolSearchToolResultBlock as MRToolSearchToolResultBlock +from otari._client.models.mr_tool_search_tool_result_error import MRToolSearchToolResultError as MRToolSearchToolResultError +from otari._client.models.mr_tool_search_tool_search_result_block import MRToolSearchToolSearchResultBlock as MRToolSearchToolSearchResultBlock +from otari._client.models.mr_tool_use_block import MRToolUseBlock as MRToolUseBlock +from otari._client.models.mr_usage import MRUsage as MRUsage +from otari._client.models.mr_web_fetch_block import MRWebFetchBlock as MRWebFetchBlock +from otari._client.models.mr_web_fetch_tool_result_block import MRWebFetchToolResultBlock as MRWebFetchToolResultBlock +from otari._client.models.mr_web_fetch_tool_result_error_block import MRWebFetchToolResultErrorBlock as MRWebFetchToolResultErrorBlock +from otari._client.models.mr_web_search_result_block import MRWebSearchResultBlock as MRWebSearchResultBlock +from otari._client.models.mr_web_search_tool_result_block import MRWebSearchToolResultBlock as MRWebSearchToolResultBlock +from otari._client.models.mr_web_search_tool_result_error import MRWebSearchToolResultError as MRWebSearchToolResultError +from otari._client.models.msg_audio import MSGAudio as MSGAudio +from otari._client.models.msg_chat_completion_assistant_message_param import MSGChatCompletionAssistantMessageParam as MSGChatCompletionAssistantMessageParam +from otari._client.models.msg_chat_completion_content_part_image_param import MSGChatCompletionContentPartImageParam as MSGChatCompletionContentPartImageParam +from otari._client.models.msg_chat_completion_content_part_input_audio_param import MSGChatCompletionContentPartInputAudioParam as MSGChatCompletionContentPartInputAudioParam +from otari._client.models.msg_chat_completion_content_part_refusal_param import MSGChatCompletionContentPartRefusalParam as MSGChatCompletionContentPartRefusalParam +from otari._client.models.msg_chat_completion_content_part_text_param import MSGChatCompletionContentPartTextParam as MSGChatCompletionContentPartTextParam +from otari._client.models.msg_chat_completion_developer_message_param import MSGChatCompletionDeveloperMessageParam as MSGChatCompletionDeveloperMessageParam +from otari._client.models.msg_chat_completion_function_message_param import MSGChatCompletionFunctionMessageParam as MSGChatCompletionFunctionMessageParam +from otari._client.models.msg_chat_completion_message_custom_tool_call_param import MSGChatCompletionMessageCustomToolCallParam as MSGChatCompletionMessageCustomToolCallParam +from otari._client.models.msg_chat_completion_message_function_tool_call_param import MSGChatCompletionMessageFunctionToolCallParam as MSGChatCompletionMessageFunctionToolCallParam +from otari._client.models.msg_chat_completion_system_message_param import MSGChatCompletionSystemMessageParam as MSGChatCompletionSystemMessageParam +from otari._client.models.msg_chat_completion_tool_message_param import MSGChatCompletionToolMessageParam as MSGChatCompletionToolMessageParam +from otari._client.models.msg_chat_completion_user_message_param import MSGChatCompletionUserMessageParam as MSGChatCompletionUserMessageParam +from otari._client.models.msg_custom import MSGCustom as MSGCustom +from otari._client.models.msg_file import MSGFile as MSGFile +from otari._client.models.msg_file_file import MSGFileFile as MSGFileFile +from otari._client.models.msg_function import MSGFunction as MSGFunction +from otari._client.models.msg_function_call import MSGFunctionCall as MSGFunctionCall +from otari._client.models.msg_image_url import MSGImageURL as MSGImageURL +from otari._client.models.msg_input_audio import MSGInputAudio as MSGInputAudio +from otari._client.models.mcp_server_config import McpServerConfig as McpServerConfig +from otari._client.models.message_response import MessageResponse as MessageResponse +from otari._client.models.messages_request import MessagesRequest as MessagesRequest +from otari._client.models.model import Model as Model +from otari._client.models.model_list_response import ModelListResponse as ModelListResponse +from otari._client.models.model_object import ModelObject as ModelObject +from otari._client.models.model_pricing_info import ModelPricingInfo as ModelPricingInfo +from otari._client.models.moderation_request import ModerationRequest as ModerationRequest +from otari._client.models.moderation_response import ModerationResponse as ModerationResponse +from otari._client.models.moderation_result import ModerationResult as ModerationResult +from otari._client.models.pricing_response import PricingResponse as PricingResponse +from otari._client.models.rr_rerank_meta import RRRerankMeta as RRRerankMeta +from otari._client.models.rr_rerank_result import RRRerankResult as RRRerankResult +from otari._client.models.rr_rerank_usage import RRRerankUsage as RRRerankUsage +from otari._client.models.rerank_request import RerankRequest as RerankRequest +from otari._client.models.rerank_response import RerankResponse as RerankResponse +from otari._client.models.responses_request import ResponsesRequest as ResponsesRequest +from otari._client.models.set_pricing_request import SetPricingRequest as SetPricingRequest +from otari._client.models.source import Source as Source +from otari._client.models.system import System as System +from otari._client.models.tool_calls_inner import ToolCallsInner as ToolCallsInner +from otari._client.models.tool_choice import ToolChoice as ToolChoice +from otari._client.models.update_budget_request import UpdateBudgetRequest as UpdateBudgetRequest +from otari._client.models.update_key_request import UpdateKeyRequest as UpdateKeyRequest +from otari._client.models.update_user_request import UpdateUserRequest as UpdateUserRequest +from otari._client.models.usage_entry import UsageEntry as UsageEntry +from otari._client.models.usage_log_response import UsageLogResponse as UsageLogResponse +from otari._client.models.user_response import UserResponse as UserResponse +from otari._client.models.validation_error import ValidationError as ValidationError + diff --git a/src/otari/_client/api/__init__.py b/src/otari/_client/api/__init__.py new file mode 100644 index 0000000..460b2a7 --- /dev/null +++ b/src/otari/_client/api/__init__.py @@ -0,0 +1,20 @@ +# flake8: noqa + +# import apis into api package +from otari._client.api.audio_api import AudioApi +from otari._client.api.batches_api import BatchesApi +from otari._client.api.budgets_api import BudgetsApi +from otari._client.api.chat_api import ChatApi +from otari._client.api.embeddings_api import EmbeddingsApi +from otari._client.api.health_api import HealthApi +from otari._client.api.images_api import ImagesApi +from otari._client.api.keys_api import KeysApi +from otari._client.api.messages_api import MessagesApi +from otari._client.api.models_api import ModelsApi +from otari._client.api.moderations_api import ModerationsApi +from otari._client.api.pricing_api import PricingApi +from otari._client.api.rerank_api import RerankApi +from otari._client.api.responses_api import ResponsesApi +from otari._client.api.usage_api import UsageApi +from otari._client.api.users_api import UsersApi + diff --git a/src/otari/_client/api/audio_api.py b/src/otari/_client/api/audio_api.py new file mode 100644 index 0000000..2418145 --- /dev/null +++ b/src/otari/_client/api/audio_api.py @@ -0,0 +1,685 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictFloat, StrictInt, StrictStr +from typing import Any, Optional, Union +from otari._client.models.audio_speech_request import AudioSpeechRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class AudioApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_speech_v1_audio_speech_post( + self, + audio_speech_request: AudioSpeechRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Create Speech + + OpenAI-compatible audio speech (TTS) endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param audio_speech_request: (required) + :type audio_speech_request: AudioSpeechRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_speech_v1_audio_speech_post_serialize( + audio_speech_request=audio_speech_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_speech_v1_audio_speech_post_with_http_info( + self, + audio_speech_request: AudioSpeechRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Create Speech + + OpenAI-compatible audio speech (TTS) endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param audio_speech_request: (required) + :type audio_speech_request: AudioSpeechRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_speech_v1_audio_speech_post_serialize( + audio_speech_request=audio_speech_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_speech_v1_audio_speech_post_without_preload_content( + self, + audio_speech_request: AudioSpeechRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Speech + + OpenAI-compatible audio speech (TTS) endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param audio_speech_request: (required) + :type audio_speech_request: AudioSpeechRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_speech_v1_audio_speech_post_serialize( + audio_speech_request=audio_speech_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_speech_v1_audio_speech_post_serialize( + self, + audio_speech_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if audio_speech_request is not None: + _body_params = audio_speech_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'audio/L16', + 'audio/aac', + 'audio/flac', + 'audio/mpeg', + 'audio/opus', + 'audio/wav' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/audio/speech', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def create_transcription_v1_audio_transcriptions_post( + self, + file: StrictStr, + model: StrictStr, + language: Optional[StrictStr] = None, + prompt: Optional[StrictStr] = None, + response_format: Optional[StrictStr] = None, + temperature: Optional[Union[StrictFloat, StrictInt]] = None, + user: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Create Transcription + + OpenAI-compatible audio transcription endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param file: (required) + :type file: str + :param model: (required) + :type model: str + :param language: + :type language: str + :param prompt: + :type prompt: str + :param response_format: + :type response_format: str + :param temperature: + :type temperature: float + :param user: + :type user: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_transcription_v1_audio_transcriptions_post_serialize( + file=file, + model=model, + language=language, + prompt=prompt, + response_format=response_format, + temperature=temperature, + user=user, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_transcription_v1_audio_transcriptions_post_with_http_info( + self, + file: StrictStr, + model: StrictStr, + language: Optional[StrictStr] = None, + prompt: Optional[StrictStr] = None, + response_format: Optional[StrictStr] = None, + temperature: Optional[Union[StrictFloat, StrictInt]] = None, + user: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Create Transcription + + OpenAI-compatible audio transcription endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param file: (required) + :type file: str + :param model: (required) + :type model: str + :param language: + :type language: str + :param prompt: + :type prompt: str + :param response_format: + :type response_format: str + :param temperature: + :type temperature: float + :param user: + :type user: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_transcription_v1_audio_transcriptions_post_serialize( + file=file, + model=model, + language=language, + prompt=prompt, + response_format=response_format, + temperature=temperature, + user=user, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_transcription_v1_audio_transcriptions_post_without_preload_content( + self, + file: StrictStr, + model: StrictStr, + language: Optional[StrictStr] = None, + prompt: Optional[StrictStr] = None, + response_format: Optional[StrictStr] = None, + temperature: Optional[Union[StrictFloat, StrictInt]] = None, + user: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Transcription + + OpenAI-compatible audio transcription endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param file: (required) + :type file: str + :param model: (required) + :type model: str + :param language: + :type language: str + :param prompt: + :type prompt: str + :param response_format: + :type response_format: str + :param temperature: + :type temperature: float + :param user: + :type user: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_transcription_v1_audio_transcriptions_post_serialize( + file=file, + model=model, + language=language, + prompt=prompt, + response_format=response_format, + temperature=temperature, + user=user, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_transcription_v1_audio_transcriptions_post_serialize( + self, + file, + model, + language, + prompt, + response_format, + temperature, + user, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + if file is not None: + _form_params.append(('file', file)) + if language is not None: + _form_params.append(('language', language)) + if model is not None: + _form_params.append(('model', model)) + if prompt is not None: + _form_params.append(('prompt', prompt)) + if response_format is not None: + _form_params.append(('response_format', response_format)) + if temperature is not None: + _form_params.append(('temperature', temperature)) + if user is not None: + _form_params.append(('user', user)) + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'multipart/form-data' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/audio/transcriptions', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/batches_api.py b/src/otari/_client/api/batches_api.py new file mode 100644 index 0000000..64614c8 --- /dev/null +++ b/src/otari/_client/api/batches_api.py @@ -0,0 +1,1458 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictInt, StrictStr +from typing import Any, Optional +from otari._client.models.create_batch_request import CreateBatchRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class BatchesApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def cancel_batch_v1_batches_batch_id_cancel_post( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Cancel Batch + + Cancel a batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._cancel_batch_v1_batches_batch_id_cancel_post_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def cancel_batch_v1_batches_batch_id_cancel_post_with_http_info( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Cancel Batch + + Cancel a batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._cancel_batch_v1_batches_batch_id_cancel_post_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def cancel_batch_v1_batches_batch_id_cancel_post_without_preload_content( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Cancel Batch + + Cancel a batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._cancel_batch_v1_batches_batch_id_cancel_post_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _cancel_batch_v1_batches_batch_id_cancel_post_serialize( + self, + batch_id, + provider, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if batch_id is not None: + _path_params['batch_id'] = batch_id + # process the query parameters + if provider is not None: + + _query_params.append(('provider', provider)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/batches/{batch_id}/cancel', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def create_batch_v1_batches_post( + self, + create_batch_request: CreateBatchRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Create Batch + + Create a batch of LLM requests for asynchronous processing. + + :param create_batch_request: (required) + :type create_batch_request: CreateBatchRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_batch_v1_batches_post_serialize( + create_batch_request=create_batch_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_batch_v1_batches_post_with_http_info( + self, + create_batch_request: CreateBatchRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Create Batch + + Create a batch of LLM requests for asynchronous processing. + + :param create_batch_request: (required) + :type create_batch_request: CreateBatchRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_batch_v1_batches_post_serialize( + create_batch_request=create_batch_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_batch_v1_batches_post_without_preload_content( + self, + create_batch_request: CreateBatchRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Batch + + Create a batch of LLM requests for asynchronous processing. + + :param create_batch_request: (required) + :type create_batch_request: CreateBatchRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_batch_v1_batches_post_serialize( + create_batch_request=create_batch_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_batch_v1_batches_post_serialize( + self, + create_batch_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_batch_request is not None: + _body_params = create_batch_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/batches', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_batches_v1_batches_get( + self, + provider: StrictStr, + after: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """List Batches + + List batches for a provider. + + :param provider: (required) + :type provider: str + :param after: + :type after: str + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_batches_v1_batches_get_serialize( + provider=provider, + after=after, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_batches_v1_batches_get_with_http_info( + self, + provider: StrictStr, + after: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """List Batches + + List batches for a provider. + + :param provider: (required) + :type provider: str + :param after: + :type after: str + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_batches_v1_batches_get_serialize( + provider=provider, + after=after, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_batches_v1_batches_get_without_preload_content( + self, + provider: StrictStr, + after: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Batches + + List batches for a provider. + + :param provider: (required) + :type provider: str + :param after: + :type after: str + :param limit: + :type limit: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_batches_v1_batches_get_serialize( + provider=provider, + after=after, + limit=limit, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_batches_v1_batches_get_serialize( + self, + provider, + after, + limit, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if provider is not None: + + _query_params.append(('provider', provider)) + + if after is not None: + + _query_params.append(('after', after)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/batches', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def retrieve_batch_results_v1_batches_batch_id_results_get( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Retrieve Batch Results + + Retrieve the results of a completed batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._retrieve_batch_results_v1_batches_batch_id_results_get_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '409': None, + '422': "HTTPValidationError", + '502': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def retrieve_batch_results_v1_batches_batch_id_results_get_with_http_info( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Retrieve Batch Results + + Retrieve the results of a completed batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._retrieve_batch_results_v1_batches_batch_id_results_get_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '409': None, + '422': "HTTPValidationError", + '502': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def retrieve_batch_results_v1_batches_batch_id_results_get_without_preload_content( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Retrieve Batch Results + + Retrieve the results of a completed batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._retrieve_batch_results_v1_batches_batch_id_results_get_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '409': None, + '422': "HTTPValidationError", + '502': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _retrieve_batch_results_v1_batches_batch_id_results_get_serialize( + self, + batch_id, + provider, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if batch_id is not None: + _path_params['batch_id'] = batch_id + # process the query parameters + if provider is not None: + + _query_params.append(('provider', provider)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/batches/{batch_id}/results', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def retrieve_batch_v1_batches_batch_id_get( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Retrieve Batch + + Retrieve the status of a batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._retrieve_batch_v1_batches_batch_id_get_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def retrieve_batch_v1_batches_batch_id_get_with_http_info( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Retrieve Batch + + Retrieve the status of a batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._retrieve_batch_v1_batches_batch_id_get_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def retrieve_batch_v1_batches_batch_id_get_without_preload_content( + self, + batch_id: StrictStr, + provider: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Retrieve Batch + + Retrieve the status of a batch. + + :param batch_id: (required) + :type batch_id: str + :param provider: (required) + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._retrieve_batch_v1_batches_batch_id_get_serialize( + batch_id=batch_id, + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _retrieve_batch_v1_batches_batch_id_get_serialize( + self, + batch_id, + provider, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if batch_id is not None: + _path_params['batch_id'] = batch_id + # process the query parameters + if provider is not None: + + _query_params.append(('provider', provider)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/batches/{batch_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_control_plane/api/budgets_api.py b/src/otari/_client/api/budgets_api.py similarity index 99% rename from src/otari/_control_plane/api/budgets_api.py rename to src/otari/_client/api/budgets_api.py index a1590cb..a78e6b0 100644 --- a/src/otari/_control_plane/api/budgets_api.py +++ b/src/otari/_client/api/budgets_api.py @@ -18,13 +18,13 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari._control_plane.models.budget_response import BudgetResponse -from otari._control_plane.models.create_budget_request import CreateBudgetRequest -from otari._control_plane.models.update_budget_request import UpdateBudgetRequest +from otari._client.models.budget_response import BudgetResponse +from otari._client.models.create_budget_request import CreateBudgetRequest +from otari._client.models.update_budget_request import UpdateBudgetRequest -from otari._control_plane.api_client import ApiClient, RequestSerialized -from otari._control_plane.api_response import ApiResponse -from otari._control_plane.rest import RESTResponseType +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType class BudgetsApi: diff --git a/src/otari/_client/api/chat_api.py b/src/otari/_client/api/chat_api.py new file mode 100644 index 0000000..8e4b9aa --- /dev/null +++ b/src/otari/_client/api/chat_api.py @@ -0,0 +1,312 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from otari._client.models.chat_completion import ChatCompletion +from otari._client.models.chat_completion_request import ChatCompletionRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class ChatApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def chat_completions_v1_chat_completions_post( + self, + chat_completion_request: ChatCompletionRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ChatCompletion: + """Chat Completions + + OpenAI-compatible chat completions endpoint. Supports both streaming and non-streaming responses. Handles reasoning content from otari providers. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param chat_completion_request: (required) + :type chat_completion_request: ChatCompletionRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._chat_completions_v1_chat_completions_post_serialize( + chat_completion_request=chat_completion_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ChatCompletion", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def chat_completions_v1_chat_completions_post_with_http_info( + self, + chat_completion_request: ChatCompletionRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ChatCompletion]: + """Chat Completions + + OpenAI-compatible chat completions endpoint. Supports both streaming and non-streaming responses. Handles reasoning content from otari providers. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param chat_completion_request: (required) + :type chat_completion_request: ChatCompletionRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._chat_completions_v1_chat_completions_post_serialize( + chat_completion_request=chat_completion_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ChatCompletion", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def chat_completions_v1_chat_completions_post_without_preload_content( + self, + chat_completion_request: ChatCompletionRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Chat Completions + + OpenAI-compatible chat completions endpoint. Supports both streaming and non-streaming responses. Handles reasoning content from otari providers. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param chat_completion_request: (required) + :type chat_completion_request: ChatCompletionRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._chat_completions_v1_chat_completions_post_serialize( + chat_completion_request=chat_completion_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ChatCompletion", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _chat_completions_v1_chat_completions_post_serialize( + self, + chat_completion_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if chat_completion_request is not None: + _body_params = chat_completion_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/chat/completions', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/embeddings_api.py b/src/otari/_client/api/embeddings_api.py new file mode 100644 index 0000000..dc1879a --- /dev/null +++ b/src/otari/_client/api/embeddings_api.py @@ -0,0 +1,312 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from otari._client.models.create_embedding_response import CreateEmbeddingResponse +from otari._client.models.embedding_request import EmbeddingRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class EmbeddingsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_embedding_v1_embeddings_post( + self, + embedding_request: EmbeddingRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> CreateEmbeddingResponse: + """Create Embedding + + OpenAI-compatible embeddings endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param embedding_request: (required) + :type embedding_request: EmbeddingRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_embedding_v1_embeddings_post_serialize( + embedding_request=embedding_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "CreateEmbeddingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_embedding_v1_embeddings_post_with_http_info( + self, + embedding_request: EmbeddingRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[CreateEmbeddingResponse]: + """Create Embedding + + OpenAI-compatible embeddings endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param embedding_request: (required) + :type embedding_request: EmbeddingRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_embedding_v1_embeddings_post_serialize( + embedding_request=embedding_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "CreateEmbeddingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_embedding_v1_embeddings_post_without_preload_content( + self, + embedding_request: EmbeddingRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Embedding + + OpenAI-compatible embeddings endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param embedding_request: (required) + :type embedding_request: EmbeddingRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_embedding_v1_embeddings_post_serialize( + embedding_request=embedding_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "CreateEmbeddingResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_embedding_v1_embeddings_post_serialize( + self, + embedding_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if embedding_request is not None: + _body_params = embedding_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/embeddings', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/health_api.py b/src/otari/_client/api/health_api.py new file mode 100644 index 0000000..4248817 --- /dev/null +++ b/src/otari/_client/api/health_api.py @@ -0,0 +1,771 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictStr +from typing import Any, Dict + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class HealthApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def health_check_health_get( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> Dict[str, str]: + """Health Check + + General health check endpoint. Returns basic health status. For infrastructure monitoring, use /health/readiness or /health/liveness instead. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_check_health_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, str]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def health_check_health_get_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[Dict[str, str]]: + """Health Check + + General health check endpoint. Returns basic health status. For infrastructure monitoring, use /health/readiness or /health/liveness instead. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_check_health_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, str]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def health_check_health_get_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Health Check + + General health check endpoint. Returns basic health status. For infrastructure monitoring, use /health/readiness or /health/liveness instead. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_check_health_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, str]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _health_check_health_get_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/health', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def health_liveness_health_liveness_get( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> str: + """Health Liveness + + Liveness probe endpoint. Simple check to verify the process is alive and responding. Used by Kubernetes/container orchestrators for liveness probes. Returns: Plain text \"I'm alive!\" message + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_liveness_health_liveness_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "str", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def health_liveness_health_liveness_get_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[str]: + """Health Liveness + + Liveness probe endpoint. Simple check to verify the process is alive and responding. Used by Kubernetes/container orchestrators for liveness probes. Returns: Plain text \"I'm alive!\" message + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_liveness_health_liveness_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "str", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def health_liveness_health_liveness_get_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Health Liveness + + Liveness probe endpoint. Simple check to verify the process is alive and responding. Used by Kubernetes/container orchestrators for liveness probes. Returns: Plain text \"I'm alive!\" message + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_liveness_health_liveness_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "str", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _health_liveness_health_liveness_get_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/health/liveness', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def health_readiness_health_readiness_get( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> Dict[str, object]: + """Health Readiness + + Readiness probe endpoint. Checks if the gateway is ready to serve requests by validating: - Database connectivity - Service availability Used by Kubernetes/container orchestrators for readiness probes. Returns HTTP 503 if any dependency is unavailable. Returns: dict: Status object with health details Raises: HTTPException: 503 if service is not ready + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_readiness_health_readiness_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def health_readiness_health_readiness_get_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[Dict[str, object]]: + """Health Readiness + + Readiness probe endpoint. Checks if the gateway is ready to serve requests by validating: - Database connectivity - Service availability Used by Kubernetes/container orchestrators for readiness probes. Returns HTTP 503 if any dependency is unavailable. Returns: dict: Status object with health details Raises: HTTPException: 503 if service is not ready + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_readiness_health_readiness_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def health_readiness_health_readiness_get_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Health Readiness + + Readiness probe endpoint. Checks if the gateway is ready to serve requests by validating: - Database connectivity - Service availability Used by Kubernetes/container orchestrators for readiness probes. Returns HTTP 503 if any dependency is unavailable. Returns: dict: Status object with health details Raises: HTTPException: 503 if service is not ready + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._health_readiness_health_readiness_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _health_readiness_health_readiness_get_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/health/readiness', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/images_api.py b/src/otari/_client/api/images_api.py new file mode 100644 index 0000000..f5b26ab --- /dev/null +++ b/src/otari/_client/api/images_api.py @@ -0,0 +1,312 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from typing import Any +from otari._client.models.image_generation_request import ImageGenerationRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class ImagesApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_image_v1_images_generations_post( + self, + image_generation_request: ImageGenerationRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Create Image + + OpenAI-compatible image generation endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param image_generation_request: (required) + :type image_generation_request: ImageGenerationRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_image_v1_images_generations_post_serialize( + image_generation_request=image_generation_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_image_v1_images_generations_post_with_http_info( + self, + image_generation_request: ImageGenerationRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Create Image + + OpenAI-compatible image generation endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param image_generation_request: (required) + :type image_generation_request: ImageGenerationRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_image_v1_images_generations_post_serialize( + image_generation_request=image_generation_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_image_v1_images_generations_post_without_preload_content( + self, + image_generation_request: ImageGenerationRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Image + + OpenAI-compatible image generation endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param image_generation_request: (required) + :type image_generation_request: ImageGenerationRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_image_v1_images_generations_post_serialize( + image_generation_request=image_generation_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_image_v1_images_generations_post_serialize( + self, + image_generation_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if image_generation_request is not None: + _body_params = image_generation_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/images/generations', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_control_plane/api/keys_api.py b/src/otari/_client/api/keys_api.py similarity index 99% rename from src/otari/_control_plane/api/keys_api.py rename to src/otari/_client/api/keys_api.py index e95679b..1a9432b 100644 --- a/src/otari/_control_plane/api/keys_api.py +++ b/src/otari/_client/api/keys_api.py @@ -18,14 +18,14 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari._control_plane.models.create_key_request import CreateKeyRequest -from otari._control_plane.models.create_key_response import CreateKeyResponse -from otari._control_plane.models.key_info import KeyInfo -from otari._control_plane.models.update_key_request import UpdateKeyRequest - -from otari._control_plane.api_client import ApiClient, RequestSerialized -from otari._control_plane.api_response import ApiResponse -from otari._control_plane.rest import RESTResponseType +from otari._client.models.create_key_request import CreateKeyRequest +from otari._client.models.create_key_response import CreateKeyResponse +from otari._client.models.key_info import KeyInfo +from otari._client.models.update_key_request import UpdateKeyRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType class KeysApi: diff --git a/src/otari/_client/api/messages_api.py b/src/otari/_client/api/messages_api.py new file mode 100644 index 0000000..6b65bff --- /dev/null +++ b/src/otari/_client/api/messages_api.py @@ -0,0 +1,312 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from otari._client.models.message_response import MessageResponse +from otari._client.models.messages_request import MessagesRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class MessagesApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_message_v1_messages_post( + self, + messages_request: MessagesRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> MessageResponse: + """Create Message + + Anthropic Messages API-compatible endpoint. Supports MCP tool-use loops, sandboxed code execution, and SearXNG web_search in both standalone mode and platform mode. Platform-mode requests resolve credentials via the platform service and (for non-tool-loop requests) get multi-attempt fallback across the resolved route. Tool-loop requests collapse to a single attempt — once ``on_first_response`` lock-in plumbing lands across the codebase, a follow-up will enable pre-lock-in fallback for tool-loop requests too. + + :param messages_request: (required) + :type messages_request: MessagesRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_message_v1_messages_post_serialize( + messages_request=messages_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MessageResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_message_v1_messages_post_with_http_info( + self, + messages_request: MessagesRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[MessageResponse]: + """Create Message + + Anthropic Messages API-compatible endpoint. Supports MCP tool-use loops, sandboxed code execution, and SearXNG web_search in both standalone mode and platform mode. Platform-mode requests resolve credentials via the platform service and (for non-tool-loop requests) get multi-attempt fallback across the resolved route. Tool-loop requests collapse to a single attempt — once ``on_first_response`` lock-in plumbing lands across the codebase, a follow-up will enable pre-lock-in fallback for tool-loop requests too. + + :param messages_request: (required) + :type messages_request: MessagesRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_message_v1_messages_post_serialize( + messages_request=messages_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MessageResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_message_v1_messages_post_without_preload_content( + self, + messages_request: MessagesRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Message + + Anthropic Messages API-compatible endpoint. Supports MCP tool-use loops, sandboxed code execution, and SearXNG web_search in both standalone mode and platform mode. Platform-mode requests resolve credentials via the platform service and (for non-tool-loop requests) get multi-attempt fallback across the resolved route. Tool-loop requests collapse to a single attempt — once ``on_first_response`` lock-in plumbing lands across the codebase, a follow-up will enable pre-lock-in fallback for tool-loop requests too. + + :param messages_request: (required) + :type messages_request: MessagesRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_message_v1_messages_post_serialize( + messages_request=messages_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MessageResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_message_v1_messages_post_serialize( + self, + messages_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if messages_request is not None: + _body_params = messages_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/messages', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/models_api.py b/src/otari/_client/api/models_api.py new file mode 100644 index 0000000..6b43e30 --- /dev/null +++ b/src/otari/_client/api/models_api.py @@ -0,0 +1,567 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import Optional +from typing_extensions import Annotated +from otari._client.models.model_list_response import ModelListResponse +from otari._client.models.model_object import ModelObject + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class ModelsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def get_model_v1_models_model_id_get( + self, + model_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ModelObject: + """Get Model + + Get details for a specific model. + + :param model_id: (required) + :type model_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_model_v1_models_model_id_get_serialize( + model_id=model_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModelObject", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_model_v1_models_model_id_get_with_http_info( + self, + model_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ModelObject]: + """Get Model + + Get details for a specific model. + + :param model_id: (required) + :type model_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_model_v1_models_model_id_get_serialize( + model_id=model_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModelObject", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_model_v1_models_model_id_get_without_preload_content( + self, + model_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Model + + Get details for a specific model. + + :param model_id: (required) + :type model_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_model_v1_models_model_id_get_serialize( + model_id=model_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModelObject", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_model_v1_models_model_id_get_serialize( + self, + model_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if model_id is not None: + _path_params['model_id'] = model_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/models/{model_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_models_v1_models_get( + self, + provider: Annotated[Optional[StrictStr], Field(description="Filter models by provider name")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ModelListResponse: + """List Models + + List all available models. Returns models auto-discovered from configured providers, enriched with pricing data from the model_pricing table when available. Models that only exist in the pricing table are also included for backward compatibility. + + :param provider: Filter models by provider name + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_models_v1_models_get_serialize( + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModelListResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_models_v1_models_get_with_http_info( + self, + provider: Annotated[Optional[StrictStr], Field(description="Filter models by provider name")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ModelListResponse]: + """List Models + + List all available models. Returns models auto-discovered from configured providers, enriched with pricing data from the model_pricing table when available. Models that only exist in the pricing table are also included for backward compatibility. + + :param provider: Filter models by provider name + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_models_v1_models_get_serialize( + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModelListResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_models_v1_models_get_without_preload_content( + self, + provider: Annotated[Optional[StrictStr], Field(description="Filter models by provider name")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Models + + List all available models. Returns models auto-discovered from configured providers, enriched with pricing data from the model_pricing table when available. Models that only exist in the pricing table are also included for backward compatibility. + + :param provider: Filter models by provider name + :type provider: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_models_v1_models_get_serialize( + provider=provider, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModelListResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_models_v1_models_get_serialize( + self, + provider, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if provider is not None: + + _query_params.append(('provider', provider)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/models', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/moderations_api.py b/src/otari/_client/api/moderations_api.py new file mode 100644 index 0000000..e8e0cee --- /dev/null +++ b/src/otari/_client/api/moderations_api.py @@ -0,0 +1,331 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictBool +from typing import Optional +from otari._client.models.moderation_request import ModerationRequest +from otari._client.models.moderation_response import ModerationResponse + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class ModerationsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_moderation_v1_moderations_post( + self, + moderation_request: ModerationRequest, + include_raw: Optional[StrictBool] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ModerationResponse: + """Create Moderation + + OpenAI-compatible moderations endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param moderation_request: (required) + :type moderation_request: ModerationRequest + :param include_raw: + :type include_raw: bool + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_moderation_v1_moderations_post_serialize( + moderation_request=moderation_request, + include_raw=include_raw, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModerationResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_moderation_v1_moderations_post_with_http_info( + self, + moderation_request: ModerationRequest, + include_raw: Optional[StrictBool] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ModerationResponse]: + """Create Moderation + + OpenAI-compatible moderations endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param moderation_request: (required) + :type moderation_request: ModerationRequest + :param include_raw: + :type include_raw: bool + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_moderation_v1_moderations_post_serialize( + moderation_request=moderation_request, + include_raw=include_raw, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModerationResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_moderation_v1_moderations_post_without_preload_content( + self, + moderation_request: ModerationRequest, + include_raw: Optional[StrictBool] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Moderation + + OpenAI-compatible moderations endpoint. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param moderation_request: (required) + :type moderation_request: ModerationRequest + :param include_raw: + :type include_raw: bool + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_moderation_v1_moderations_post_serialize( + moderation_request=moderation_request, + include_raw=include_raw, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ModerationResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_moderation_v1_moderations_post_serialize( + self, + moderation_request, + include_raw, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + if include_raw is not None: + + _query_params.append(('include_raw', include_raw)) + + # process the header parameters + # process the form parameters + # process the body parameter + if moderation_request is not None: + _body_params = moderation_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/moderations', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_control_plane/api/pricing_api.py b/src/otari/_client/api/pricing_api.py similarity index 99% rename from src/otari/_control_plane/api/pricing_api.py rename to src/otari/_client/api/pricing_api.py index 73ec780..a735ba8 100644 --- a/src/otari/_control_plane/api/pricing_api.py +++ b/src/otari/_client/api/pricing_api.py @@ -19,12 +19,12 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari._control_plane.models.pricing_response import PricingResponse -from otari._control_plane.models.set_pricing_request import SetPricingRequest +from otari._client.models.pricing_response import PricingResponse +from otari._client.models.set_pricing_request import SetPricingRequest -from otari._control_plane.api_client import ApiClient, RequestSerialized -from otari._control_plane.api_response import ApiResponse -from otari._control_plane.rest import RESTResponseType +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType class PricingApi: diff --git a/src/otari/_client/api/rerank_api.py b/src/otari/_client/api/rerank_api.py new file mode 100644 index 0000000..78cf4df --- /dev/null +++ b/src/otari/_client/api/rerank_api.py @@ -0,0 +1,312 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from otari._client.models.rerank_request import RerankRequest +from otari._client.models.rerank_response import RerankResponse + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class RerankApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_rerank_v1_rerank_post( + self, + rerank_request: RerankRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RerankResponse: + """Create Rerank + + Rerank documents by relevance to a query. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param rerank_request: (required) + :type rerank_request: RerankRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_rerank_v1_rerank_post_serialize( + rerank_request=rerank_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "RerankResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_rerank_v1_rerank_post_with_http_info( + self, + rerank_request: RerankRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[RerankResponse]: + """Create Rerank + + Rerank documents by relevance to a query. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param rerank_request: (required) + :type rerank_request: RerankRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_rerank_v1_rerank_post_serialize( + rerank_request=rerank_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "RerankResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_rerank_v1_rerank_post_without_preload_content( + self, + rerank_request: RerankRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Rerank + + Rerank documents by relevance to a query. Authentication modes: - Master key + user field: Use specified user (must exist) - API key + user field: Use specified user (must exist) - API key without user field: Use virtual user created with API key + + :param rerank_request: (required) + :type rerank_request: RerankRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_rerank_v1_rerank_post_serialize( + rerank_request=rerank_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "RerankResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_rerank_v1_rerank_post_serialize( + self, + rerank_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if rerank_request is not None: + _body_params = rerank_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/rerank', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/api/responses_api.py b/src/otari/_client/api/responses_api.py new file mode 100644 index 0000000..36f6a1c --- /dev/null +++ b/src/otari/_client/api/responses_api.py @@ -0,0 +1,312 @@ +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from typing import Any +from otari._client.models.responses_request import ResponsesRequest + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class ResponsesApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_response_v1_responses_post( + self, + responses_request: ResponsesRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Create Response + + OpenAI-compatible Responses endpoint. Supports MCP tool-use loops, sandboxed code execution, and SearXNG web_search in both standalone mode and platform mode. Platform-mode requests resolve credentials via the platform service and (for non-tool-loop requests) get multi-attempt fallback across the resolved route. Tool-loop requests collapse to a single attempt — once ``on_first_response`` lock-in plumbing lands across the codebase, a follow-up will enable pre-lock-in fallback for tool-loop requests too. + + :param responses_request: (required) + :type responses_request: ResponsesRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_response_v1_responses_post_serialize( + responses_request=responses_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_response_v1_responses_post_with_http_info( + self, + responses_request: ResponsesRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Create Response + + OpenAI-compatible Responses endpoint. Supports MCP tool-use loops, sandboxed code execution, and SearXNG web_search in both standalone mode and platform mode. Platform-mode requests resolve credentials via the platform service and (for non-tool-loop requests) get multi-attempt fallback across the resolved route. Tool-loop requests collapse to a single attempt — once ``on_first_response`` lock-in plumbing lands across the codebase, a follow-up will enable pre-lock-in fallback for tool-loop requests too. + + :param responses_request: (required) + :type responses_request: ResponsesRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_response_v1_responses_post_serialize( + responses_request=responses_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_response_v1_responses_post_without_preload_content( + self, + responses_request: ResponsesRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Response + + OpenAI-compatible Responses endpoint. Supports MCP tool-use loops, sandboxed code execution, and SearXNG web_search in both standalone mode and platform mode. Platform-mode requests resolve credentials via the platform service and (for non-tool-loop requests) get multi-attempt fallback across the resolved route. Tool-loop requests collapse to a single attempt — once ``on_first_response`` lock-in plumbing lands across the codebase, a follow-up will enable pre-lock-in fallback for tool-loop requests too. + + :param responses_request: (required) + :type responses_request: ResponsesRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_response_v1_responses_post_serialize( + responses_request=responses_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_response_v1_responses_post_serialize( + self, + responses_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if responses_request is not None: + _body_params = responses_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/responses', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_control_plane/api/usage_api.py b/src/otari/_client/api/usage_api.py similarity index 98% rename from src/otari/_control_plane/api/usage_api.py rename to src/otari/_client/api/usage_api.py index d811abf..7782989 100644 --- a/src/otari/_control_plane/api/usage_api.py +++ b/src/otari/_client/api/usage_api.py @@ -19,11 +19,11 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari._control_plane.models.usage_entry import UsageEntry +from otari._client.models.usage_entry import UsageEntry -from otari._control_plane.api_client import ApiClient, RequestSerialized -from otari._control_plane.api_response import ApiResponse -from otari._control_plane.rest import RESTResponseType +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType class UsageApi: diff --git a/src/otari/_control_plane/api/users_api.py b/src/otari/_client/api/users_api.py similarity index 99% rename from src/otari/_control_plane/api/users_api.py rename to src/otari/_client/api/users_api.py index 26beef2..b105597 100644 --- a/src/otari/_control_plane/api/users_api.py +++ b/src/otari/_client/api/users_api.py @@ -18,14 +18,14 @@ from pydantic import Field, StrictStr from typing import List, Optional from typing_extensions import Annotated -from otari._control_plane.models.create_user_request import CreateUserRequest -from otari._control_plane.models.update_user_request import UpdateUserRequest -from otari._control_plane.models.usage_log_response import UsageLogResponse -from otari._control_plane.models.user_response import UserResponse - -from otari._control_plane.api_client import ApiClient, RequestSerialized -from otari._control_plane.api_response import ApiResponse -from otari._control_plane.rest import RESTResponseType +from otari._client.models.create_user_request import CreateUserRequest +from otari._client.models.update_user_request import UpdateUserRequest +from otari._client.models.usage_log_response import UsageLogResponse +from otari._client.models.user_response import UserResponse + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType class UsersApi: diff --git a/src/otari/_control_plane/api_client.py b/src/otari/_client/api_client.py similarity index 98% rename from src/otari/_control_plane/api_client.py rename to src/otari/_client/api_client.py index ade80f9..d8d0b13 100644 --- a/src/otari/_control_plane/api_client.py +++ b/src/otari/_client/api_client.py @@ -26,11 +26,11 @@ from typing import Tuple, Optional, List, Dict, Union from pydantic import SecretStr -from otari._control_plane.configuration import Configuration -from otari._control_plane.api_response import ApiResponse, T as ApiResponseT -import otari._control_plane.models -from otari._control_plane import rest -from otari._control_plane.exceptions import ( +from otari._client.configuration import Configuration +from otari._client.api_response import ApiResponse, T as ApiResponseT +import otari._client.models +from otari._client import rest +from otari._client.exceptions import ( ApiValueError, ApiException, BadRequestException, @@ -452,7 +452,7 @@ def __deserialize(self, data, klass): if klass in self.NATIVE_TYPES_MAPPING: klass = self.NATIVE_TYPES_MAPPING[klass] else: - klass = getattr(otari._control_plane.models, klass) + klass = getattr(otari._client.models, klass) if klass in self.PRIMITIVE_TYPES: return self.__deserialize_primitive(data, klass) diff --git a/src/otari/_control_plane/api_response.py b/src/otari/_client/api_response.py similarity index 100% rename from src/otari/_control_plane/api_response.py rename to src/otari/_client/api_response.py diff --git a/src/otari/_control_plane/configuration.py b/src/otari/_client/configuration.py similarity index 99% rename from src/otari/_control_plane/configuration.py rename to src/otari/_client/configuration.py index 7fd7ba7..5cd7bc4 100644 --- a/src/otari/_control_plane/configuration.py +++ b/src/otari/_client/configuration.py @@ -256,7 +256,7 @@ def __init__( self.logger = {} """Logging Settings """ - self.logger["package_logger"] = logging.getLogger("otari._control_plane") + self.logger["package_logger"] = logging.getLogger("otari._client") self.logger["urllib3_logger"] = logging.getLogger("urllib3") self.logger_format = '%(asctime)s %(levelname)s %(message)s' """Log format diff --git a/src/otari/_control_plane/exceptions.py b/src/otari/_client/exceptions.py similarity index 100% rename from src/otari/_control_plane/exceptions.py rename to src/otari/_client/exceptions.py diff --git a/src/otari/_client/models/__init__.py b/src/otari/_client/models/__init__.py new file mode 100644 index 0000000..d886a76 --- /dev/null +++ b/src/otari/_client/models/__init__.py @@ -0,0 +1,177 @@ +# coding: utf-8 + +# flake8: noqa +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +# import models into model package +from otari._client.models.audio_speech_request import AudioSpeechRequest +from otari._client.models.batch_request_item import BatchRequestItem +from otari._client.models.budget_response import BudgetResponse +from otari._client.models.cc_chat_completion_audio import CCChatCompletionAudio +from otari._client.models.cc_chat_completion_message import CCChatCompletionMessage +from otari._client.models.cc_chat_completion_message_custom_tool_call import CCChatCompletionMessageCustomToolCall +from otari._client.models.cc_chat_completion_message_function_tool_call import CCChatCompletionMessageFunctionToolCall +from otari._client.models.cc_chat_completion_message_tool_calls_inner import CCChatCompletionMessageToolCallsInner +from otari._client.models.cc_chat_completion_token_logprob import CCChatCompletionTokenLogprob +from otari._client.models.cc_choice import CCChoice +from otari._client.models.cc_choice_logprobs import CCChoiceLogprobs +from otari._client.models.cc_completion_tokens_details import CCCompletionTokensDetails +from otari._client.models.cc_completion_usage import CCCompletionUsage +from otari._client.models.cc_custom import CCCustom +from otari._client.models.cc_function import CCFunction +from otari._client.models.cc_function_call import CCFunctionCall +from otari._client.models.cck_chat_completion_token_logprob import CCKChatCompletionTokenLogprob +from otari._client.models.cck_choice_delta import CCKChoiceDelta +from otari._client.models.cck_choice_delta_function_call import CCKChoiceDeltaFunctionCall +from otari._client.models.cck_choice_delta_tool_call import CCKChoiceDeltaToolCall +from otari._client.models.cck_choice_delta_tool_call_function import CCKChoiceDeltaToolCallFunction +from otari._client.models.cck_choice_logprobs import CCKChoiceLogprobs +from otari._client.models.cck_chunk_choice import CCKChunkChoice +from otari._client.models.cck_completion_tokens_details import CCKCompletionTokensDetails +from otari._client.models.cck_completion_usage import CCKCompletionUsage +from otari._client.models.cck_prompt_tokens_details import CCKPromptTokensDetails +from otari._client.models.cck_reasoning import CCKReasoning +from otari._client.models.cck_top_logprob import CCKTopLogprob +from otari._client.models.cc_prompt_tokens_details import CCPromptTokensDetails +from otari._client.models.cc_reasoning import CCReasoning +from otari._client.models.cc_top_logprob import CCTopLogprob +from otari._client.models.caller import Caller +from otari._client.models.chat_completion import ChatCompletion +from otari._client.models.chat_completion_chunk import ChatCompletionChunk +from otari._client.models.chat_completion_request import ChatCompletionRequest +from otari._client.models.chat_message_input import ChatMessageInput +from otari._client.models.content import Content +from otari._client.models.content1 import Content1 +from otari._client.models.content2 import Content2 +from otari._client.models.content2_any_of_inner import Content2AnyOfInner +from otari._client.models.content3 import Content3 +from otari._client.models.content4 import Content4 +from otari._client.models.content5 import Content5 +from otari._client.models.content6 import Content6 +from otari._client.models.content7 import Content7 +from otari._client.models.content8 import Content8 +from otari._client.models.content9_inner import Content9Inner +from otari._client.models.content_any_of_inner import ContentAnyOfInner +from otari._client.models.create_batch_request import CreateBatchRequest +from otari._client.models.create_budget_request import CreateBudgetRequest +from otari._client.models.create_embedding_response import CreateEmbeddingResponse +from otari._client.models.create_key_request import CreateKeyRequest +from otari._client.models.create_key_response import CreateKeyResponse +from otari._client.models.create_user_request import CreateUserRequest +from otari._client.models.emb_embedding import EMBEmbedding +from otari._client.models.emb_usage import EMBUsage +from otari._client.models.embedding_request import EmbeddingRequest +from otari._client.models.guardrail_config import GuardrailConfig +from otari._client.models.http_validation_error import HTTPValidationError +from otari._client.models.image_generation_request import ImageGenerationRequest +from otari._client.models.input import Input +from otari._client.models.input1 import Input1 +from otari._client.models.key_info import KeyInfo +from otari._client.models.location_inner import LocationInner +from otari._client.models.mr_base64_pdf_source import MRBase64PDFSource +from otari._client.models.mr_bash_code_execution_output_block import MRBashCodeExecutionOutputBlock +from otari._client.models.mr_bash_code_execution_result_block import MRBashCodeExecutionResultBlock +from otari._client.models.mr_bash_code_execution_tool_result_block import MRBashCodeExecutionToolResultBlock +from otari._client.models.mr_bash_code_execution_tool_result_error import MRBashCodeExecutionToolResultError +from otari._client.models.mr_cache_creation import MRCacheCreation +from otari._client.models.mr_citation_char_location import MRCitationCharLocation +from otari._client.models.mr_citation_content_block_location import MRCitationContentBlockLocation +from otari._client.models.mr_citation_page_location import MRCitationPageLocation +from otari._client.models.mr_citations_config import MRCitationsConfig +from otari._client.models.mr_citations_search_result_location import MRCitationsSearchResultLocation +from otari._client.models.mr_citations_web_search_result_location import MRCitationsWebSearchResultLocation +from otari._client.models.mr_code_execution_output_block import MRCodeExecutionOutputBlock +from otari._client.models.mr_code_execution_result_block import MRCodeExecutionResultBlock +from otari._client.models.mr_code_execution_tool_result_block import MRCodeExecutionToolResultBlock +from otari._client.models.mr_code_execution_tool_result_error import MRCodeExecutionToolResultError +from otari._client.models.mr_container import MRContainer +from otari._client.models.mr_container_upload_block import MRContainerUploadBlock +from otari._client.models.mr_direct_caller import MRDirectCaller +from otari._client.models.mr_document_block import MRDocumentBlock +from otari._client.models.mr_encrypted_code_execution_result_block import MREncryptedCodeExecutionResultBlock +from otari._client.models.mr_plain_text_source import MRPlainTextSource +from otari._client.models.mr_redacted_thinking_block import MRRedactedThinkingBlock +from otari._client.models.mr_refusal_stop_details import MRRefusalStopDetails +from otari._client.models.mr_server_tool_caller import MRServerToolCaller +from otari._client.models.mr_server_tool_caller20260120 import MRServerToolCaller20260120 +from otari._client.models.mr_server_tool_usage import MRServerToolUsage +from otari._client.models.mr_server_tool_use_block import MRServerToolUseBlock +from otari._client.models.mr_text_block import MRTextBlock +from otari._client.models.mr_text_block_citations_inner import MRTextBlockCitationsInner +from otari._client.models.mr_text_editor_code_execution_create_result_block import MRTextEditorCodeExecutionCreateResultBlock +from otari._client.models.mr_text_editor_code_execution_str_replace_result_block import MRTextEditorCodeExecutionStrReplaceResultBlock +from otari._client.models.mr_text_editor_code_execution_tool_result_block import MRTextEditorCodeExecutionToolResultBlock +from otari._client.models.mr_text_editor_code_execution_tool_result_error import MRTextEditorCodeExecutionToolResultError +from otari._client.models.mr_text_editor_code_execution_view_result_block import MRTextEditorCodeExecutionViewResultBlock +from otari._client.models.mr_thinking_block import MRThinkingBlock +from otari._client.models.mr_tool_reference_block import MRToolReferenceBlock +from otari._client.models.mr_tool_search_tool_result_block import MRToolSearchToolResultBlock +from otari._client.models.mr_tool_search_tool_result_error import MRToolSearchToolResultError +from otari._client.models.mr_tool_search_tool_search_result_block import MRToolSearchToolSearchResultBlock +from otari._client.models.mr_tool_use_block import MRToolUseBlock +from otari._client.models.mr_usage import MRUsage +from otari._client.models.mr_web_fetch_block import MRWebFetchBlock +from otari._client.models.mr_web_fetch_tool_result_block import MRWebFetchToolResultBlock +from otari._client.models.mr_web_fetch_tool_result_error_block import MRWebFetchToolResultErrorBlock +from otari._client.models.mr_web_search_result_block import MRWebSearchResultBlock +from otari._client.models.mr_web_search_tool_result_block import MRWebSearchToolResultBlock +from otari._client.models.mr_web_search_tool_result_error import MRWebSearchToolResultError +from otari._client.models.msg_audio import MSGAudio +from otari._client.models.msg_chat_completion_assistant_message_param import MSGChatCompletionAssistantMessageParam +from otari._client.models.msg_chat_completion_content_part_image_param import MSGChatCompletionContentPartImageParam +from otari._client.models.msg_chat_completion_content_part_input_audio_param import MSGChatCompletionContentPartInputAudioParam +from otari._client.models.msg_chat_completion_content_part_refusal_param import MSGChatCompletionContentPartRefusalParam +from otari._client.models.msg_chat_completion_content_part_text_param import MSGChatCompletionContentPartTextParam +from otari._client.models.msg_chat_completion_developer_message_param import MSGChatCompletionDeveloperMessageParam +from otari._client.models.msg_chat_completion_function_message_param import MSGChatCompletionFunctionMessageParam +from otari._client.models.msg_chat_completion_message_custom_tool_call_param import MSGChatCompletionMessageCustomToolCallParam +from otari._client.models.msg_chat_completion_message_function_tool_call_param import MSGChatCompletionMessageFunctionToolCallParam +from otari._client.models.msg_chat_completion_system_message_param import MSGChatCompletionSystemMessageParam +from otari._client.models.msg_chat_completion_tool_message_param import MSGChatCompletionToolMessageParam +from otari._client.models.msg_chat_completion_user_message_param import MSGChatCompletionUserMessageParam +from otari._client.models.msg_custom import MSGCustom +from otari._client.models.msg_file import MSGFile +from otari._client.models.msg_file_file import MSGFileFile +from otari._client.models.msg_function import MSGFunction +from otari._client.models.msg_function_call import MSGFunctionCall +from otari._client.models.msg_image_url import MSGImageURL +from otari._client.models.msg_input_audio import MSGInputAudio +from otari._client.models.mcp_server_config import McpServerConfig +from otari._client.models.message_response import MessageResponse +from otari._client.models.messages_request import MessagesRequest +from otari._client.models.model import Model +from otari._client.models.model_list_response import ModelListResponse +from otari._client.models.model_object import ModelObject +from otari._client.models.model_pricing_info import ModelPricingInfo +from otari._client.models.moderation_request import ModerationRequest +from otari._client.models.moderation_response import ModerationResponse +from otari._client.models.moderation_result import ModerationResult +from otari._client.models.pricing_response import PricingResponse +from otari._client.models.rr_rerank_meta import RRRerankMeta +from otari._client.models.rr_rerank_result import RRRerankResult +from otari._client.models.rr_rerank_usage import RRRerankUsage +from otari._client.models.rerank_request import RerankRequest +from otari._client.models.rerank_response import RerankResponse +from otari._client.models.responses_request import ResponsesRequest +from otari._client.models.set_pricing_request import SetPricingRequest +from otari._client.models.source import Source +from otari._client.models.system import System +from otari._client.models.tool_calls_inner import ToolCallsInner +from otari._client.models.tool_choice import ToolChoice +from otari._client.models.update_budget_request import UpdateBudgetRequest +from otari._client.models.update_key_request import UpdateKeyRequest +from otari._client.models.update_user_request import UpdateUserRequest +from otari._client.models.usage_entry import UsageEntry +from otari._client.models.usage_log_response import UsageLogResponse +from otari._client.models.user_response import UserResponse +from otari._client.models.validation_error import ValidationError + diff --git a/src/otari/_client/models/audio_speech_request.py b/src/otari/_client/models/audio_speech_request.py new file mode 100644 index 0000000..0cc33ee --- /dev/null +++ b/src/otari/_client/models/audio_speech_request.py @@ -0,0 +1,120 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AudioSpeechRequest(BaseModel): + """ + OpenAI-compatible audio speech (TTS) request. + """ # noqa: E501 + input: StrictStr + instructions: Optional[StrictStr] = None + model: StrictStr + response_format: Optional[StrictStr] = None + speed: Optional[Union[StrictFloat, StrictInt]] = None + user: Optional[StrictStr] = None + voice: StrictStr + __properties: ClassVar[List[str]] = ["input", "instructions", "model", "response_format", "speed", "user", "voice"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AudioSpeechRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if instructions (nullable) is None + # and model_fields_set contains the field + if self.instructions is None and "instructions" in self.model_fields_set: + _dict['instructions'] = None + + # set to None if response_format (nullable) is None + # and model_fields_set contains the field + if self.response_format is None and "response_format" in self.model_fields_set: + _dict['response_format'] = None + + # set to None if speed (nullable) is None + # and model_fields_set contains the field + if self.speed is None and "speed" in self.model_fields_set: + _dict['speed'] = None + + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AudioSpeechRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "input": obj.get("input"), + "instructions": obj.get("instructions"), + "model": obj.get("model"), + "response_format": obj.get("response_format"), + "speed": obj.get("speed"), + "user": obj.get("user"), + "voice": obj.get("voice") + }) + return _obj + + diff --git a/src/otari/_client/models/batch_request_item.py b/src/otari/_client/models/batch_request_item.py new file mode 100644 index 0000000..149a48d --- /dev/null +++ b/src/otari/_client/models/batch_request_item.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class BatchRequestItem(BaseModel): + """ + BatchRequestItem + """ # noqa: E501 + body: Dict[str, Any] + custom_id: StrictStr + __properties: ClassVar[List[str]] = ["body", "custom_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BatchRequestItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BatchRequestItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "body": obj.get("body"), + "custom_id": obj.get("custom_id") + }) + return _obj + + diff --git a/src/otari/_control_plane/models/budget_response.py b/src/otari/_client/models/budget_response.py similarity index 100% rename from src/otari/_control_plane/models/budget_response.py rename to src/otari/_client/models/budget_response.py diff --git a/src/otari/_client/models/caller.py b/src/otari/_client/models/caller.py new file mode 100644 index 0000000..a3a2d72 --- /dev/null +++ b/src/otari/_client/models/caller.py @@ -0,0 +1,155 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_direct_caller import MRDirectCaller +from otari._client.models.mr_server_tool_caller import MRServerToolCaller +from otari._client.models.mr_server_tool_caller20260120 import MRServerToolCaller20260120 +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CALLER_ANY_OF_SCHEMAS = ["MRDirectCaller", "MRServerToolCaller", "MRServerToolCaller20260120"] + +class Caller(BaseModel): + """ + Caller + """ + + # data type: MRDirectCaller + anyof_schema_1_validator: Optional[MRDirectCaller] = None + # data type: MRServerToolCaller + anyof_schema_2_validator: Optional[MRServerToolCaller] = None + # data type: MRServerToolCaller20260120 + anyof_schema_3_validator: Optional[MRServerToolCaller20260120] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRDirectCaller, MRServerToolCaller, MRServerToolCaller20260120]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRDirectCaller", "MRServerToolCaller", "MRServerToolCaller20260120" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + if v is None: + return v + + instance = Caller.model_construct() + error_messages = [] + # validate data type: MRDirectCaller + if not isinstance(v, MRDirectCaller): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRDirectCaller`") + else: + return v + + # validate data type: MRServerToolCaller + if not isinstance(v, MRServerToolCaller): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRServerToolCaller`") + else: + return v + + # validate data type: MRServerToolCaller20260120 + if not isinstance(v, MRServerToolCaller20260120): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRServerToolCaller20260120`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Caller with anyOf schemas: MRDirectCaller, MRServerToolCaller, MRServerToolCaller20260120. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + if json_str is None: + return instance + + error_messages = [] + # anyof_schema_1_validator: Optional[MRDirectCaller] = None + try: + instance.actual_instance = MRDirectCaller.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRServerToolCaller] = None + try: + instance.actual_instance = MRServerToolCaller.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MRServerToolCaller20260120] = None + try: + instance.actual_instance = MRServerToolCaller20260120.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Caller with anyOf schemas: MRDirectCaller, MRServerToolCaller, MRServerToolCaller20260120. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRDirectCaller, MRServerToolCaller, MRServerToolCaller20260120]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/cc_chat_completion_audio.py b/src/otari/_client/models/cc_chat_completion_audio.py new file mode 100644 index 0000000..88acc49 --- /dev/null +++ b/src/otari/_client/models/cc_chat_completion_audio.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChatCompletionAudio(BaseModel): + """ + If the audio output modality is requested, this object contains data about the audio response from the model. [Learn more](https://platform.openai.com/docs/guides/audio). + """ # noqa: E501 + id: StrictStr + data: StrictStr + expires_at: StrictInt + transcript: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "data", "expires_at", "transcript"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChatCompletionAudio from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChatCompletionAudio from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "data": obj.get("data"), + "expires_at": obj.get("expires_at"), + "transcript": obj.get("transcript") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_chat_completion_message.py b/src/otari/_client/models/cc_chat_completion_message.py new file mode 100644 index 0000000..b6d515b --- /dev/null +++ b/src/otari/_client/models/cc_chat_completion_message.py @@ -0,0 +1,177 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cc_chat_completion_audio import CCChatCompletionAudio +from otari._client.models.cc_chat_completion_message_tool_calls_inner import CCChatCompletionMessageToolCallsInner +from otari._client.models.cc_function_call import CCFunctionCall +from otari._client.models.cc_reasoning import CCReasoning +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChatCompletionMessage(BaseModel): + """ + CCChatCompletionMessage + """ # noqa: E501 + content: Optional[StrictStr] = None + refusal: Optional[StrictStr] = None + role: StrictStr + annotations: Optional[List[Dict[str, Any]]] = None + audio: Optional[CCChatCompletionAudio] = None + function_call: Optional[CCFunctionCall] = None + tool_calls: Optional[List[CCChatCompletionMessageToolCallsInner]] = None + reasoning: Optional[CCReasoning] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "refusal", "role", "annotations", "audio", "function_call", "tool_calls", "reasoning"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['assistant']): + raise ValueError("must be one of enum values ('assistant')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChatCompletionMessage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of audio + if self.audio: + _dict['audio'] = self.audio.to_dict() + # override the default output from pydantic by calling `to_dict()` of function_call + if self.function_call: + _dict['function_call'] = self.function_call.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in tool_calls (list) + _items = [] + if self.tool_calls: + for _item_tool_calls in self.tool_calls: + if _item_tool_calls: + _items.append(_item_tool_calls.to_dict()) + _dict['tool_calls'] = _items + # override the default output from pydantic by calling `to_dict()` of reasoning + if self.reasoning: + _dict['reasoning'] = self.reasoning.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if content (nullable) is None + # and model_fields_set contains the field + if self.content is None and "content" in self.model_fields_set: + _dict['content'] = None + + # set to None if refusal (nullable) is None + # and model_fields_set contains the field + if self.refusal is None and "refusal" in self.model_fields_set: + _dict['refusal'] = None + + # set to None if annotations (nullable) is None + # and model_fields_set contains the field + if self.annotations is None and "annotations" in self.model_fields_set: + _dict['annotations'] = None + + # set to None if audio (nullable) is None + # and model_fields_set contains the field + if self.audio is None and "audio" in self.model_fields_set: + _dict['audio'] = None + + # set to None if function_call (nullable) is None + # and model_fields_set contains the field + if self.function_call is None and "function_call" in self.model_fields_set: + _dict['function_call'] = None + + # set to None if tool_calls (nullable) is None + # and model_fields_set contains the field + if self.tool_calls is None and "tool_calls" in self.model_fields_set: + _dict['tool_calls'] = None + + # set to None if reasoning (nullable) is None + # and model_fields_set contains the field + if self.reasoning is None and "reasoning" in self.model_fields_set: + _dict['reasoning'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChatCompletionMessage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content"), + "refusal": obj.get("refusal"), + "role": obj.get("role"), + "annotations": obj.get("annotations"), + "audio": CCChatCompletionAudio.from_dict(obj["audio"]) if obj.get("audio") is not None else None, + "function_call": CCFunctionCall.from_dict(obj["function_call"]) if obj.get("function_call") is not None else None, + "tool_calls": [CCChatCompletionMessageToolCallsInner.from_dict(_item) for _item in obj["tool_calls"]] if obj.get("tool_calls") is not None else None, + "reasoning": CCReasoning.from_dict(obj["reasoning"]) if obj.get("reasoning") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_chat_completion_message_custom_tool_call.py b/src/otari/_client/models/cc_chat_completion_message_custom_tool_call.py new file mode 100644 index 0000000..cab3b5b --- /dev/null +++ b/src/otari/_client/models/cc_chat_completion_message_custom_tool_call.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.cc_custom import CCCustom +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChatCompletionMessageCustomToolCall(BaseModel): + """ + A call to a custom tool created by the model. + """ # noqa: E501 + id: StrictStr + custom: CCCustom + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "custom", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['custom']): + raise ValueError("must be one of enum values ('custom')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChatCompletionMessageCustomToolCall from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of custom + if self.custom: + _dict['custom'] = self.custom.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChatCompletionMessageCustomToolCall from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "custom": CCCustom.from_dict(obj["custom"]) if obj.get("custom") is not None else None, + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_chat_completion_message_function_tool_call.py b/src/otari/_client/models/cc_chat_completion_message_function_tool_call.py new file mode 100644 index 0000000..fd1c101 --- /dev/null +++ b/src/otari/_client/models/cc_chat_completion_message_function_tool_call.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.cc_function import CCFunction +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChatCompletionMessageFunctionToolCall(BaseModel): + """ + A call to a function tool created by the model. + """ # noqa: E501 + id: StrictStr + function: CCFunction + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "function", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['function']): + raise ValueError("must be one of enum values ('function')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChatCompletionMessageFunctionToolCall from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of function + if self.function: + _dict['function'] = self.function.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChatCompletionMessageFunctionToolCall from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "function": CCFunction.from_dict(obj["function"]) if obj.get("function") is not None else None, + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_chat_completion_message_tool_calls_inner.py b/src/otari/_client/models/cc_chat_completion_message_tool_calls_inner.py new file mode 100644 index 0000000..2fd774f --- /dev/null +++ b/src/otari/_client/models/cc_chat_completion_message_tool_calls_inner.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.cc_chat_completion_message_custom_tool_call import CCChatCompletionMessageCustomToolCall +from otari._client.models.cc_chat_completion_message_function_tool_call import CCChatCompletionMessageFunctionToolCall +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CCCHATCOMPLETIONMESSAGETOOLCALLSINNER_ANY_OF_SCHEMAS = ["CCChatCompletionMessageCustomToolCall", "CCChatCompletionMessageFunctionToolCall"] + +class CCChatCompletionMessageToolCallsInner(BaseModel): + """ + CCChatCompletionMessageToolCallsInner + """ + + # data type: CCChatCompletionMessageFunctionToolCall + anyof_schema_1_validator: Optional[CCChatCompletionMessageFunctionToolCall] = None + # data type: CCChatCompletionMessageCustomToolCall + anyof_schema_2_validator: Optional[CCChatCompletionMessageCustomToolCall] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[CCChatCompletionMessageCustomToolCall, CCChatCompletionMessageFunctionToolCall]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "CCChatCompletionMessageCustomToolCall", "CCChatCompletionMessageFunctionToolCall" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = CCChatCompletionMessageToolCallsInner.model_construct() + error_messages = [] + # validate data type: CCChatCompletionMessageFunctionToolCall + if not isinstance(v, CCChatCompletionMessageFunctionToolCall): + error_messages.append(f"Error! Input type `{type(v)}` is not `CCChatCompletionMessageFunctionToolCall`") + else: + return v + + # validate data type: CCChatCompletionMessageCustomToolCall + if not isinstance(v, CCChatCompletionMessageCustomToolCall): + error_messages.append(f"Error! Input type `{type(v)}` is not `CCChatCompletionMessageCustomToolCall`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in CCChatCompletionMessageToolCallsInner with anyOf schemas: CCChatCompletionMessageCustomToolCall, CCChatCompletionMessageFunctionToolCall. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[CCChatCompletionMessageFunctionToolCall] = None + try: + instance.actual_instance = CCChatCompletionMessageFunctionToolCall.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[CCChatCompletionMessageCustomToolCall] = None + try: + instance.actual_instance = CCChatCompletionMessageCustomToolCall.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into CCChatCompletionMessageToolCallsInner with anyOf schemas: CCChatCompletionMessageCustomToolCall, CCChatCompletionMessageFunctionToolCall. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], CCChatCompletionMessageCustomToolCall, CCChatCompletionMessageFunctionToolCall]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/cc_chat_completion_token_logprob.py b/src/otari/_client/models/cc_chat_completion_token_logprob.py new file mode 100644 index 0000000..5443004 --- /dev/null +++ b/src/otari/_client/models/cc_chat_completion_token_logprob.py @@ -0,0 +1,120 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from otari._client.models.cc_top_logprob import CCTopLogprob +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChatCompletionTokenLogprob(BaseModel): + """ + CCChatCompletionTokenLogprob + """ # noqa: E501 + token: StrictStr + bytes: Optional[List[StrictInt]] = None + logprob: Union[StrictFloat, StrictInt] + top_logprobs: List[CCTopLogprob] + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["token", "bytes", "logprob", "top_logprobs"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChatCompletionTokenLogprob from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in top_logprobs (list) + _items = [] + if self.top_logprobs: + for _item_top_logprobs in self.top_logprobs: + if _item_top_logprobs: + _items.append(_item_top_logprobs.to_dict()) + _dict['top_logprobs'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if bytes (nullable) is None + # and model_fields_set contains the field + if self.bytes is None and "bytes" in self.model_fields_set: + _dict['bytes'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChatCompletionTokenLogprob from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "token": obj.get("token"), + "bytes": obj.get("bytes"), + "logprob": obj.get("logprob"), + "top_logprobs": [CCTopLogprob.from_dict(_item) for _item in obj["top_logprobs"]] if obj.get("top_logprobs") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_choice.py b/src/otari/_client/models/cc_choice.py new file mode 100644 index 0000000..2a23c8c --- /dev/null +++ b/src/otari/_client/models/cc_choice.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cc_chat_completion_message import CCChatCompletionMessage +from otari._client.models.cc_choice_logprobs import CCChoiceLogprobs +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChoice(BaseModel): + """ + CCChoice + """ # noqa: E501 + finish_reason: StrictStr + index: StrictInt + logprobs: Optional[CCChoiceLogprobs] = None + message: CCChatCompletionMessage + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["finish_reason", "index", "logprobs", "message"] + + @field_validator('finish_reason') + def finish_reason_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['stop', 'length', 'tool_calls', 'content_filter', 'function_call']): + raise ValueError("must be one of enum values ('stop', 'length', 'tool_calls', 'content_filter', 'function_call')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChoice from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of logprobs + if self.logprobs: + _dict['logprobs'] = self.logprobs.to_dict() + # override the default output from pydantic by calling `to_dict()` of message + if self.message: + _dict['message'] = self.message.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if logprobs (nullable) is None + # and model_fields_set contains the field + if self.logprobs is None and "logprobs" in self.model_fields_set: + _dict['logprobs'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChoice from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "finish_reason": obj.get("finish_reason"), + "index": obj.get("index"), + "logprobs": CCChoiceLogprobs.from_dict(obj["logprobs"]) if obj.get("logprobs") is not None else None, + "message": CCChatCompletionMessage.from_dict(obj["message"]) if obj.get("message") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_choice_logprobs.py b/src/otari/_client/models/cc_choice_logprobs.py new file mode 100644 index 0000000..7bb4175 --- /dev/null +++ b/src/otari/_client/models/cc_choice_logprobs.py @@ -0,0 +1,128 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cc_chat_completion_token_logprob import CCChatCompletionTokenLogprob +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCChoiceLogprobs(BaseModel): + """ + Log probability information for the choice. + """ # noqa: E501 + content: Optional[List[CCChatCompletionTokenLogprob]] = None + refusal: Optional[List[CCChatCompletionTokenLogprob]] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "refusal"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCChoiceLogprobs from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in content (list) + _items = [] + if self.content: + for _item_content in self.content: + if _item_content: + _items.append(_item_content.to_dict()) + _dict['content'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in refusal (list) + _items = [] + if self.refusal: + for _item_refusal in self.refusal: + if _item_refusal: + _items.append(_item_refusal.to_dict()) + _dict['refusal'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if content (nullable) is None + # and model_fields_set contains the field + if self.content is None and "content" in self.model_fields_set: + _dict['content'] = None + + # set to None if refusal (nullable) is None + # and model_fields_set contains the field + if self.refusal is None and "refusal" in self.model_fields_set: + _dict['refusal'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCChoiceLogprobs from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": [CCChatCompletionTokenLogprob.from_dict(_item) for _item in obj["content"]] if obj.get("content") is not None else None, + "refusal": [CCChatCompletionTokenLogprob.from_dict(_item) for _item in obj["refusal"]] if obj.get("refusal") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_completion_tokens_details.py b/src/otari/_client/models/cc_completion_tokens_details.py new file mode 100644 index 0000000..47caf33 --- /dev/null +++ b/src/otari/_client/models/cc_completion_tokens_details.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCCompletionTokensDetails(BaseModel): + """ + Breakdown of tokens used in a completion. + """ # noqa: E501 + accepted_prediction_tokens: Optional[StrictInt] = None + audio_tokens: Optional[StrictInt] = None + reasoning_tokens: Optional[StrictInt] = None + rejected_prediction_tokens: Optional[StrictInt] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["accepted_prediction_tokens", "audio_tokens", "reasoning_tokens", "rejected_prediction_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCCompletionTokensDetails from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if accepted_prediction_tokens (nullable) is None + # and model_fields_set contains the field + if self.accepted_prediction_tokens is None and "accepted_prediction_tokens" in self.model_fields_set: + _dict['accepted_prediction_tokens'] = None + + # set to None if audio_tokens (nullable) is None + # and model_fields_set contains the field + if self.audio_tokens is None and "audio_tokens" in self.model_fields_set: + _dict['audio_tokens'] = None + + # set to None if reasoning_tokens (nullable) is None + # and model_fields_set contains the field + if self.reasoning_tokens is None and "reasoning_tokens" in self.model_fields_set: + _dict['reasoning_tokens'] = None + + # set to None if rejected_prediction_tokens (nullable) is None + # and model_fields_set contains the field + if self.rejected_prediction_tokens is None and "rejected_prediction_tokens" in self.model_fields_set: + _dict['rejected_prediction_tokens'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCCompletionTokensDetails from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "accepted_prediction_tokens": obj.get("accepted_prediction_tokens"), + "audio_tokens": obj.get("audio_tokens"), + "reasoning_tokens": obj.get("reasoning_tokens"), + "rejected_prediction_tokens": obj.get("rejected_prediction_tokens") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_completion_usage.py b/src/otari/_client/models/cc_completion_usage.py new file mode 100644 index 0000000..105ca2f --- /dev/null +++ b/src/otari/_client/models/cc_completion_usage.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cc_completion_tokens_details import CCCompletionTokensDetails +from otari._client.models.cc_prompt_tokens_details import CCPromptTokensDetails +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCCompletionUsage(BaseModel): + """ + Usage statistics for the completion request. + """ # noqa: E501 + completion_tokens: StrictInt + prompt_tokens: StrictInt + total_tokens: StrictInt + completion_tokens_details: Optional[CCCompletionTokensDetails] = None + prompt_tokens_details: Optional[CCPromptTokensDetails] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["completion_tokens", "prompt_tokens", "total_tokens", "completion_tokens_details", "prompt_tokens_details"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCCompletionUsage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of completion_tokens_details + if self.completion_tokens_details: + _dict['completion_tokens_details'] = self.completion_tokens_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of prompt_tokens_details + if self.prompt_tokens_details: + _dict['prompt_tokens_details'] = self.prompt_tokens_details.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if completion_tokens_details (nullable) is None + # and model_fields_set contains the field + if self.completion_tokens_details is None and "completion_tokens_details" in self.model_fields_set: + _dict['completion_tokens_details'] = None + + # set to None if prompt_tokens_details (nullable) is None + # and model_fields_set contains the field + if self.prompt_tokens_details is None and "prompt_tokens_details" in self.model_fields_set: + _dict['prompt_tokens_details'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCCompletionUsage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "completion_tokens": obj.get("completion_tokens"), + "prompt_tokens": obj.get("prompt_tokens"), + "total_tokens": obj.get("total_tokens"), + "completion_tokens_details": CCCompletionTokensDetails.from_dict(obj["completion_tokens_details"]) if obj.get("completion_tokens_details") is not None else None, + "prompt_tokens_details": CCPromptTokensDetails.from_dict(obj["prompt_tokens_details"]) if obj.get("prompt_tokens_details") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_custom.py b/src/otari/_client/models/cc_custom.py new file mode 100644 index 0000000..54686ac --- /dev/null +++ b/src/otari/_client/models/cc_custom.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCCustom(BaseModel): + """ + The custom tool that the model called. + """ # noqa: E501 + input: StrictStr + name: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["input", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCCustom from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCCustom from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "input": obj.get("input"), + "name": obj.get("name") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_function.py b/src/otari/_client/models/cc_function.py new file mode 100644 index 0000000..af06013 --- /dev/null +++ b/src/otari/_client/models/cc_function.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCFunction(BaseModel): + """ + The function that the model called. + """ # noqa: E501 + arguments: StrictStr + name: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["arguments", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCFunction from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCFunction from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "arguments": obj.get("arguments"), + "name": obj.get("name") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_function_call.py b/src/otari/_client/models/cc_function_call.py new file mode 100644 index 0000000..25bb26f --- /dev/null +++ b/src/otari/_client/models/cc_function_call.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCFunctionCall(BaseModel): + """ + Deprecated and replaced by `tool_calls`. The name and arguments of a function that should be called, as generated by the model. + """ # noqa: E501 + arguments: StrictStr + name: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["arguments", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCFunctionCall from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCFunctionCall from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "arguments": obj.get("arguments"), + "name": obj.get("name") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_prompt_tokens_details.py b/src/otari/_client/models/cc_prompt_tokens_details.py new file mode 100644 index 0000000..dc36bbb --- /dev/null +++ b/src/otari/_client/models/cc_prompt_tokens_details.py @@ -0,0 +1,113 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCPromptTokensDetails(BaseModel): + """ + Breakdown of tokens used in the prompt. + """ # noqa: E501 + audio_tokens: Optional[StrictInt] = None + cached_tokens: Optional[StrictInt] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["audio_tokens", "cached_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCPromptTokensDetails from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if audio_tokens (nullable) is None + # and model_fields_set contains the field + if self.audio_tokens is None and "audio_tokens" in self.model_fields_set: + _dict['audio_tokens'] = None + + # set to None if cached_tokens (nullable) is None + # and model_fields_set contains the field + if self.cached_tokens is None and "cached_tokens" in self.model_fields_set: + _dict['cached_tokens'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCPromptTokensDetails from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "audio_tokens": obj.get("audio_tokens"), + "cached_tokens": obj.get("cached_tokens") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cc_reasoning.py b/src/otari/_client/models/cc_reasoning.py new file mode 100644 index 0000000..a985df3 --- /dev/null +++ b/src/otari/_client/models/cc_reasoning.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCReasoning(BaseModel): + """ + Reasoning content emitted by a model. Serializes as a plain JSON string so that responses are compatible with OpenAI-style clients that expect ``delta.reasoning`` / ``message.reasoning`` to be a string. The Python attribute ``content`` remains available for typed access (e.g. ``message.reasoning.content``). + """ # noqa: E501 + content: StrictStr + __properties: ClassVar[List[str]] = ["content"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCReasoning from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCReasoning from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content") + }) + return _obj + + diff --git a/src/otari/_client/models/cc_top_logprob.py b/src/otari/_client/models/cc_top_logprob.py new file mode 100644 index 0000000..f078648 --- /dev/null +++ b/src/otari/_client/models/cc_top_logprob.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCTopLogprob(BaseModel): + """ + CCTopLogprob + """ # noqa: E501 + token: StrictStr + bytes: Optional[List[StrictInt]] = None + logprob: Union[StrictFloat, StrictInt] + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["token", "bytes", "logprob"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCTopLogprob from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if bytes (nullable) is None + # and model_fields_set contains the field + if self.bytes is None and "bytes" in self.model_fields_set: + _dict['bytes'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCTopLogprob from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "token": obj.get("token"), + "bytes": obj.get("bytes"), + "logprob": obj.get("logprob") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_chat_completion_token_logprob.py b/src/otari/_client/models/cck_chat_completion_token_logprob.py new file mode 100644 index 0000000..cede850 --- /dev/null +++ b/src/otari/_client/models/cck_chat_completion_token_logprob.py @@ -0,0 +1,120 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from otari._client.models.cck_top_logprob import CCKTopLogprob +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChatCompletionTokenLogprob(BaseModel): + """ + CCKChatCompletionTokenLogprob + """ # noqa: E501 + token: StrictStr + bytes: Optional[List[StrictInt]] = None + logprob: Union[StrictFloat, StrictInt] + top_logprobs: List[CCKTopLogprob] + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["token", "bytes", "logprob", "top_logprobs"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChatCompletionTokenLogprob from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in top_logprobs (list) + _items = [] + if self.top_logprobs: + for _item_top_logprobs in self.top_logprobs: + if _item_top_logprobs: + _items.append(_item_top_logprobs.to_dict()) + _dict['top_logprobs'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if bytes (nullable) is None + # and model_fields_set contains the field + if self.bytes is None and "bytes" in self.model_fields_set: + _dict['bytes'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChatCompletionTokenLogprob from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "token": obj.get("token"), + "bytes": obj.get("bytes"), + "logprob": obj.get("logprob"), + "top_logprobs": [CCKTopLogprob.from_dict(_item) for _item in obj["top_logprobs"]] if obj.get("top_logprobs") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_choice_delta.py b/src/otari/_client/models/cck_choice_delta.py new file mode 100644 index 0000000..7e7c7ff --- /dev/null +++ b/src/otari/_client/models/cck_choice_delta.py @@ -0,0 +1,167 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cck_choice_delta_function_call import CCKChoiceDeltaFunctionCall +from otari._client.models.cck_choice_delta_tool_call import CCKChoiceDeltaToolCall +from otari._client.models.cck_reasoning import CCKReasoning +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChoiceDelta(BaseModel): + """ + CCKChoiceDelta + """ # noqa: E501 + content: Optional[StrictStr] = None + function_call: Optional[CCKChoiceDeltaFunctionCall] = None + refusal: Optional[StrictStr] = None + role: Optional[StrictStr] = None + tool_calls: Optional[List[CCKChoiceDeltaToolCall]] = None + reasoning: Optional[CCKReasoning] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "function_call", "refusal", "role", "tool_calls", "reasoning"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['developer', 'system', 'user', 'assistant', 'tool']): + raise ValueError("must be one of enum values ('developer', 'system', 'user', 'assistant', 'tool')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChoiceDelta from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of function_call + if self.function_call: + _dict['function_call'] = self.function_call.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in tool_calls (list) + _items = [] + if self.tool_calls: + for _item_tool_calls in self.tool_calls: + if _item_tool_calls: + _items.append(_item_tool_calls.to_dict()) + _dict['tool_calls'] = _items + # override the default output from pydantic by calling `to_dict()` of reasoning + if self.reasoning: + _dict['reasoning'] = self.reasoning.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if content (nullable) is None + # and model_fields_set contains the field + if self.content is None and "content" in self.model_fields_set: + _dict['content'] = None + + # set to None if function_call (nullable) is None + # and model_fields_set contains the field + if self.function_call is None and "function_call" in self.model_fields_set: + _dict['function_call'] = None + + # set to None if refusal (nullable) is None + # and model_fields_set contains the field + if self.refusal is None and "refusal" in self.model_fields_set: + _dict['refusal'] = None + + # set to None if role (nullable) is None + # and model_fields_set contains the field + if self.role is None and "role" in self.model_fields_set: + _dict['role'] = None + + # set to None if tool_calls (nullable) is None + # and model_fields_set contains the field + if self.tool_calls is None and "tool_calls" in self.model_fields_set: + _dict['tool_calls'] = None + + # set to None if reasoning (nullable) is None + # and model_fields_set contains the field + if self.reasoning is None and "reasoning" in self.model_fields_set: + _dict['reasoning'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChoiceDelta from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content"), + "function_call": CCKChoiceDeltaFunctionCall.from_dict(obj["function_call"]) if obj.get("function_call") is not None else None, + "refusal": obj.get("refusal"), + "role": obj.get("role"), + "tool_calls": [CCKChoiceDeltaToolCall.from_dict(_item) for _item in obj["tool_calls"]] if obj.get("tool_calls") is not None else None, + "reasoning": CCKReasoning.from_dict(obj["reasoning"]) if obj.get("reasoning") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_choice_delta_function_call.py b/src/otari/_client/models/cck_choice_delta_function_call.py new file mode 100644 index 0000000..b2e0862 --- /dev/null +++ b/src/otari/_client/models/cck_choice_delta_function_call.py @@ -0,0 +1,113 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChoiceDeltaFunctionCall(BaseModel): + """ + Deprecated and replaced by `tool_calls`. The name and arguments of a function that should be called, as generated by the model. + """ # noqa: E501 + arguments: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + name: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["arguments", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChoiceDeltaFunctionCall from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if arguments (nullable) is None + # and model_fields_set contains the field + if self.arguments is None and "arguments" in self.model_fields_set: + _dict['arguments'] = None + + # set to None if name (nullable) is None + # and model_fields_set contains the field + if self.name is None and "name" in self.model_fields_set: + _dict['name'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChoiceDeltaFunctionCall from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "arguments": obj.get("arguments"), + "name": obj.get("name") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_choice_delta_tool_call.py b/src/otari/_client/models/cck_choice_delta_tool_call.py new file mode 100644 index 0000000..cf7e4e9 --- /dev/null +++ b/src/otari/_client/models/cck_choice_delta_tool_call.py @@ -0,0 +1,136 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cck_choice_delta_tool_call_function import CCKChoiceDeltaToolCallFunction +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChoiceDeltaToolCall(BaseModel): + """ + CCKChoiceDeltaToolCall + """ # noqa: E501 + index: StrictInt + id: Optional[StrictStr] = None + function: Optional[CCKChoiceDeltaToolCallFunction] = None + type: Optional[StrictStr] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["index", "id", "function", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['function']): + raise ValueError("must be one of enum values ('function')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChoiceDeltaToolCall from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of function + if self.function: + _dict['function'] = self.function.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if id (nullable) is None + # and model_fields_set contains the field + if self.id is None and "id" in self.model_fields_set: + _dict['id'] = None + + # set to None if function (nullable) is None + # and model_fields_set contains the field + if self.function is None and "function" in self.model_fields_set: + _dict['function'] = None + + # set to None if type (nullable) is None + # and model_fields_set contains the field + if self.type is None and "type" in self.model_fields_set: + _dict['type'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChoiceDeltaToolCall from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "index": obj.get("index"), + "id": obj.get("id"), + "function": CCKChoiceDeltaToolCallFunction.from_dict(obj["function"]) if obj.get("function") is not None else None, + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_choice_delta_tool_call_function.py b/src/otari/_client/models/cck_choice_delta_tool_call_function.py new file mode 100644 index 0000000..6af39e7 --- /dev/null +++ b/src/otari/_client/models/cck_choice_delta_tool_call_function.py @@ -0,0 +1,113 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChoiceDeltaToolCallFunction(BaseModel): + """ + CCKChoiceDeltaToolCallFunction + """ # noqa: E501 + arguments: Optional[StrictStr] = None + name: Optional[StrictStr] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["arguments", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChoiceDeltaToolCallFunction from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if arguments (nullable) is None + # and model_fields_set contains the field + if self.arguments is None and "arguments" in self.model_fields_set: + _dict['arguments'] = None + + # set to None if name (nullable) is None + # and model_fields_set contains the field + if self.name is None and "name" in self.model_fields_set: + _dict['name'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChoiceDeltaToolCallFunction from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "arguments": obj.get("arguments"), + "name": obj.get("name") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_choice_logprobs.py b/src/otari/_client/models/cck_choice_logprobs.py new file mode 100644 index 0000000..14832de --- /dev/null +++ b/src/otari/_client/models/cck_choice_logprobs.py @@ -0,0 +1,128 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cck_chat_completion_token_logprob import CCKChatCompletionTokenLogprob +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChoiceLogprobs(BaseModel): + """ + Log probability information for the choice. + """ # noqa: E501 + content: Optional[List[CCKChatCompletionTokenLogprob]] = None + refusal: Optional[List[CCKChatCompletionTokenLogprob]] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "refusal"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChoiceLogprobs from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in content (list) + _items = [] + if self.content: + for _item_content in self.content: + if _item_content: + _items.append(_item_content.to_dict()) + _dict['content'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in refusal (list) + _items = [] + if self.refusal: + for _item_refusal in self.refusal: + if _item_refusal: + _items.append(_item_refusal.to_dict()) + _dict['refusal'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if content (nullable) is None + # and model_fields_set contains the field + if self.content is None and "content" in self.model_fields_set: + _dict['content'] = None + + # set to None if refusal (nullable) is None + # and model_fields_set contains the field + if self.refusal is None and "refusal" in self.model_fields_set: + _dict['refusal'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChoiceLogprobs from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": [CCKChatCompletionTokenLogprob.from_dict(_item) for _item in obj["content"]] if obj.get("content") is not None else None, + "refusal": [CCKChatCompletionTokenLogprob.from_dict(_item) for _item in obj["refusal"]] if obj.get("refusal") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_chunk_choice.py b/src/otari/_client/models/cck_chunk_choice.py new file mode 100644 index 0000000..167c5ca --- /dev/null +++ b/src/otari/_client/models/cck_chunk_choice.py @@ -0,0 +1,135 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cck_choice_delta import CCKChoiceDelta +from otari._client.models.cck_choice_logprobs import CCKChoiceLogprobs +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKChunkChoice(BaseModel): + """ + CCKChunkChoice + """ # noqa: E501 + delta: CCKChoiceDelta + finish_reason: Optional[StrictStr] = None + index: StrictInt + logprobs: Optional[CCKChoiceLogprobs] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["delta", "finish_reason", "index", "logprobs"] + + @field_validator('finish_reason') + def finish_reason_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['stop', 'length', 'tool_calls', 'content_filter', 'function_call']): + raise ValueError("must be one of enum values ('stop', 'length', 'tool_calls', 'content_filter', 'function_call')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKChunkChoice from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of delta + if self.delta: + _dict['delta'] = self.delta.to_dict() + # override the default output from pydantic by calling `to_dict()` of logprobs + if self.logprobs: + _dict['logprobs'] = self.logprobs.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if finish_reason (nullable) is None + # and model_fields_set contains the field + if self.finish_reason is None and "finish_reason" in self.model_fields_set: + _dict['finish_reason'] = None + + # set to None if logprobs (nullable) is None + # and model_fields_set contains the field + if self.logprobs is None and "logprobs" in self.model_fields_set: + _dict['logprobs'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKChunkChoice from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "delta": CCKChoiceDelta.from_dict(obj["delta"]) if obj.get("delta") is not None else None, + "finish_reason": obj.get("finish_reason"), + "index": obj.get("index"), + "logprobs": CCKChoiceLogprobs.from_dict(obj["logprobs"]) if obj.get("logprobs") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_completion_tokens_details.py b/src/otari/_client/models/cck_completion_tokens_details.py new file mode 100644 index 0000000..32073f9 --- /dev/null +++ b/src/otari/_client/models/cck_completion_tokens_details.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKCompletionTokensDetails(BaseModel): + """ + Breakdown of tokens used in a completion. + """ # noqa: E501 + accepted_prediction_tokens: Optional[StrictInt] = None + audio_tokens: Optional[StrictInt] = None + reasoning_tokens: Optional[StrictInt] = None + rejected_prediction_tokens: Optional[StrictInt] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["accepted_prediction_tokens", "audio_tokens", "reasoning_tokens", "rejected_prediction_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKCompletionTokensDetails from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if accepted_prediction_tokens (nullable) is None + # and model_fields_set contains the field + if self.accepted_prediction_tokens is None and "accepted_prediction_tokens" in self.model_fields_set: + _dict['accepted_prediction_tokens'] = None + + # set to None if audio_tokens (nullable) is None + # and model_fields_set contains the field + if self.audio_tokens is None and "audio_tokens" in self.model_fields_set: + _dict['audio_tokens'] = None + + # set to None if reasoning_tokens (nullable) is None + # and model_fields_set contains the field + if self.reasoning_tokens is None and "reasoning_tokens" in self.model_fields_set: + _dict['reasoning_tokens'] = None + + # set to None if rejected_prediction_tokens (nullable) is None + # and model_fields_set contains the field + if self.rejected_prediction_tokens is None and "rejected_prediction_tokens" in self.model_fields_set: + _dict['rejected_prediction_tokens'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKCompletionTokensDetails from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "accepted_prediction_tokens": obj.get("accepted_prediction_tokens"), + "audio_tokens": obj.get("audio_tokens"), + "reasoning_tokens": obj.get("reasoning_tokens"), + "rejected_prediction_tokens": obj.get("rejected_prediction_tokens") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_completion_usage.py b/src/otari/_client/models/cck_completion_usage.py new file mode 100644 index 0000000..a04ee69 --- /dev/null +++ b/src/otari/_client/models/cck_completion_usage.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cck_completion_tokens_details import CCKCompletionTokensDetails +from otari._client.models.cck_prompt_tokens_details import CCKPromptTokensDetails +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKCompletionUsage(BaseModel): + """ + Usage statistics for the completion request. + """ # noqa: E501 + completion_tokens: StrictInt + prompt_tokens: StrictInt + total_tokens: StrictInt + completion_tokens_details: Optional[CCKCompletionTokensDetails] = None + prompt_tokens_details: Optional[CCKPromptTokensDetails] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["completion_tokens", "prompt_tokens", "total_tokens", "completion_tokens_details", "prompt_tokens_details"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKCompletionUsage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of completion_tokens_details + if self.completion_tokens_details: + _dict['completion_tokens_details'] = self.completion_tokens_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of prompt_tokens_details + if self.prompt_tokens_details: + _dict['prompt_tokens_details'] = self.prompt_tokens_details.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if completion_tokens_details (nullable) is None + # and model_fields_set contains the field + if self.completion_tokens_details is None and "completion_tokens_details" in self.model_fields_set: + _dict['completion_tokens_details'] = None + + # set to None if prompt_tokens_details (nullable) is None + # and model_fields_set contains the field + if self.prompt_tokens_details is None and "prompt_tokens_details" in self.model_fields_set: + _dict['prompt_tokens_details'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKCompletionUsage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "completion_tokens": obj.get("completion_tokens"), + "prompt_tokens": obj.get("prompt_tokens"), + "total_tokens": obj.get("total_tokens"), + "completion_tokens_details": CCKCompletionTokensDetails.from_dict(obj["completion_tokens_details"]) if obj.get("completion_tokens_details") is not None else None, + "prompt_tokens_details": CCKPromptTokensDetails.from_dict(obj["prompt_tokens_details"]) if obj.get("prompt_tokens_details") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_prompt_tokens_details.py b/src/otari/_client/models/cck_prompt_tokens_details.py new file mode 100644 index 0000000..9630316 --- /dev/null +++ b/src/otari/_client/models/cck_prompt_tokens_details.py @@ -0,0 +1,113 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKPromptTokensDetails(BaseModel): + """ + Breakdown of tokens used in the prompt. + """ # noqa: E501 + audio_tokens: Optional[StrictInt] = None + cached_tokens: Optional[StrictInt] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["audio_tokens", "cached_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKPromptTokensDetails from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if audio_tokens (nullable) is None + # and model_fields_set contains the field + if self.audio_tokens is None and "audio_tokens" in self.model_fields_set: + _dict['audio_tokens'] = None + + # set to None if cached_tokens (nullable) is None + # and model_fields_set contains the field + if self.cached_tokens is None and "cached_tokens" in self.model_fields_set: + _dict['cached_tokens'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKPromptTokensDetails from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "audio_tokens": obj.get("audio_tokens"), + "cached_tokens": obj.get("cached_tokens") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/cck_reasoning.py b/src/otari/_client/models/cck_reasoning.py new file mode 100644 index 0000000..d58cae3 --- /dev/null +++ b/src/otari/_client/models/cck_reasoning.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKReasoning(BaseModel): + """ + Reasoning content emitted by a model. Serializes as a plain JSON string so that responses are compatible with OpenAI-style clients that expect ``delta.reasoning`` / ``message.reasoning`` to be a string. The Python attribute ``content`` remains available for typed access (e.g. ``message.reasoning.content``). + """ # noqa: E501 + content: StrictStr + __properties: ClassVar[List[str]] = ["content"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKReasoning from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKReasoning from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content") + }) + return _obj + + diff --git a/src/otari/_client/models/cck_top_logprob.py b/src/otari/_client/models/cck_top_logprob.py new file mode 100644 index 0000000..b8173e6 --- /dev/null +++ b/src/otari/_client/models/cck_top_logprob.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CCKTopLogprob(BaseModel): + """ + CCKTopLogprob + """ # noqa: E501 + token: StrictStr + bytes: Optional[List[StrictInt]] = None + logprob: Union[StrictFloat, StrictInt] + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["token", "bytes", "logprob"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CCKTopLogprob from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if bytes (nullable) is None + # and model_fields_set contains the field + if self.bytes is None and "bytes" in self.model_fields_set: + _dict['bytes'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CCKTopLogprob from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "token": obj.get("token"), + "bytes": obj.get("bytes"), + "logprob": obj.get("logprob") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/chat_completion.py b/src/otari/_client/models/chat_completion.py new file mode 100644 index 0000000..5e33613 --- /dev/null +++ b/src/otari/_client/models/chat_completion.py @@ -0,0 +1,149 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cc_choice import CCChoice +from otari._client.models.cc_completion_usage import CCCompletionUsage +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ChatCompletion(BaseModel): + """ + ChatCompletion + """ # noqa: E501 + id: StrictStr + choices: List[CCChoice] + created: StrictInt + model: StrictStr + object: StrictStr + service_tier: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + system_fingerprint: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + usage: Optional[CCCompletionUsage] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "choices", "created", "model", "object", "service_tier", "system_fingerprint", "usage"] + + @field_validator('object') + def object_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['chat.completion']): + raise ValueError("must be one of enum values ('chat.completion')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ChatCompletion from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in choices (list) + _items = [] + if self.choices: + for _item_choices in self.choices: + if _item_choices: + _items.append(_item_choices.to_dict()) + _dict['choices'] = _items + # override the default output from pydantic by calling `to_dict()` of usage + if self.usage: + _dict['usage'] = self.usage.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if service_tier (nullable) is None + # and model_fields_set contains the field + if self.service_tier is None and "service_tier" in self.model_fields_set: + _dict['service_tier'] = None + + # set to None if system_fingerprint (nullable) is None + # and model_fields_set contains the field + if self.system_fingerprint is None and "system_fingerprint" in self.model_fields_set: + _dict['system_fingerprint'] = None + + # set to None if usage (nullable) is None + # and model_fields_set contains the field + if self.usage is None and "usage" in self.model_fields_set: + _dict['usage'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ChatCompletion from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "choices": [CCChoice.from_dict(_item) for _item in obj["choices"]] if obj.get("choices") is not None else None, + "created": obj.get("created"), + "model": obj.get("model"), + "object": obj.get("object"), + "service_tier": obj.get("service_tier"), + "system_fingerprint": obj.get("system_fingerprint"), + "usage": CCCompletionUsage.from_dict(obj["usage"]) if obj.get("usage") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/chat_completion_chunk.py b/src/otari/_client/models/chat_completion_chunk.py new file mode 100644 index 0000000..3b6e819 --- /dev/null +++ b/src/otari/_client/models/chat_completion_chunk.py @@ -0,0 +1,149 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.cck_chunk_choice import CCKChunkChoice +from otari._client.models.cck_completion_usage import CCKCompletionUsage +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ChatCompletionChunk(BaseModel): + """ + ChatCompletionChunk + """ # noqa: E501 + id: StrictStr + choices: List[CCKChunkChoice] + created: StrictInt + model: StrictStr + object: StrictStr + service_tier: Optional[StrictStr] = None + system_fingerprint: Optional[StrictStr] = None + usage: Optional[CCKCompletionUsage] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "choices", "created", "model", "object", "service_tier", "system_fingerprint", "usage"] + + @field_validator('object') + def object_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['chat.completion.chunk']): + raise ValueError("must be one of enum values ('chat.completion.chunk')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ChatCompletionChunk from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in choices (list) + _items = [] + if self.choices: + for _item_choices in self.choices: + if _item_choices: + _items.append(_item_choices.to_dict()) + _dict['choices'] = _items + # override the default output from pydantic by calling `to_dict()` of usage + if self.usage: + _dict['usage'] = self.usage.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if service_tier (nullable) is None + # and model_fields_set contains the field + if self.service_tier is None and "service_tier" in self.model_fields_set: + _dict['service_tier'] = None + + # set to None if system_fingerprint (nullable) is None + # and model_fields_set contains the field + if self.system_fingerprint is None and "system_fingerprint" in self.model_fields_set: + _dict['system_fingerprint'] = None + + # set to None if usage (nullable) is None + # and model_fields_set contains the field + if self.usage is None and "usage" in self.model_fields_set: + _dict['usage'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ChatCompletionChunk from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "choices": [CCKChunkChoice.from_dict(_item) for _item in obj["choices"]] if obj.get("choices") is not None else None, + "created": obj.get("created"), + "model": obj.get("model"), + "object": obj.get("object"), + "service_tier": obj.get("service_tier"), + "system_fingerprint": obj.get("system_fingerprint"), + "usage": CCKCompletionUsage.from_dict(obj["usage"]) if obj.get("usage") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/chat_completion_request.py b/src/otari/_client/models/chat_completion_request.py new file mode 100644 index 0000000..80c0bdf --- /dev/null +++ b/src/otari/_client/models/chat_completion_request.py @@ -0,0 +1,220 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from uuid import UUID +from otari._client.models.chat_message_input import ChatMessageInput +from otari._client.models.guardrail_config import GuardrailConfig +from otari._client.models.mcp_server_config import McpServerConfig +from otari._client.models.tool_choice import ToolChoice +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ChatCompletionRequest(BaseModel): + """ + OpenAI-compatible chat completion request. + """ # noqa: E501 + guardrails: Optional[Annotated[List[GuardrailConfig], Field(max_length=8)]] = None + max_completion_tokens: Optional[StrictInt] = None + max_tokens: Optional[StrictInt] = None + max_tool_iterations: Optional[Annotated[int, Field(le=25, strict=True, ge=1)]] = None + mcp_server_ids: Optional[List[UUID]] = None + mcp_servers: Optional[List[McpServerConfig]] = None + messages: Annotated[List[ChatMessageInput], Field(min_length=1)] + model: StrictStr + response_format: Optional[Dict[str, Any]] = None + stream: Optional[StrictBool] = False + stream_options: Optional[Dict[str, Any]] = None + temperature: Optional[Union[StrictFloat, StrictInt]] = None + tool_choice: Optional[ToolChoice] = None + tools: Optional[List[Optional[Dict[str, Any]]]] = None + tools_header: Optional[Annotated[str, Field(strict=True, max_length=4000)]] = Field(default=None, description="Optional override for the lead-in that the gateway prepends before the per-tool hint block in the system message. Useful for expressing global tool-selection policy (e.g. 'prefer MCP tools over code_execution'). Falls back to GATEWAY_TOOLS_HEADER env, then to the built-in default.") + top_p: Optional[Union[StrictFloat, StrictInt]] = None + user: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["guardrails", "max_completion_tokens", "max_tokens", "max_tool_iterations", "mcp_server_ids", "mcp_servers", "messages", "model", "response_format", "stream", "stream_options", "temperature", "tool_choice", "tools", "tools_header", "top_p", "user"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ChatCompletionRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in guardrails (list) + _items = [] + if self.guardrails: + for _item_guardrails in self.guardrails: + if _item_guardrails: + _items.append(_item_guardrails.to_dict()) + _dict['guardrails'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in mcp_servers (list) + _items = [] + if self.mcp_servers: + for _item_mcp_servers in self.mcp_servers: + if _item_mcp_servers: + _items.append(_item_mcp_servers.to_dict()) + _dict['mcp_servers'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in messages (list) + _items = [] + if self.messages: + for _item_messages in self.messages: + if _item_messages: + _items.append(_item_messages.to_dict()) + _dict['messages'] = _items + # override the default output from pydantic by calling `to_dict()` of tool_choice + if self.tool_choice: + _dict['tool_choice'] = self.tool_choice.to_dict() + # set to None if guardrails (nullable) is None + # and model_fields_set contains the field + if self.guardrails is None and "guardrails" in self.model_fields_set: + _dict['guardrails'] = None + + # set to None if max_completion_tokens (nullable) is None + # and model_fields_set contains the field + if self.max_completion_tokens is None and "max_completion_tokens" in self.model_fields_set: + _dict['max_completion_tokens'] = None + + # set to None if max_tokens (nullable) is None + # and model_fields_set contains the field + if self.max_tokens is None and "max_tokens" in self.model_fields_set: + _dict['max_tokens'] = None + + # set to None if max_tool_iterations (nullable) is None + # and model_fields_set contains the field + if self.max_tool_iterations is None and "max_tool_iterations" in self.model_fields_set: + _dict['max_tool_iterations'] = None + + # set to None if mcp_server_ids (nullable) is None + # and model_fields_set contains the field + if self.mcp_server_ids is None and "mcp_server_ids" in self.model_fields_set: + _dict['mcp_server_ids'] = None + + # set to None if mcp_servers (nullable) is None + # and model_fields_set contains the field + if self.mcp_servers is None and "mcp_servers" in self.model_fields_set: + _dict['mcp_servers'] = None + + # set to None if response_format (nullable) is None + # and model_fields_set contains the field + if self.response_format is None and "response_format" in self.model_fields_set: + _dict['response_format'] = None + + # set to None if stream_options (nullable) is None + # and model_fields_set contains the field + if self.stream_options is None and "stream_options" in self.model_fields_set: + _dict['stream_options'] = None + + # set to None if temperature (nullable) is None + # and model_fields_set contains the field + if self.temperature is None and "temperature" in self.model_fields_set: + _dict['temperature'] = None + + # set to None if tool_choice (nullable) is None + # and model_fields_set contains the field + if self.tool_choice is None and "tool_choice" in self.model_fields_set: + _dict['tool_choice'] = None + + # set to None if tools (nullable) is None + # and model_fields_set contains the field + if self.tools is None and "tools" in self.model_fields_set: + _dict['tools'] = None + + # set to None if tools_header (nullable) is None + # and model_fields_set contains the field + if self.tools_header is None and "tools_header" in self.model_fields_set: + _dict['tools_header'] = None + + # set to None if top_p (nullable) is None + # and model_fields_set contains the field + if self.top_p is None and "top_p" in self.model_fields_set: + _dict['top_p'] = None + + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ChatCompletionRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "guardrails": [GuardrailConfig.from_dict(_item) for _item in obj["guardrails"]] if obj.get("guardrails") is not None else None, + "max_completion_tokens": obj.get("max_completion_tokens"), + "max_tokens": obj.get("max_tokens"), + "max_tool_iterations": obj.get("max_tool_iterations"), + "mcp_server_ids": obj.get("mcp_server_ids"), + "mcp_servers": [McpServerConfig.from_dict(_item) for _item in obj["mcp_servers"]] if obj.get("mcp_servers") is not None else None, + "messages": [ChatMessageInput.from_dict(_item) for _item in obj["messages"]] if obj.get("messages") is not None else None, + "model": obj.get("model"), + "response_format": obj.get("response_format"), + "stream": obj.get("stream") if obj.get("stream") is not None else False, + "stream_options": obj.get("stream_options"), + "temperature": obj.get("temperature"), + "tool_choice": ToolChoice.from_dict(obj["tool_choice"]) if obj.get("tool_choice") is not None else None, + "tools": obj.get("tools"), + "tools_header": obj.get("tools_header"), + "top_p": obj.get("top_p"), + "user": obj.get("user") + }) + return _obj + + diff --git a/src/otari/_client/models/chat_message_input.py b/src/otari/_client/models/chat_message_input.py new file mode 100644 index 0000000..0c59fce --- /dev/null +++ b/src/otari/_client/models/chat_message_input.py @@ -0,0 +1,194 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.msg_chat_completion_assistant_message_param import MSGChatCompletionAssistantMessageParam +from otari._client.models.msg_chat_completion_developer_message_param import MSGChatCompletionDeveloperMessageParam +from otari._client.models.msg_chat_completion_function_message_param import MSGChatCompletionFunctionMessageParam +from otari._client.models.msg_chat_completion_system_message_param import MSGChatCompletionSystemMessageParam +from otari._client.models.msg_chat_completion_tool_message_param import MSGChatCompletionToolMessageParam +from otari._client.models.msg_chat_completion_user_message_param import MSGChatCompletionUserMessageParam +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CHATMESSAGEINPUT_ANY_OF_SCHEMAS = ["MSGChatCompletionAssistantMessageParam", "MSGChatCompletionDeveloperMessageParam", "MSGChatCompletionFunctionMessageParam", "MSGChatCompletionSystemMessageParam", "MSGChatCompletionToolMessageParam", "MSGChatCompletionUserMessageParam"] + +class ChatMessageInput(BaseModel): + """ + ChatMessageInput + """ + + # data type: MSGChatCompletionDeveloperMessageParam + anyof_schema_1_validator: Optional[MSGChatCompletionDeveloperMessageParam] = None + # data type: MSGChatCompletionSystemMessageParam + anyof_schema_2_validator: Optional[MSGChatCompletionSystemMessageParam] = None + # data type: MSGChatCompletionUserMessageParam + anyof_schema_3_validator: Optional[MSGChatCompletionUserMessageParam] = None + # data type: MSGChatCompletionAssistantMessageParam + anyof_schema_4_validator: Optional[MSGChatCompletionAssistantMessageParam] = None + # data type: MSGChatCompletionToolMessageParam + anyof_schema_5_validator: Optional[MSGChatCompletionToolMessageParam] = None + # data type: MSGChatCompletionFunctionMessageParam + anyof_schema_6_validator: Optional[MSGChatCompletionFunctionMessageParam] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MSGChatCompletionAssistantMessageParam, MSGChatCompletionDeveloperMessageParam, MSGChatCompletionFunctionMessageParam, MSGChatCompletionSystemMessageParam, MSGChatCompletionToolMessageParam, MSGChatCompletionUserMessageParam]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MSGChatCompletionAssistantMessageParam", "MSGChatCompletionDeveloperMessageParam", "MSGChatCompletionFunctionMessageParam", "MSGChatCompletionSystemMessageParam", "MSGChatCompletionToolMessageParam", "MSGChatCompletionUserMessageParam" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = ChatMessageInput.model_construct() + error_messages = [] + # validate data type: MSGChatCompletionDeveloperMessageParam + if not isinstance(v, MSGChatCompletionDeveloperMessageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionDeveloperMessageParam`") + else: + return v + + # validate data type: MSGChatCompletionSystemMessageParam + if not isinstance(v, MSGChatCompletionSystemMessageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionSystemMessageParam`") + else: + return v + + # validate data type: MSGChatCompletionUserMessageParam + if not isinstance(v, MSGChatCompletionUserMessageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionUserMessageParam`") + else: + return v + + # validate data type: MSGChatCompletionAssistantMessageParam + if not isinstance(v, MSGChatCompletionAssistantMessageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionAssistantMessageParam`") + else: + return v + + # validate data type: MSGChatCompletionToolMessageParam + if not isinstance(v, MSGChatCompletionToolMessageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionToolMessageParam`") + else: + return v + + # validate data type: MSGChatCompletionFunctionMessageParam + if not isinstance(v, MSGChatCompletionFunctionMessageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionFunctionMessageParam`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in ChatMessageInput with anyOf schemas: MSGChatCompletionAssistantMessageParam, MSGChatCompletionDeveloperMessageParam, MSGChatCompletionFunctionMessageParam, MSGChatCompletionSystemMessageParam, MSGChatCompletionToolMessageParam, MSGChatCompletionUserMessageParam. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MSGChatCompletionDeveloperMessageParam] = None + try: + instance.actual_instance = MSGChatCompletionDeveloperMessageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MSGChatCompletionSystemMessageParam] = None + try: + instance.actual_instance = MSGChatCompletionSystemMessageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MSGChatCompletionUserMessageParam] = None + try: + instance.actual_instance = MSGChatCompletionUserMessageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_4_validator: Optional[MSGChatCompletionAssistantMessageParam] = None + try: + instance.actual_instance = MSGChatCompletionAssistantMessageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_5_validator: Optional[MSGChatCompletionToolMessageParam] = None + try: + instance.actual_instance = MSGChatCompletionToolMessageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_6_validator: Optional[MSGChatCompletionFunctionMessageParam] = None + try: + instance.actual_instance = MSGChatCompletionFunctionMessageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into ChatMessageInput with anyOf schemas: MSGChatCompletionAssistantMessageParam, MSGChatCompletionDeveloperMessageParam, MSGChatCompletionFunctionMessageParam, MSGChatCompletionSystemMessageParam, MSGChatCompletionToolMessageParam, MSGChatCompletionUserMessageParam. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MSGChatCompletionAssistantMessageParam, MSGChatCompletionDeveloperMessageParam, MSGChatCompletionFunctionMessageParam, MSGChatCompletionSystemMessageParam, MSGChatCompletionToolMessageParam, MSGChatCompletionUserMessageParam]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content.py b/src/otari/_client/models/content.py new file mode 100644 index 0000000..b03a3aa --- /dev/null +++ b/src/otari/_client/models/content.py @@ -0,0 +1,145 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import List, Optional +from otari._client.models.content_any_of_inner import ContentAnyOfInner +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT_ANY_OF_SCHEMAS = ["List[ContentAnyOfInner]", "str"] + +class Content(BaseModel): + """ + Content + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: List[ContentAnyOfInner] + anyof_schema_2_validator: Optional[List[ContentAnyOfInner]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[ContentAnyOfInner], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[ContentAnyOfInner]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + if v is None: + return v + + instance = Content.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[ContentAnyOfInner] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content with anyOf schemas: List[ContentAnyOfInner], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + if json_str is None: + return instance + + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[ContentAnyOfInner] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content with anyOf schemas: List[ContentAnyOfInner], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[ContentAnyOfInner], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content1.py b/src/otari/_client/models/content1.py new file mode 100644 index 0000000..2bd24ef --- /dev/null +++ b/src/otari/_client/models/content1.py @@ -0,0 +1,139 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import List, Optional +from otari._client.models.msg_chat_completion_content_part_text_param import MSGChatCompletionContentPartTextParam +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT1_ANY_OF_SCHEMAS = ["List[MSGChatCompletionContentPartTextParam]", "str"] + +class Content1(BaseModel): + """ + Content1 + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: List[MSGChatCompletionContentPartTextParam] + anyof_schema_2_validator: Optional[List[MSGChatCompletionContentPartTextParam]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[MSGChatCompletionContentPartTextParam], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[MSGChatCompletionContentPartTextParam]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content1.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[MSGChatCompletionContentPartTextParam] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content1 with anyOf schemas: List[MSGChatCompletionContentPartTextParam], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[MSGChatCompletionContentPartTextParam] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content1 with anyOf schemas: List[MSGChatCompletionContentPartTextParam], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[MSGChatCompletionContentPartTextParam], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content2.py b/src/otari/_client/models/content2.py new file mode 100644 index 0000000..b56eebf --- /dev/null +++ b/src/otari/_client/models/content2.py @@ -0,0 +1,139 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import List, Optional +from otari._client.models.content2_any_of_inner import Content2AnyOfInner +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT2_ANY_OF_SCHEMAS = ["List[Content2AnyOfInner]", "str"] + +class Content2(BaseModel): + """ + Content2 + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: List[Content2AnyOfInner] + anyof_schema_2_validator: Optional[List[Content2AnyOfInner]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[Content2AnyOfInner], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[Content2AnyOfInner]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content2.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[Content2AnyOfInner] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content2 with anyOf schemas: List[Content2AnyOfInner], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[Content2AnyOfInner] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content2 with anyOf schemas: List[Content2AnyOfInner], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[Content2AnyOfInner], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content2_any_of_inner.py b/src/otari/_client/models/content2_any_of_inner.py new file mode 100644 index 0000000..40320a0 --- /dev/null +++ b/src/otari/_client/models/content2_any_of_inner.py @@ -0,0 +1,164 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.msg_chat_completion_content_part_image_param import MSGChatCompletionContentPartImageParam +from otari._client.models.msg_chat_completion_content_part_input_audio_param import MSGChatCompletionContentPartInputAudioParam +from otari._client.models.msg_chat_completion_content_part_text_param import MSGChatCompletionContentPartTextParam +from otari._client.models.msg_file import MSGFile +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT2ANYOFINNER_ANY_OF_SCHEMAS = ["MSGChatCompletionContentPartImageParam", "MSGChatCompletionContentPartInputAudioParam", "MSGChatCompletionContentPartTextParam", "MSGFile"] + +class Content2AnyOfInner(BaseModel): + """ + Content2AnyOfInner + """ + + # data type: MSGChatCompletionContentPartTextParam + anyof_schema_1_validator: Optional[MSGChatCompletionContentPartTextParam] = None + # data type: MSGChatCompletionContentPartImageParam + anyof_schema_2_validator: Optional[MSGChatCompletionContentPartImageParam] = None + # data type: MSGChatCompletionContentPartInputAudioParam + anyof_schema_3_validator: Optional[MSGChatCompletionContentPartInputAudioParam] = None + # data type: MSGFile + anyof_schema_4_validator: Optional[MSGFile] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MSGChatCompletionContentPartImageParam, MSGChatCompletionContentPartInputAudioParam, MSGChatCompletionContentPartTextParam, MSGFile]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MSGChatCompletionContentPartImageParam", "MSGChatCompletionContentPartInputAudioParam", "MSGChatCompletionContentPartTextParam", "MSGFile" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content2AnyOfInner.model_construct() + error_messages = [] + # validate data type: MSGChatCompletionContentPartTextParam + if not isinstance(v, MSGChatCompletionContentPartTextParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionContentPartTextParam`") + else: + return v + + # validate data type: MSGChatCompletionContentPartImageParam + if not isinstance(v, MSGChatCompletionContentPartImageParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionContentPartImageParam`") + else: + return v + + # validate data type: MSGChatCompletionContentPartInputAudioParam + if not isinstance(v, MSGChatCompletionContentPartInputAudioParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionContentPartInputAudioParam`") + else: + return v + + # validate data type: MSGFile + if not isinstance(v, MSGFile): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGFile`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content2AnyOfInner with anyOf schemas: MSGChatCompletionContentPartImageParam, MSGChatCompletionContentPartInputAudioParam, MSGChatCompletionContentPartTextParam, MSGFile. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MSGChatCompletionContentPartTextParam] = None + try: + instance.actual_instance = MSGChatCompletionContentPartTextParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MSGChatCompletionContentPartImageParam] = None + try: + instance.actual_instance = MSGChatCompletionContentPartImageParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MSGChatCompletionContentPartInputAudioParam] = None + try: + instance.actual_instance = MSGChatCompletionContentPartInputAudioParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_4_validator: Optional[MSGFile] = None + try: + instance.actual_instance = MSGFile.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content2AnyOfInner with anyOf schemas: MSGChatCompletionContentPartImageParam, MSGChatCompletionContentPartInputAudioParam, MSGChatCompletionContentPartTextParam, MSGFile. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MSGChatCompletionContentPartImageParam, MSGChatCompletionContentPartInputAudioParam, MSGChatCompletionContentPartTextParam, MSGFile]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content3.py b/src/otari/_client/models/content3.py new file mode 100644 index 0000000..c684bbe --- /dev/null +++ b/src/otari/_client/models/content3.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_bash_code_execution_result_block import MRBashCodeExecutionResultBlock +from otari._client.models.mr_bash_code_execution_tool_result_error import MRBashCodeExecutionToolResultError +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT3_ANY_OF_SCHEMAS = ["MRBashCodeExecutionResultBlock", "MRBashCodeExecutionToolResultError"] + +class Content3(BaseModel): + """ + Content3 + """ + + # data type: MRBashCodeExecutionToolResultError + anyof_schema_1_validator: Optional[MRBashCodeExecutionToolResultError] = None + # data type: MRBashCodeExecutionResultBlock + anyof_schema_2_validator: Optional[MRBashCodeExecutionResultBlock] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRBashCodeExecutionResultBlock, MRBashCodeExecutionToolResultError]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRBashCodeExecutionResultBlock", "MRBashCodeExecutionToolResultError" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content3.model_construct() + error_messages = [] + # validate data type: MRBashCodeExecutionToolResultError + if not isinstance(v, MRBashCodeExecutionToolResultError): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRBashCodeExecutionToolResultError`") + else: + return v + + # validate data type: MRBashCodeExecutionResultBlock + if not isinstance(v, MRBashCodeExecutionResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRBashCodeExecutionResultBlock`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content3 with anyOf schemas: MRBashCodeExecutionResultBlock, MRBashCodeExecutionToolResultError. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRBashCodeExecutionToolResultError] = None + try: + instance.actual_instance = MRBashCodeExecutionToolResultError.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRBashCodeExecutionResultBlock] = None + try: + instance.actual_instance = MRBashCodeExecutionResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content3 with anyOf schemas: MRBashCodeExecutionResultBlock, MRBashCodeExecutionToolResultError. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRBashCodeExecutionResultBlock, MRBashCodeExecutionToolResultError]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content4.py b/src/otari/_client/models/content4.py new file mode 100644 index 0000000..e1b3b2f --- /dev/null +++ b/src/otari/_client/models/content4.py @@ -0,0 +1,149 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_code_execution_result_block import MRCodeExecutionResultBlock +from otari._client.models.mr_code_execution_tool_result_error import MRCodeExecutionToolResultError +from otari._client.models.mr_encrypted_code_execution_result_block import MREncryptedCodeExecutionResultBlock +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT4_ANY_OF_SCHEMAS = ["MRCodeExecutionResultBlock", "MRCodeExecutionToolResultError", "MREncryptedCodeExecutionResultBlock"] + +class Content4(BaseModel): + """ + Content4 + """ + + # data type: MRCodeExecutionToolResultError + anyof_schema_1_validator: Optional[MRCodeExecutionToolResultError] = None + # data type: MRCodeExecutionResultBlock + anyof_schema_2_validator: Optional[MRCodeExecutionResultBlock] = None + # data type: MREncryptedCodeExecutionResultBlock + anyof_schema_3_validator: Optional[MREncryptedCodeExecutionResultBlock] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRCodeExecutionResultBlock, MRCodeExecutionToolResultError, MREncryptedCodeExecutionResultBlock]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRCodeExecutionResultBlock", "MRCodeExecutionToolResultError", "MREncryptedCodeExecutionResultBlock" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content4.model_construct() + error_messages = [] + # validate data type: MRCodeExecutionToolResultError + if not isinstance(v, MRCodeExecutionToolResultError): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCodeExecutionToolResultError`") + else: + return v + + # validate data type: MRCodeExecutionResultBlock + if not isinstance(v, MRCodeExecutionResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCodeExecutionResultBlock`") + else: + return v + + # validate data type: MREncryptedCodeExecutionResultBlock + if not isinstance(v, MREncryptedCodeExecutionResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MREncryptedCodeExecutionResultBlock`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content4 with anyOf schemas: MRCodeExecutionResultBlock, MRCodeExecutionToolResultError, MREncryptedCodeExecutionResultBlock. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRCodeExecutionToolResultError] = None + try: + instance.actual_instance = MRCodeExecutionToolResultError.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRCodeExecutionResultBlock] = None + try: + instance.actual_instance = MRCodeExecutionResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MREncryptedCodeExecutionResultBlock] = None + try: + instance.actual_instance = MREncryptedCodeExecutionResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content4 with anyOf schemas: MRCodeExecutionResultBlock, MRCodeExecutionToolResultError, MREncryptedCodeExecutionResultBlock. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRCodeExecutionResultBlock, MRCodeExecutionToolResultError, MREncryptedCodeExecutionResultBlock]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content5.py b/src/otari/_client/models/content5.py new file mode 100644 index 0000000..7139a32 --- /dev/null +++ b/src/otari/_client/models/content5.py @@ -0,0 +1,164 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_text_editor_code_execution_create_result_block import MRTextEditorCodeExecutionCreateResultBlock +from otari._client.models.mr_text_editor_code_execution_str_replace_result_block import MRTextEditorCodeExecutionStrReplaceResultBlock +from otari._client.models.mr_text_editor_code_execution_tool_result_error import MRTextEditorCodeExecutionToolResultError +from otari._client.models.mr_text_editor_code_execution_view_result_block import MRTextEditorCodeExecutionViewResultBlock +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT5_ANY_OF_SCHEMAS = ["MRTextEditorCodeExecutionCreateResultBlock", "MRTextEditorCodeExecutionStrReplaceResultBlock", "MRTextEditorCodeExecutionToolResultError", "MRTextEditorCodeExecutionViewResultBlock"] + +class Content5(BaseModel): + """ + Content5 + """ + + # data type: MRTextEditorCodeExecutionToolResultError + anyof_schema_1_validator: Optional[MRTextEditorCodeExecutionToolResultError] = None + # data type: MRTextEditorCodeExecutionViewResultBlock + anyof_schema_2_validator: Optional[MRTextEditorCodeExecutionViewResultBlock] = None + # data type: MRTextEditorCodeExecutionCreateResultBlock + anyof_schema_3_validator: Optional[MRTextEditorCodeExecutionCreateResultBlock] = None + # data type: MRTextEditorCodeExecutionStrReplaceResultBlock + anyof_schema_4_validator: Optional[MRTextEditorCodeExecutionStrReplaceResultBlock] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRTextEditorCodeExecutionCreateResultBlock, MRTextEditorCodeExecutionStrReplaceResultBlock, MRTextEditorCodeExecutionToolResultError, MRTextEditorCodeExecutionViewResultBlock]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRTextEditorCodeExecutionCreateResultBlock", "MRTextEditorCodeExecutionStrReplaceResultBlock", "MRTextEditorCodeExecutionToolResultError", "MRTextEditorCodeExecutionViewResultBlock" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content5.model_construct() + error_messages = [] + # validate data type: MRTextEditorCodeExecutionToolResultError + if not isinstance(v, MRTextEditorCodeExecutionToolResultError): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRTextEditorCodeExecutionToolResultError`") + else: + return v + + # validate data type: MRTextEditorCodeExecutionViewResultBlock + if not isinstance(v, MRTextEditorCodeExecutionViewResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRTextEditorCodeExecutionViewResultBlock`") + else: + return v + + # validate data type: MRTextEditorCodeExecutionCreateResultBlock + if not isinstance(v, MRTextEditorCodeExecutionCreateResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRTextEditorCodeExecutionCreateResultBlock`") + else: + return v + + # validate data type: MRTextEditorCodeExecutionStrReplaceResultBlock + if not isinstance(v, MRTextEditorCodeExecutionStrReplaceResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRTextEditorCodeExecutionStrReplaceResultBlock`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content5 with anyOf schemas: MRTextEditorCodeExecutionCreateResultBlock, MRTextEditorCodeExecutionStrReplaceResultBlock, MRTextEditorCodeExecutionToolResultError, MRTextEditorCodeExecutionViewResultBlock. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRTextEditorCodeExecutionToolResultError] = None + try: + instance.actual_instance = MRTextEditorCodeExecutionToolResultError.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRTextEditorCodeExecutionViewResultBlock] = None + try: + instance.actual_instance = MRTextEditorCodeExecutionViewResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MRTextEditorCodeExecutionCreateResultBlock] = None + try: + instance.actual_instance = MRTextEditorCodeExecutionCreateResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_4_validator: Optional[MRTextEditorCodeExecutionStrReplaceResultBlock] = None + try: + instance.actual_instance = MRTextEditorCodeExecutionStrReplaceResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content5 with anyOf schemas: MRTextEditorCodeExecutionCreateResultBlock, MRTextEditorCodeExecutionStrReplaceResultBlock, MRTextEditorCodeExecutionToolResultError, MRTextEditorCodeExecutionViewResultBlock. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRTextEditorCodeExecutionCreateResultBlock, MRTextEditorCodeExecutionStrReplaceResultBlock, MRTextEditorCodeExecutionToolResultError, MRTextEditorCodeExecutionViewResultBlock]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content6.py b/src/otari/_client/models/content6.py new file mode 100644 index 0000000..9d80fde --- /dev/null +++ b/src/otari/_client/models/content6.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_tool_search_tool_result_error import MRToolSearchToolResultError +from otari._client.models.mr_tool_search_tool_search_result_block import MRToolSearchToolSearchResultBlock +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT6_ANY_OF_SCHEMAS = ["MRToolSearchToolResultError", "MRToolSearchToolSearchResultBlock"] + +class Content6(BaseModel): + """ + Content6 + """ + + # data type: MRToolSearchToolResultError + anyof_schema_1_validator: Optional[MRToolSearchToolResultError] = None + # data type: MRToolSearchToolSearchResultBlock + anyof_schema_2_validator: Optional[MRToolSearchToolSearchResultBlock] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRToolSearchToolResultError, MRToolSearchToolSearchResultBlock]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRToolSearchToolResultError", "MRToolSearchToolSearchResultBlock" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content6.model_construct() + error_messages = [] + # validate data type: MRToolSearchToolResultError + if not isinstance(v, MRToolSearchToolResultError): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRToolSearchToolResultError`") + else: + return v + + # validate data type: MRToolSearchToolSearchResultBlock + if not isinstance(v, MRToolSearchToolSearchResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRToolSearchToolSearchResultBlock`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content6 with anyOf schemas: MRToolSearchToolResultError, MRToolSearchToolSearchResultBlock. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRToolSearchToolResultError] = None + try: + instance.actual_instance = MRToolSearchToolResultError.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRToolSearchToolSearchResultBlock] = None + try: + instance.actual_instance = MRToolSearchToolSearchResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content6 with anyOf schemas: MRToolSearchToolResultError, MRToolSearchToolSearchResultBlock. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRToolSearchToolResultError, MRToolSearchToolSearchResultBlock]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content7.py b/src/otari/_client/models/content7.py new file mode 100644 index 0000000..9d8702a --- /dev/null +++ b/src/otari/_client/models/content7.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_web_fetch_block import MRWebFetchBlock +from otari._client.models.mr_web_fetch_tool_result_error_block import MRWebFetchToolResultErrorBlock +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT7_ANY_OF_SCHEMAS = ["MRWebFetchBlock", "MRWebFetchToolResultErrorBlock"] + +class Content7(BaseModel): + """ + Content7 + """ + + # data type: MRWebFetchToolResultErrorBlock + anyof_schema_1_validator: Optional[MRWebFetchToolResultErrorBlock] = None + # data type: MRWebFetchBlock + anyof_schema_2_validator: Optional[MRWebFetchBlock] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRWebFetchBlock, MRWebFetchToolResultErrorBlock]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRWebFetchBlock", "MRWebFetchToolResultErrorBlock" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content7.model_construct() + error_messages = [] + # validate data type: MRWebFetchToolResultErrorBlock + if not isinstance(v, MRWebFetchToolResultErrorBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRWebFetchToolResultErrorBlock`") + else: + return v + + # validate data type: MRWebFetchBlock + if not isinstance(v, MRWebFetchBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRWebFetchBlock`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content7 with anyOf schemas: MRWebFetchBlock, MRWebFetchToolResultErrorBlock. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRWebFetchToolResultErrorBlock] = None + try: + instance.actual_instance = MRWebFetchToolResultErrorBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRWebFetchBlock] = None + try: + instance.actual_instance = MRWebFetchBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content7 with anyOf schemas: MRWebFetchBlock, MRWebFetchToolResultErrorBlock. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRWebFetchBlock, MRWebFetchToolResultErrorBlock]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content8.py b/src/otari/_client/models/content8.py new file mode 100644 index 0000000..a745767 --- /dev/null +++ b/src/otari/_client/models/content8.py @@ -0,0 +1,137 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import List, Optional +from otari._client.models.mr_web_search_result_block import MRWebSearchResultBlock +from otari._client.models.mr_web_search_tool_result_error import MRWebSearchToolResultError +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT8_ANY_OF_SCHEMAS = ["List[MRWebSearchResultBlock]", "MRWebSearchToolResultError"] + +class Content8(BaseModel): + """ + Content8 + """ + + # data type: MRWebSearchToolResultError + anyof_schema_1_validator: Optional[MRWebSearchToolResultError] = None + # data type: List[MRWebSearchResultBlock] + anyof_schema_2_validator: Optional[List[MRWebSearchResultBlock]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[MRWebSearchResultBlock], MRWebSearchToolResultError]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[MRWebSearchResultBlock]", "MRWebSearchToolResultError" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content8.model_construct() + error_messages = [] + # validate data type: MRWebSearchToolResultError + if not isinstance(v, MRWebSearchToolResultError): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRWebSearchToolResultError`") + else: + return v + + # validate data type: List[MRWebSearchResultBlock] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content8 with anyOf schemas: List[MRWebSearchResultBlock], MRWebSearchToolResultError. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRWebSearchToolResultError] = None + try: + instance.actual_instance = MRWebSearchToolResultError.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[MRWebSearchResultBlock] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content8 with anyOf schemas: List[MRWebSearchResultBlock], MRWebSearchToolResultError. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[MRWebSearchResultBlock], MRWebSearchToolResultError]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content9_inner.py b/src/otari/_client/models/content9_inner.py new file mode 100644 index 0000000..b4fc172 --- /dev/null +++ b/src/otari/_client/models/content9_inner.py @@ -0,0 +1,284 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_bash_code_execution_tool_result_block import MRBashCodeExecutionToolResultBlock +from otari._client.models.mr_code_execution_tool_result_block import MRCodeExecutionToolResultBlock +from otari._client.models.mr_container_upload_block import MRContainerUploadBlock +from otari._client.models.mr_redacted_thinking_block import MRRedactedThinkingBlock +from otari._client.models.mr_server_tool_use_block import MRServerToolUseBlock +from otari._client.models.mr_text_block import MRTextBlock +from otari._client.models.mr_text_editor_code_execution_tool_result_block import MRTextEditorCodeExecutionToolResultBlock +from otari._client.models.mr_thinking_block import MRThinkingBlock +from otari._client.models.mr_tool_search_tool_result_block import MRToolSearchToolResultBlock +from otari._client.models.mr_tool_use_block import MRToolUseBlock +from otari._client.models.mr_web_fetch_tool_result_block import MRWebFetchToolResultBlock +from otari._client.models.mr_web_search_tool_result_block import MRWebSearchToolResultBlock +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENT9INNER_ANY_OF_SCHEMAS = ["MRBashCodeExecutionToolResultBlock", "MRCodeExecutionToolResultBlock", "MRContainerUploadBlock", "MRRedactedThinkingBlock", "MRServerToolUseBlock", "MRTextBlock", "MRTextEditorCodeExecutionToolResultBlock", "MRThinkingBlock", "MRToolSearchToolResultBlock", "MRToolUseBlock", "MRWebFetchToolResultBlock", "MRWebSearchToolResultBlock"] + +class Content9Inner(BaseModel): + """ + Content9Inner + """ + + # data type: MRTextBlock + anyof_schema_1_validator: Optional[MRTextBlock] = None + # data type: MRThinkingBlock + anyof_schema_2_validator: Optional[MRThinkingBlock] = None + # data type: MRRedactedThinkingBlock + anyof_schema_3_validator: Optional[MRRedactedThinkingBlock] = None + # data type: MRToolUseBlock + anyof_schema_4_validator: Optional[MRToolUseBlock] = None + # data type: MRServerToolUseBlock + anyof_schema_5_validator: Optional[MRServerToolUseBlock] = None + # data type: MRWebSearchToolResultBlock + anyof_schema_6_validator: Optional[MRWebSearchToolResultBlock] = None + # data type: MRWebFetchToolResultBlock + anyof_schema_7_validator: Optional[MRWebFetchToolResultBlock] = None + # data type: MRCodeExecutionToolResultBlock + anyof_schema_8_validator: Optional[MRCodeExecutionToolResultBlock] = None + # data type: MRBashCodeExecutionToolResultBlock + anyof_schema_9_validator: Optional[MRBashCodeExecutionToolResultBlock] = None + # data type: MRTextEditorCodeExecutionToolResultBlock + anyof_schema_10_validator: Optional[MRTextEditorCodeExecutionToolResultBlock] = None + # data type: MRToolSearchToolResultBlock + anyof_schema_11_validator: Optional[MRToolSearchToolResultBlock] = None + # data type: MRContainerUploadBlock + anyof_schema_12_validator: Optional[MRContainerUploadBlock] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRBashCodeExecutionToolResultBlock, MRCodeExecutionToolResultBlock, MRContainerUploadBlock, MRRedactedThinkingBlock, MRServerToolUseBlock, MRTextBlock, MRTextEditorCodeExecutionToolResultBlock, MRThinkingBlock, MRToolSearchToolResultBlock, MRToolUseBlock, MRWebFetchToolResultBlock, MRWebSearchToolResultBlock]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRBashCodeExecutionToolResultBlock", "MRCodeExecutionToolResultBlock", "MRContainerUploadBlock", "MRRedactedThinkingBlock", "MRServerToolUseBlock", "MRTextBlock", "MRTextEditorCodeExecutionToolResultBlock", "MRThinkingBlock", "MRToolSearchToolResultBlock", "MRToolUseBlock", "MRWebFetchToolResultBlock", "MRWebSearchToolResultBlock" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Content9Inner.model_construct() + error_messages = [] + # validate data type: MRTextBlock + if not isinstance(v, MRTextBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRTextBlock`") + else: + return v + + # validate data type: MRThinkingBlock + if not isinstance(v, MRThinkingBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRThinkingBlock`") + else: + return v + + # validate data type: MRRedactedThinkingBlock + if not isinstance(v, MRRedactedThinkingBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRRedactedThinkingBlock`") + else: + return v + + # validate data type: MRToolUseBlock + if not isinstance(v, MRToolUseBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRToolUseBlock`") + else: + return v + + # validate data type: MRServerToolUseBlock + if not isinstance(v, MRServerToolUseBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRServerToolUseBlock`") + else: + return v + + # validate data type: MRWebSearchToolResultBlock + if not isinstance(v, MRWebSearchToolResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRWebSearchToolResultBlock`") + else: + return v + + # validate data type: MRWebFetchToolResultBlock + if not isinstance(v, MRWebFetchToolResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRWebFetchToolResultBlock`") + else: + return v + + # validate data type: MRCodeExecutionToolResultBlock + if not isinstance(v, MRCodeExecutionToolResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCodeExecutionToolResultBlock`") + else: + return v + + # validate data type: MRBashCodeExecutionToolResultBlock + if not isinstance(v, MRBashCodeExecutionToolResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRBashCodeExecutionToolResultBlock`") + else: + return v + + # validate data type: MRTextEditorCodeExecutionToolResultBlock + if not isinstance(v, MRTextEditorCodeExecutionToolResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRTextEditorCodeExecutionToolResultBlock`") + else: + return v + + # validate data type: MRToolSearchToolResultBlock + if not isinstance(v, MRToolSearchToolResultBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRToolSearchToolResultBlock`") + else: + return v + + # validate data type: MRContainerUploadBlock + if not isinstance(v, MRContainerUploadBlock): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRContainerUploadBlock`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Content9Inner with anyOf schemas: MRBashCodeExecutionToolResultBlock, MRCodeExecutionToolResultBlock, MRContainerUploadBlock, MRRedactedThinkingBlock, MRServerToolUseBlock, MRTextBlock, MRTextEditorCodeExecutionToolResultBlock, MRThinkingBlock, MRToolSearchToolResultBlock, MRToolUseBlock, MRWebFetchToolResultBlock, MRWebSearchToolResultBlock. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRTextBlock] = None + try: + instance.actual_instance = MRTextBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRThinkingBlock] = None + try: + instance.actual_instance = MRThinkingBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MRRedactedThinkingBlock] = None + try: + instance.actual_instance = MRRedactedThinkingBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_4_validator: Optional[MRToolUseBlock] = None + try: + instance.actual_instance = MRToolUseBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_5_validator: Optional[MRServerToolUseBlock] = None + try: + instance.actual_instance = MRServerToolUseBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_6_validator: Optional[MRWebSearchToolResultBlock] = None + try: + instance.actual_instance = MRWebSearchToolResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_7_validator: Optional[MRWebFetchToolResultBlock] = None + try: + instance.actual_instance = MRWebFetchToolResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_8_validator: Optional[MRCodeExecutionToolResultBlock] = None + try: + instance.actual_instance = MRCodeExecutionToolResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_9_validator: Optional[MRBashCodeExecutionToolResultBlock] = None + try: + instance.actual_instance = MRBashCodeExecutionToolResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_10_validator: Optional[MRTextEditorCodeExecutionToolResultBlock] = None + try: + instance.actual_instance = MRTextEditorCodeExecutionToolResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_11_validator: Optional[MRToolSearchToolResultBlock] = None + try: + instance.actual_instance = MRToolSearchToolResultBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_12_validator: Optional[MRContainerUploadBlock] = None + try: + instance.actual_instance = MRContainerUploadBlock.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Content9Inner with anyOf schemas: MRBashCodeExecutionToolResultBlock, MRCodeExecutionToolResultBlock, MRContainerUploadBlock, MRRedactedThinkingBlock, MRServerToolUseBlock, MRTextBlock, MRTextEditorCodeExecutionToolResultBlock, MRThinkingBlock, MRToolSearchToolResultBlock, MRToolUseBlock, MRWebFetchToolResultBlock, MRWebSearchToolResultBlock. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRBashCodeExecutionToolResultBlock, MRCodeExecutionToolResultBlock, MRContainerUploadBlock, MRRedactedThinkingBlock, MRServerToolUseBlock, MRTextBlock, MRTextEditorCodeExecutionToolResultBlock, MRThinkingBlock, MRToolSearchToolResultBlock, MRToolUseBlock, MRWebFetchToolResultBlock, MRWebSearchToolResultBlock]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/content_any_of_inner.py b/src/otari/_client/models/content_any_of_inner.py new file mode 100644 index 0000000..d58b39f --- /dev/null +++ b/src/otari/_client/models/content_any_of_inner.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.msg_chat_completion_content_part_refusal_param import MSGChatCompletionContentPartRefusalParam +from otari._client.models.msg_chat_completion_content_part_text_param import MSGChatCompletionContentPartTextParam +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +CONTENTANYOFINNER_ANY_OF_SCHEMAS = ["MSGChatCompletionContentPartRefusalParam", "MSGChatCompletionContentPartTextParam"] + +class ContentAnyOfInner(BaseModel): + """ + ContentAnyOfInner + """ + + # data type: MSGChatCompletionContentPartTextParam + anyof_schema_1_validator: Optional[MSGChatCompletionContentPartTextParam] = None + # data type: MSGChatCompletionContentPartRefusalParam + anyof_schema_2_validator: Optional[MSGChatCompletionContentPartRefusalParam] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MSGChatCompletionContentPartRefusalParam, MSGChatCompletionContentPartTextParam]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MSGChatCompletionContentPartRefusalParam", "MSGChatCompletionContentPartTextParam" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = ContentAnyOfInner.model_construct() + error_messages = [] + # validate data type: MSGChatCompletionContentPartTextParam + if not isinstance(v, MSGChatCompletionContentPartTextParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionContentPartTextParam`") + else: + return v + + # validate data type: MSGChatCompletionContentPartRefusalParam + if not isinstance(v, MSGChatCompletionContentPartRefusalParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionContentPartRefusalParam`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in ContentAnyOfInner with anyOf schemas: MSGChatCompletionContentPartRefusalParam, MSGChatCompletionContentPartTextParam. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MSGChatCompletionContentPartTextParam] = None + try: + instance.actual_instance = MSGChatCompletionContentPartTextParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MSGChatCompletionContentPartRefusalParam] = None + try: + instance.actual_instance = MSGChatCompletionContentPartRefusalParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into ContentAnyOfInner with anyOf schemas: MSGChatCompletionContentPartRefusalParam, MSGChatCompletionContentPartTextParam. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MSGChatCompletionContentPartRefusalParam, MSGChatCompletionContentPartTextParam]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/create_batch_request.py b/src/otari/_client/models/create_batch_request.py new file mode 100644 index 0000000..0a6f3dc --- /dev/null +++ b/src/otari/_client/models/create_batch_request.py @@ -0,0 +1,108 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from otari._client.models.batch_request_item import BatchRequestItem +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CreateBatchRequest(BaseModel): + """ + CreateBatchRequest + """ # noqa: E501 + completion_window: Optional[StrictStr] = '24h' + metadata: Optional[Dict[str, StrictStr]] = None + model: StrictStr + requests: Annotated[List[BatchRequestItem], Field(min_length=1, max_length=10000)] + __properties: ClassVar[List[str]] = ["completion_window", "metadata", "model", "requests"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateBatchRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in requests (list) + _items = [] + if self.requests: + for _item_requests in self.requests: + if _item_requests: + _items.append(_item_requests.to_dict()) + _dict['requests'] = _items + # set to None if metadata (nullable) is None + # and model_fields_set contains the field + if self.metadata is None and "metadata" in self.model_fields_set: + _dict['metadata'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateBatchRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "completion_window": obj.get("completion_window") if obj.get("completion_window") is not None else '24h', + "metadata": obj.get("metadata"), + "model": obj.get("model"), + "requests": [BatchRequestItem.from_dict(_item) for _item in obj["requests"]] if obj.get("requests") is not None else None + }) + return _obj + + diff --git a/src/otari/_control_plane/models/create_budget_request.py b/src/otari/_client/models/create_budget_request.py similarity index 100% rename from src/otari/_control_plane/models/create_budget_request.py rename to src/otari/_client/models/create_budget_request.py diff --git a/src/otari/_client/models/create_embedding_response.py b/src/otari/_client/models/create_embedding_response.py new file mode 100644 index 0000000..4b1ef54 --- /dev/null +++ b/src/otari/_client/models/create_embedding_response.py @@ -0,0 +1,126 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.emb_embedding import EMBEmbedding +from otari._client.models.emb_usage import EMBUsage +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class CreateEmbeddingResponse(BaseModel): + """ + CreateEmbeddingResponse + """ # noqa: E501 + data: List[EMBEmbedding] + model: StrictStr + object: StrictStr + usage: EMBUsage + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["data", "model", "object", "usage"] + + @field_validator('object') + def object_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['list']): + raise ValueError("must be one of enum values ('list')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateEmbeddingResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in data (list) + _items = [] + if self.data: + for _item_data in self.data: + if _item_data: + _items.append(_item_data.to_dict()) + _dict['data'] = _items + # override the default output from pydantic by calling `to_dict()` of usage + if self.usage: + _dict['usage'] = self.usage.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateEmbeddingResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "data": [EMBEmbedding.from_dict(_item) for _item in obj["data"]] if obj.get("data") is not None else None, + "model": obj.get("model"), + "object": obj.get("object"), + "usage": EMBUsage.from_dict(obj["usage"]) if obj.get("usage") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_control_plane/models/create_key_request.py b/src/otari/_client/models/create_key_request.py similarity index 100% rename from src/otari/_control_plane/models/create_key_request.py rename to src/otari/_client/models/create_key_request.py diff --git a/src/otari/_control_plane/models/create_key_response.py b/src/otari/_client/models/create_key_response.py similarity index 100% rename from src/otari/_control_plane/models/create_key_response.py rename to src/otari/_client/models/create_key_response.py diff --git a/src/otari/_control_plane/models/create_user_request.py b/src/otari/_client/models/create_user_request.py similarity index 100% rename from src/otari/_control_plane/models/create_user_request.py rename to src/otari/_client/models/create_user_request.py diff --git a/src/otari/_client/models/emb_embedding.py b/src/otari/_client/models/emb_embedding.py new file mode 100644 index 0000000..4cef120 --- /dev/null +++ b/src/otari/_client/models/emb_embedding.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class EMBEmbedding(BaseModel): + """ + Represents an embedding vector returned by embedding endpoint. + """ # noqa: E501 + embedding: List[Union[StrictFloat, StrictInt]] + index: StrictInt + object: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["embedding", "index", "object"] + + @field_validator('object') + def object_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['embedding']): + raise ValueError("must be one of enum values ('embedding')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EMBEmbedding from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of EMBEmbedding from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "embedding": obj.get("embedding"), + "index": obj.get("index"), + "object": obj.get("object") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/emb_usage.py b/src/otari/_client/models/emb_usage.py new file mode 100644 index 0000000..4bbc5be --- /dev/null +++ b/src/otari/_client/models/emb_usage.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class EMBUsage(BaseModel): + """ + The usage information for the request. + """ # noqa: E501 + prompt_tokens: StrictInt + total_tokens: StrictInt + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["prompt_tokens", "total_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EMBUsage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of EMBUsage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "prompt_tokens": obj.get("prompt_tokens"), + "total_tokens": obj.get("total_tokens") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/embedding_request.py b/src/otari/_client/models/embedding_request.py new file mode 100644 index 0000000..4ab6215 --- /dev/null +++ b/src/otari/_client/models/embedding_request.py @@ -0,0 +1,115 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.input import Input +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class EmbeddingRequest(BaseModel): + """ + OpenAI-compatible embedding request. + """ # noqa: E501 + dimensions: Optional[StrictInt] = None + encoding_format: Optional[StrictStr] = None + input: Input + model: StrictStr + user: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["dimensions", "encoding_format", "input", "model", "user"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of EmbeddingRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of input + if self.input: + _dict['input'] = self.input.to_dict() + # set to None if dimensions (nullable) is None + # and model_fields_set contains the field + if self.dimensions is None and "dimensions" in self.model_fields_set: + _dict['dimensions'] = None + + # set to None if encoding_format (nullable) is None + # and model_fields_set contains the field + if self.encoding_format is None and "encoding_format" in self.model_fields_set: + _dict['encoding_format'] = None + + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of EmbeddingRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "dimensions": obj.get("dimensions"), + "encoding_format": obj.get("encoding_format"), + "input": Input.from_dict(obj["input"]) if obj.get("input") is not None else None, + "model": obj.get("model"), + "user": obj.get("user") + }) + return _obj + + diff --git a/src/otari/_client/models/guardrail_config.py b/src/otari/_client/models/guardrail_config.py new file mode 100644 index 0000000..89d663d --- /dev/null +++ b/src/otari/_client/models/guardrail_config.py @@ -0,0 +1,123 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class GuardrailConfig(BaseModel): + """ + A single guardrail check the caller wants the gateway to enforce. URL safety: when ``url`` is supplied it is validated at parse time with the same SSRF guard used for MCP server URLs (loopback allowed by default for same-host sidecars; gated by ``GATEWAY_MCP_ALLOW_LOOPBACK`` / ``GATEWAY_MCP_ALLOW_PRIVATE_HOSTS``). Most deployments omit ``url`` and rely on the operator-set ``GATEWAY_GUARDRAILS_URL`` instead. + """ # noqa: E501 + mode: Optional[StrictStr] = 'monitor' + on: Optional[List[StrictStr]] = None + profile: Annotated[str, Field(min_length=1, strict=True, max_length=128)] + url: Optional[Annotated[str, Field(min_length=1, strict=True)]] = None + validate_kwargs: Optional[Dict[str, Any]] = None + __properties: ClassVar[List[str]] = ["mode", "on", "profile", "url", "validate_kwargs"] + + @field_validator('mode') + def mode_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['block', 'monitor']): + raise ValueError("must be one of enum values ('block', 'monitor')") + return value + + @field_validator('on') + def on_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + for i in value: + if i not in set(['input', 'output']): + raise ValueError("each list item must be one of ('input', 'output')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of GuardrailConfig from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if url (nullable) is None + # and model_fields_set contains the field + if self.url is None and "url" in self.model_fields_set: + _dict['url'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of GuardrailConfig from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "mode": obj.get("mode") if obj.get("mode") is not None else 'monitor', + "on": obj.get("on"), + "profile": obj.get("profile"), + "url": obj.get("url"), + "validate_kwargs": obj.get("validate_kwargs") + }) + return _obj + + diff --git a/src/otari/_control_plane/models/http_validation_error.py b/src/otari/_client/models/http_validation_error.py similarity index 97% rename from src/otari/_control_plane/models/http_validation_error.py rename to src/otari/_client/models/http_validation_error.py index afca717..9adaa01 100644 --- a/src/otari/_control_plane/models/http_validation_error.py +++ b/src/otari/_client/models/http_validation_error.py @@ -19,7 +19,7 @@ from pydantic import BaseModel, ConfigDict from typing import Any, ClassVar, Dict, List, Optional -from otari._control_plane.models.validation_error import ValidationError +from otari._client.models.validation_error import ValidationError from typing import Optional, Set from typing_extensions import Self from pydantic_core import to_jsonable_python diff --git a/src/otari/_client/models/image_generation_request.py b/src/otari/_client/models/image_generation_request.py new file mode 100644 index 0000000..7452d9f --- /dev/null +++ b/src/otari/_client/models/image_generation_request.py @@ -0,0 +1,132 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ImageGenerationRequest(BaseModel): + """ + OpenAI-compatible image generation request. + """ # noqa: E501 + model: StrictStr + n: Optional[StrictInt] = None + prompt: StrictStr + quality: Optional[StrictStr] = None + response_format: Optional[StrictStr] = None + size: Optional[StrictStr] = None + style: Optional[StrictStr] = None + user: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["model", "n", "prompt", "quality", "response_format", "size", "style", "user"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ImageGenerationRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if n (nullable) is None + # and model_fields_set contains the field + if self.n is None and "n" in self.model_fields_set: + _dict['n'] = None + + # set to None if quality (nullable) is None + # and model_fields_set contains the field + if self.quality is None and "quality" in self.model_fields_set: + _dict['quality'] = None + + # set to None if response_format (nullable) is None + # and model_fields_set contains the field + if self.response_format is None and "response_format" in self.model_fields_set: + _dict['response_format'] = None + + # set to None if size (nullable) is None + # and model_fields_set contains the field + if self.size is None and "size" in self.model_fields_set: + _dict['size'] = None + + # set to None if style (nullable) is None + # and model_fields_set contains the field + if self.style is None and "style" in self.model_fields_set: + _dict['style'] = None + + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ImageGenerationRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "model": obj.get("model"), + "n": obj.get("n"), + "prompt": obj.get("prompt"), + "quality": obj.get("quality"), + "response_format": obj.get("response_format"), + "size": obj.get("size"), + "style": obj.get("style"), + "user": obj.get("user") + }) + return _obj + + diff --git a/src/otari/_client/models/input.py b/src/otari/_client/models/input.py new file mode 100644 index 0000000..90b6639 --- /dev/null +++ b/src/otari/_client/models/input.py @@ -0,0 +1,138 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import List, Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +INPUT_ANY_OF_SCHEMAS = ["List[str]", "str"] + +class Input(BaseModel): + """ + Input text to embed + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: List[str] + anyof_schema_2_validator: Optional[List[StrictStr]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[str], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[str]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Input.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[str] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Input with anyOf schemas: List[str], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[str] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Input with anyOf schemas: List[str], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[str], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/input1.py b/src/otari/_client/models/input1.py new file mode 100644 index 0000000..47fa16d --- /dev/null +++ b/src/otari/_client/models/input1.py @@ -0,0 +1,155 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Any, Dict, List, Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +INPUT1_ANY_OF_SCHEMAS = ["List[Dict[str, object]]", "List[str]", "str"] + +class Input1(BaseModel): + """ + Text, list of texts, or list of content-part dicts to moderate + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + # data type: List[str] + anyof_schema_2_validator: Optional[List[StrictStr]] = None + # data type: List[Dict[str, object]] + anyof_schema_3_validator: Optional[List[Dict[str, Any]]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[Dict[str, object]], List[str], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[Dict[str, object]]", "List[str]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Input1.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[str] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[Dict[str, object]] + try: + instance.anyof_schema_3_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Input1 with anyOf schemas: List[Dict[str, object]], List[str], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[str] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[Dict[str, object]] + try: + # validation + instance.anyof_schema_3_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_3_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Input1 with anyOf schemas: List[Dict[str, object]], List[str], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[Dict[str, object]], List[str], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_control_plane/models/key_info.py b/src/otari/_client/models/key_info.py similarity index 100% rename from src/otari/_control_plane/models/key_info.py rename to src/otari/_client/models/key_info.py diff --git a/src/otari/_control_plane/models/location_inner.py b/src/otari/_client/models/location_inner.py similarity index 100% rename from src/otari/_control_plane/models/location_inner.py rename to src/otari/_client/models/location_inner.py diff --git a/src/otari/_client/models/mcp_server_config.py b/src/otari/_client/models/mcp_server_config.py new file mode 100644 index 0000000..f66ffa0 --- /dev/null +++ b/src/otari/_client/models/mcp_server_config.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class McpServerConfig(BaseModel): + """ + Inline MCP server configuration accepted on the chat completions request. Streamable HTTP transport. The `url` must be reachable from the gateway process. URL safety is enforced at parse time: * SSRF guard rejects private, link-local, and reserved IP ranges. Loopback is allowed by default (sidecars, dev) — set ``GATEWAY_MCP_ALLOW_LOOPBACK=false`` to disable. * Plain ``http://`` is rejected when ``authorization_token`` is set, to keep bearer tokens off the wire in cleartext. + """ # noqa: E501 + allowed_tools: Optional[List[StrictStr]] = None + authorization_token: Optional[StrictStr] = None + name: Annotated[str, Field(min_length=1, strict=True, max_length=128)] + purpose_hint: Optional[Annotated[str, Field(strict=True, max_length=2000)]] = None + url: Annotated[str, Field(min_length=1, strict=True)] + __properties: ClassVar[List[str]] = ["allowed_tools", "authorization_token", "name", "purpose_hint", "url"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of McpServerConfig from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if allowed_tools (nullable) is None + # and model_fields_set contains the field + if self.allowed_tools is None and "allowed_tools" in self.model_fields_set: + _dict['allowed_tools'] = None + + # set to None if authorization_token (nullable) is None + # and model_fields_set contains the field + if self.authorization_token is None and "authorization_token" in self.model_fields_set: + _dict['authorization_token'] = None + + # set to None if purpose_hint (nullable) is None + # and model_fields_set contains the field + if self.purpose_hint is None and "purpose_hint" in self.model_fields_set: + _dict['purpose_hint'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of McpServerConfig from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "allowed_tools": obj.get("allowed_tools"), + "authorization_token": obj.get("authorization_token"), + "name": obj.get("name"), + "purpose_hint": obj.get("purpose_hint"), + "url": obj.get("url") + }) + return _obj + + diff --git a/src/otari/_client/models/message_response.py b/src/otari/_client/models/message_response.py new file mode 100644 index 0000000..b8f2149 --- /dev/null +++ b/src/otari/_client/models/message_response.py @@ -0,0 +1,187 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.content9_inner import Content9Inner +from otari._client.models.model import Model +from otari._client.models.mr_container import MRContainer +from otari._client.models.mr_refusal_stop_details import MRRefusalStopDetails +from otari._client.models.mr_usage import MRUsage +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MessageResponse(BaseModel): + """ + MessageResponse + """ # noqa: E501 + id: StrictStr + container: Optional[MRContainer] = None + content: List[Content9Inner] + model: Model + role: StrictStr + stop_details: Optional[MRRefusalStopDetails] = None + stop_reason: Optional[StrictStr] = None + stop_sequence: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + type: StrictStr + usage: MRUsage + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "container", "content", "model", "role", "stop_details", "stop_reason", "stop_sequence", "type", "usage"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['assistant']): + raise ValueError("must be one of enum values ('assistant')") + return value + + @field_validator('stop_reason') + def stop_reason_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['end_turn', 'max_tokens', 'stop_sequence', 'tool_use', 'pause_turn', 'refusal']): + raise ValueError("must be one of enum values ('end_turn', 'max_tokens', 'stop_sequence', 'tool_use', 'pause_turn', 'refusal')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['message']): + raise ValueError("must be one of enum values ('message')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MessageResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of container + if self.container: + _dict['container'] = self.container.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in content (list) + _items = [] + if self.content: + for _item_content in self.content: + if _item_content: + _items.append(_item_content.to_dict()) + _dict['content'] = _items + # override the default output from pydantic by calling `to_dict()` of model + if self.model: + _dict['model'] = self.model.to_dict() + # override the default output from pydantic by calling `to_dict()` of stop_details + if self.stop_details: + _dict['stop_details'] = self.stop_details.to_dict() + # override the default output from pydantic by calling `to_dict()` of usage + if self.usage: + _dict['usage'] = self.usage.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if container (nullable) is None + # and model_fields_set contains the field + if self.container is None and "container" in self.model_fields_set: + _dict['container'] = None + + # set to None if stop_details (nullable) is None + # and model_fields_set contains the field + if self.stop_details is None and "stop_details" in self.model_fields_set: + _dict['stop_details'] = None + + # set to None if stop_reason (nullable) is None + # and model_fields_set contains the field + if self.stop_reason is None and "stop_reason" in self.model_fields_set: + _dict['stop_reason'] = None + + # set to None if stop_sequence (nullable) is None + # and model_fields_set contains the field + if self.stop_sequence is None and "stop_sequence" in self.model_fields_set: + _dict['stop_sequence'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MessageResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "container": MRContainer.from_dict(obj["container"]) if obj.get("container") is not None else None, + "content": [Content9Inner.from_dict(_item) for _item in obj["content"]] if obj.get("content") is not None else None, + "model": Model.from_dict(obj["model"]) if obj.get("model") is not None else None, + "role": obj.get("role"), + "stop_details": MRRefusalStopDetails.from_dict(obj["stop_details"]) if obj.get("stop_details") is not None else None, + "stop_reason": obj.get("stop_reason"), + "stop_sequence": obj.get("stop_sequence"), + "type": obj.get("type"), + "usage": MRUsage.from_dict(obj["usage"]) if obj.get("usage") is not None else None + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/messages_request.py b/src/otari/_client/models/messages_request.py new file mode 100644 index 0000000..8f9b4c8 --- /dev/null +++ b/src/otari/_client/models/messages_request.py @@ -0,0 +1,221 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing_extensions import Annotated +from uuid import UUID +from otari._client.models.guardrail_config import GuardrailConfig +from otari._client.models.mcp_server_config import McpServerConfig +from otari._client.models.system import System +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MessagesRequest(BaseModel): + """ + Anthropic Messages API-compatible request. Gateway-internal fields (``mcp_servers``, ``mcp_server_ids``, ``guardrails``, ``tools_header``, ``max_tool_iterations``) opt the request into gateway-managed MCP / sandbox / web_search / guardrails without changing the upstream wire shape. They're stripped before the request is forwarded. + """ # noqa: E501 + cache_control: Optional[Dict[str, Any]] = None + guardrails: Optional[Annotated[List[GuardrailConfig], Field(max_length=8)]] = None + max_tokens: StrictInt + max_tool_iterations: Optional[Annotated[int, Field(le=25, strict=True, ge=1)]] = None + mcp_server_ids: Optional[List[UUID]] = None + mcp_servers: Optional[List[McpServerConfig]] = None + messages: Annotated[List[Optional[Dict[str, Any]]], Field(min_length=1)] + metadata: Optional[Dict[str, Any]] = None + model: StrictStr + stop_sequences: Optional[List[StrictStr]] = None + stream: Optional[StrictBool] = False + system: Optional[System] = None + temperature: Optional[Union[StrictFloat, StrictInt]] = None + thinking: Optional[Dict[str, Any]] = None + tool_choice: Optional[Dict[str, Any]] = None + tools: Optional[List[Dict[str, Any]]] = None + tools_header: Optional[StrictStr] = None + top_k: Optional[StrictInt] = None + top_p: Optional[Union[StrictFloat, StrictInt]] = None + __properties: ClassVar[List[str]] = ["cache_control", "guardrails", "max_tokens", "max_tool_iterations", "mcp_server_ids", "mcp_servers", "messages", "metadata", "model", "stop_sequences", "stream", "system", "temperature", "thinking", "tool_choice", "tools", "tools_header", "top_k", "top_p"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MessagesRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in guardrails (list) + _items = [] + if self.guardrails: + for _item_guardrails in self.guardrails: + if _item_guardrails: + _items.append(_item_guardrails.to_dict()) + _dict['guardrails'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in mcp_servers (list) + _items = [] + if self.mcp_servers: + for _item_mcp_servers in self.mcp_servers: + if _item_mcp_servers: + _items.append(_item_mcp_servers.to_dict()) + _dict['mcp_servers'] = _items + # override the default output from pydantic by calling `to_dict()` of system + if self.system: + _dict['system'] = self.system.to_dict() + # set to None if cache_control (nullable) is None + # and model_fields_set contains the field + if self.cache_control is None and "cache_control" in self.model_fields_set: + _dict['cache_control'] = None + + # set to None if guardrails (nullable) is None + # and model_fields_set contains the field + if self.guardrails is None and "guardrails" in self.model_fields_set: + _dict['guardrails'] = None + + # set to None if max_tool_iterations (nullable) is None + # and model_fields_set contains the field + if self.max_tool_iterations is None and "max_tool_iterations" in self.model_fields_set: + _dict['max_tool_iterations'] = None + + # set to None if mcp_server_ids (nullable) is None + # and model_fields_set contains the field + if self.mcp_server_ids is None and "mcp_server_ids" in self.model_fields_set: + _dict['mcp_server_ids'] = None + + # set to None if mcp_servers (nullable) is None + # and model_fields_set contains the field + if self.mcp_servers is None and "mcp_servers" in self.model_fields_set: + _dict['mcp_servers'] = None + + # set to None if metadata (nullable) is None + # and model_fields_set contains the field + if self.metadata is None and "metadata" in self.model_fields_set: + _dict['metadata'] = None + + # set to None if stop_sequences (nullable) is None + # and model_fields_set contains the field + if self.stop_sequences is None and "stop_sequences" in self.model_fields_set: + _dict['stop_sequences'] = None + + # set to None if system (nullable) is None + # and model_fields_set contains the field + if self.system is None and "system" in self.model_fields_set: + _dict['system'] = None + + # set to None if temperature (nullable) is None + # and model_fields_set contains the field + if self.temperature is None and "temperature" in self.model_fields_set: + _dict['temperature'] = None + + # set to None if thinking (nullable) is None + # and model_fields_set contains the field + if self.thinking is None and "thinking" in self.model_fields_set: + _dict['thinking'] = None + + # set to None if tool_choice (nullable) is None + # and model_fields_set contains the field + if self.tool_choice is None and "tool_choice" in self.model_fields_set: + _dict['tool_choice'] = None + + # set to None if tools (nullable) is None + # and model_fields_set contains the field + if self.tools is None and "tools" in self.model_fields_set: + _dict['tools'] = None + + # set to None if tools_header (nullable) is None + # and model_fields_set contains the field + if self.tools_header is None and "tools_header" in self.model_fields_set: + _dict['tools_header'] = None + + # set to None if top_k (nullable) is None + # and model_fields_set contains the field + if self.top_k is None and "top_k" in self.model_fields_set: + _dict['top_k'] = None + + # set to None if top_p (nullable) is None + # and model_fields_set contains the field + if self.top_p is None and "top_p" in self.model_fields_set: + _dict['top_p'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MessagesRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cache_control": obj.get("cache_control"), + "guardrails": [GuardrailConfig.from_dict(_item) for _item in obj["guardrails"]] if obj.get("guardrails") is not None else None, + "max_tokens": obj.get("max_tokens"), + "max_tool_iterations": obj.get("max_tool_iterations"), + "mcp_server_ids": obj.get("mcp_server_ids"), + "mcp_servers": [McpServerConfig.from_dict(_item) for _item in obj["mcp_servers"]] if obj.get("mcp_servers") is not None else None, + "messages": obj.get("messages"), + "metadata": obj.get("metadata"), + "model": obj.get("model"), + "stop_sequences": obj.get("stop_sequences"), + "stream": obj.get("stream") if obj.get("stream") is not None else False, + "system": System.from_dict(obj["system"]) if obj.get("system") is not None else None, + "temperature": obj.get("temperature"), + "thinking": obj.get("thinking"), + "tool_choice": obj.get("tool_choice"), + "tools": obj.get("tools"), + "tools_header": obj.get("tools_header"), + "top_k": obj.get("top_k"), + "top_p": obj.get("top_p") + }) + return _obj + + diff --git a/src/otari/_client/models/model.py b/src/otari/_client/models/model.py new file mode 100644 index 0000000..86ca45a --- /dev/null +++ b/src/otari/_client/models/model.py @@ -0,0 +1,138 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +MODEL_ANY_OF_SCHEMAS = ["str"] + +class Model(BaseModel): + """ + Model + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: str + anyof_schema_2_validator: Optional[StrictStr] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Model.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: str + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Model with anyOf schemas: str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into str + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Model with anyOf schemas: str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/model_list_response.py b/src/otari/_client/models/model_list_response.py new file mode 100644 index 0000000..8c8dedb --- /dev/null +++ b/src/otari/_client/models/model_list_response.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.model_object import ModelObject +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ModelListResponse(BaseModel): + """ + OpenAI-compatible model list response. + """ # noqa: E501 + data: List[ModelObject] + object: Optional[StrictStr] = 'list' + __properties: ClassVar[List[str]] = ["data", "object"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ModelListResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in data (list) + _items = [] + if self.data: + for _item_data in self.data: + if _item_data: + _items.append(_item_data.to_dict()) + _dict['data'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ModelListResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "data": [ModelObject.from_dict(_item) for _item in obj["data"]] if obj.get("data") is not None else None, + "object": obj.get("object") if obj.get("object") is not None else 'list' + }) + return _obj + + diff --git a/src/otari/_client/models/model_object.py b/src/otari/_client/models/model_object.py new file mode 100644 index 0000000..6c58a63 --- /dev/null +++ b/src/otari/_client/models/model_object.py @@ -0,0 +1,105 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.model_pricing_info import ModelPricingInfo +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ModelObject(BaseModel): + """ + OpenAI-compatible model object. + """ # noqa: E501 + created: StrictInt + id: StrictStr + object: Optional[StrictStr] = 'model' + owned_by: StrictStr + pricing: Optional[ModelPricingInfo] = None + __properties: ClassVar[List[str]] = ["created", "id", "object", "owned_by", "pricing"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ModelObject from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of pricing + if self.pricing: + _dict['pricing'] = self.pricing.to_dict() + # set to None if pricing (nullable) is None + # and model_fields_set contains the field + if self.pricing is None and "pricing" in self.model_fields_set: + _dict['pricing'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ModelObject from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "created": obj.get("created"), + "id": obj.get("id"), + "object": obj.get("object") if obj.get("object") is not None else 'model', + "owned_by": obj.get("owned_by"), + "pricing": ModelPricingInfo.from_dict(obj["pricing"]) if obj.get("pricing") is not None else None + }) + return _obj + + diff --git a/src/otari/_client/models/model_pricing_info.py b/src/otari/_client/models/model_pricing_info.py new file mode 100644 index 0000000..53b91c6 --- /dev/null +++ b/src/otari/_client/models/model_pricing_info.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt +from typing import Any, ClassVar, Dict, List, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ModelPricingInfo(BaseModel): + """ + Pricing information for a model. + """ # noqa: E501 + input_price_per_million: Union[StrictFloat, StrictInt] + output_price_per_million: Union[StrictFloat, StrictInt] + __properties: ClassVar[List[str]] = ["input_price_per_million", "output_price_per_million"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ModelPricingInfo from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ModelPricingInfo from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "input_price_per_million": obj.get("input_price_per_million"), + "output_price_per_million": obj.get("output_price_per_million") + }) + return _obj + + diff --git a/src/otari/_client/models/moderation_request.py b/src/otari/_client/models/moderation_request.py new file mode 100644 index 0000000..f88e3e0 --- /dev/null +++ b/src/otari/_client/models/moderation_request.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.input1 import Input1 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ModerationRequest(BaseModel): + """ + OpenAI-compatible moderation request. + """ # noqa: E501 + input: Input1 + model: StrictStr + user: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["input", "model", "user"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ModerationRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of input + if self.input: + _dict['input'] = self.input.to_dict() + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ModerationRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "input": Input1.from_dict(obj["input"]) if obj.get("input") is not None else None, + "model": obj.get("model"), + "user": obj.get("user") + }) + return _obj + + diff --git a/src/otari/_client/models/moderation_response.py b/src/otari/_client/models/moderation_response.py new file mode 100644 index 0000000..1e1e198 --- /dev/null +++ b/src/otari/_client/models/moderation_response.py @@ -0,0 +1,100 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from otari._client.models.moderation_result import ModerationResult +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ModerationResponse(BaseModel): + """ + Normalized moderation response across providers. + """ # noqa: E501 + id: StrictStr + model: StrictStr + results: List[ModerationResult] + __properties: ClassVar[List[str]] = ["id", "model", "results"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ModerationResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in results (list) + _items = [] + if self.results: + for _item_results in self.results: + if _item_results: + _items.append(_item_results.to_dict()) + _dict['results'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ModerationResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "model": obj.get("model"), + "results": [ModerationResult.from_dict(_item) for _item in obj["results"]] if obj.get("results") is not None else None + }) + return _obj + + diff --git a/src/otari/_client/models/moderation_result.py b/src/otari/_client/models/moderation_result.py new file mode 100644 index 0000000..228785d --- /dev/null +++ b/src/otari/_client/models/moderation_result.py @@ -0,0 +1,106 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictFloat, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ModerationResult(BaseModel): + """ + A single moderation decision, typically one per input item. + """ # noqa: E501 + categories: Optional[Dict[str, StrictBool]] = None + category_applied_input_types: Optional[Dict[str, List[StrictStr]]] = None + category_scores: Optional[Dict[str, Union[StrictFloat, StrictInt]]] = None + flagged: StrictBool + provider_raw: Optional[Dict[str, Any]] = None + __properties: ClassVar[List[str]] = ["categories", "category_applied_input_types", "category_scores", "flagged", "provider_raw"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ModerationResult from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if category_applied_input_types (nullable) is None + # and model_fields_set contains the field + if self.category_applied_input_types is None and "category_applied_input_types" in self.model_fields_set: + _dict['category_applied_input_types'] = None + + # set to None if provider_raw (nullable) is None + # and model_fields_set contains the field + if self.provider_raw is None and "provider_raw" in self.model_fields_set: + _dict['provider_raw'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ModerationResult from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "categories": obj.get("categories"), + "category_applied_input_types": obj.get("category_applied_input_types"), + "category_scores": obj.get("category_scores"), + "flagged": obj.get("flagged"), + "provider_raw": obj.get("provider_raw") + }) + return _obj + + diff --git a/src/otari/_client/models/mr_base64_pdf_source.py b/src/otari/_client/models/mr_base64_pdf_source.py new file mode 100644 index 0000000..1a75703 --- /dev/null +++ b/src/otari/_client/models/mr_base64_pdf_source.py @@ -0,0 +1,119 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRBase64PDFSource(BaseModel): + """ + MRBase64PDFSource + """ # noqa: E501 + data: StrictStr + media_type: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["data", "media_type", "type"] + + @field_validator('media_type') + def media_type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['application/pdf']): + raise ValueError("must be one of enum values ('application/pdf')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['base64']): + raise ValueError("must be one of enum values ('base64')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRBase64PDFSource from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRBase64PDFSource from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "data": obj.get("data"), + "media_type": obj.get("media_type"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_bash_code_execution_output_block.py b/src/otari/_client/models/mr_bash_code_execution_output_block.py new file mode 100644 index 0000000..de705c2 --- /dev/null +++ b/src/otari/_client/models/mr_bash_code_execution_output_block.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRBashCodeExecutionOutputBlock(BaseModel): + """ + MRBashCodeExecutionOutputBlock + """ # noqa: E501 + file_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["file_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['bash_code_execution_output']): + raise ValueError("must be one of enum values ('bash_code_execution_output')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionOutputBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionOutputBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "file_id": obj.get("file_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_bash_code_execution_result_block.py b/src/otari/_client/models/mr_bash_code_execution_result_block.py new file mode 100644 index 0000000..6f0284e --- /dev/null +++ b/src/otari/_client/models/mr_bash_code_execution_result_block.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.mr_bash_code_execution_output_block import MRBashCodeExecutionOutputBlock +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRBashCodeExecutionResultBlock(BaseModel): + """ + MRBashCodeExecutionResultBlock + """ # noqa: E501 + content: List[MRBashCodeExecutionOutputBlock] + return_code: StrictInt + stderr: StrictStr + stdout: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "return_code", "stderr", "stdout", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['bash_code_execution_result']): + raise ValueError("must be one of enum values ('bash_code_execution_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in content (list) + _items = [] + if self.content: + for _item_content in self.content: + if _item_content: + _items.append(_item_content.to_dict()) + _dict['content'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": [MRBashCodeExecutionOutputBlock.from_dict(_item) for _item in obj["content"]] if obj.get("content") is not None else None, + "return_code": obj.get("return_code"), + "stderr": obj.get("stderr"), + "stdout": obj.get("stdout"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_bash_code_execution_tool_result_block.py b/src/otari/_client/models/mr_bash_code_execution_tool_result_block.py new file mode 100644 index 0000000..2c81ae0 --- /dev/null +++ b/src/otari/_client/models/mr_bash_code_execution_tool_result_block.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.content3 import Content3 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRBashCodeExecutionToolResultBlock(BaseModel): + """ + MRBashCodeExecutionToolResultBlock + """ # noqa: E501 + content: Content3 + tool_use_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "tool_use_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['bash_code_execution_tool_result']): + raise ValueError("must be one of enum values ('bash_code_execution_tool_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionToolResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionToolResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content3.from_dict(obj["content"]) if obj.get("content") is not None else None, + "tool_use_id": obj.get("tool_use_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_bash_code_execution_tool_result_error.py b/src/otari/_client/models/mr_bash_code_execution_tool_result_error.py new file mode 100644 index 0000000..1e778a3 --- /dev/null +++ b/src/otari/_client/models/mr_bash_code_execution_tool_result_error.py @@ -0,0 +1,117 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRBashCodeExecutionToolResultError(BaseModel): + """ + MRBashCodeExecutionToolResultError + """ # noqa: E501 + error_code: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["error_code", "type"] + + @field_validator('error_code') + def error_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded', 'output_file_too_large']): + raise ValueError("must be one of enum values ('invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded', 'output_file_too_large')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['bash_code_execution_tool_result_error']): + raise ValueError("must be one of enum values ('bash_code_execution_tool_result_error')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionToolResultError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRBashCodeExecutionToolResultError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "error_code": obj.get("error_code"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_cache_creation.py b/src/otari/_client/models/mr_cache_creation.py new file mode 100644 index 0000000..72cf31a --- /dev/null +++ b/src/otari/_client/models/mr_cache_creation.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCacheCreation(BaseModel): + """ + MRCacheCreation + """ # noqa: E501 + ephemeral_1h_input_tokens: StrictInt + ephemeral_5m_input_tokens: StrictInt + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["ephemeral_1h_input_tokens", "ephemeral_5m_input_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCacheCreation from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCacheCreation from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "ephemeral_1h_input_tokens": obj.get("ephemeral_1h_input_tokens"), + "ephemeral_5m_input_tokens": obj.get("ephemeral_5m_input_tokens") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_citation_char_location.py b/src/otari/_client/models/mr_citation_char_location.py new file mode 100644 index 0000000..e89c000 --- /dev/null +++ b/src/otari/_client/models/mr_citation_char_location.py @@ -0,0 +1,130 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCitationCharLocation(BaseModel): + """ + MRCitationCharLocation + """ # noqa: E501 + cited_text: StrictStr + document_index: StrictInt + document_title: Optional[StrictStr] = None + end_char_index: StrictInt + file_id: Optional[StrictStr] = None + start_char_index: StrictInt + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cited_text", "document_index", "document_title", "end_char_index", "file_id", "start_char_index", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['char_location']): + raise ValueError("must be one of enum values ('char_location')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCitationCharLocation from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if document_title (nullable) is None + # and model_fields_set contains the field + if self.document_title is None and "document_title" in self.model_fields_set: + _dict['document_title'] = None + + # set to None if file_id (nullable) is None + # and model_fields_set contains the field + if self.file_id is None and "file_id" in self.model_fields_set: + _dict['file_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCitationCharLocation from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cited_text": obj.get("cited_text"), + "document_index": obj.get("document_index"), + "document_title": obj.get("document_title"), + "end_char_index": obj.get("end_char_index"), + "file_id": obj.get("file_id"), + "start_char_index": obj.get("start_char_index"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_citation_content_block_location.py b/src/otari/_client/models/mr_citation_content_block_location.py new file mode 100644 index 0000000..44eb0ef --- /dev/null +++ b/src/otari/_client/models/mr_citation_content_block_location.py @@ -0,0 +1,130 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCitationContentBlockLocation(BaseModel): + """ + MRCitationContentBlockLocation + """ # noqa: E501 + cited_text: StrictStr + document_index: StrictInt + document_title: Optional[StrictStr] = None + end_block_index: StrictInt + file_id: Optional[StrictStr] = None + start_block_index: StrictInt + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cited_text", "document_index", "document_title", "end_block_index", "file_id", "start_block_index", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['content_block_location']): + raise ValueError("must be one of enum values ('content_block_location')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCitationContentBlockLocation from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if document_title (nullable) is None + # and model_fields_set contains the field + if self.document_title is None and "document_title" in self.model_fields_set: + _dict['document_title'] = None + + # set to None if file_id (nullable) is None + # and model_fields_set contains the field + if self.file_id is None and "file_id" in self.model_fields_set: + _dict['file_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCitationContentBlockLocation from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cited_text": obj.get("cited_text"), + "document_index": obj.get("document_index"), + "document_title": obj.get("document_title"), + "end_block_index": obj.get("end_block_index"), + "file_id": obj.get("file_id"), + "start_block_index": obj.get("start_block_index"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_citation_page_location.py b/src/otari/_client/models/mr_citation_page_location.py new file mode 100644 index 0000000..f25af13 --- /dev/null +++ b/src/otari/_client/models/mr_citation_page_location.py @@ -0,0 +1,130 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCitationPageLocation(BaseModel): + """ + MRCitationPageLocation + """ # noqa: E501 + cited_text: StrictStr + document_index: StrictInt + document_title: Optional[StrictStr] = None + end_page_number: StrictInt + file_id: Optional[StrictStr] = None + start_page_number: StrictInt + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cited_text", "document_index", "document_title", "end_page_number", "file_id", "start_page_number", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['page_location']): + raise ValueError("must be one of enum values ('page_location')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCitationPageLocation from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if document_title (nullable) is None + # and model_fields_set contains the field + if self.document_title is None and "document_title" in self.model_fields_set: + _dict['document_title'] = None + + # set to None if file_id (nullable) is None + # and model_fields_set contains the field + if self.file_id is None and "file_id" in self.model_fields_set: + _dict['file_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCitationPageLocation from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cited_text": obj.get("cited_text"), + "document_index": obj.get("document_index"), + "document_title": obj.get("document_title"), + "end_page_number": obj.get("end_page_number"), + "file_id": obj.get("file_id"), + "start_page_number": obj.get("start_page_number"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_citations_config.py b/src/otari/_client/models/mr_citations_config.py new file mode 100644 index 0000000..d28a098 --- /dev/null +++ b/src/otari/_client/models/mr_citations_config.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCitationsConfig(BaseModel): + """ + MRCitationsConfig + """ # noqa: E501 + enabled: StrictBool + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["enabled"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCitationsConfig from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCitationsConfig from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "enabled": obj.get("enabled") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_citations_search_result_location.py b/src/otari/_client/models/mr_citations_search_result_location.py new file mode 100644 index 0000000..d4c7b24 --- /dev/null +++ b/src/otari/_client/models/mr_citations_search_result_location.py @@ -0,0 +1,125 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCitationsSearchResultLocation(BaseModel): + """ + MRCitationsSearchResultLocation + """ # noqa: E501 + cited_text: StrictStr + end_block_index: StrictInt + search_result_index: StrictInt + source: StrictStr + start_block_index: StrictInt + title: Optional[StrictStr] = None + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cited_text", "end_block_index", "search_result_index", "source", "start_block_index", "title", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['search_result_location']): + raise ValueError("must be one of enum values ('search_result_location')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCitationsSearchResultLocation from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if title (nullable) is None + # and model_fields_set contains the field + if self.title is None and "title" in self.model_fields_set: + _dict['title'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCitationsSearchResultLocation from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cited_text": obj.get("cited_text"), + "end_block_index": obj.get("end_block_index"), + "search_result_index": obj.get("search_result_index"), + "source": obj.get("source"), + "start_block_index": obj.get("start_block_index"), + "title": obj.get("title"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_citations_web_search_result_location.py b/src/otari/_client/models/mr_citations_web_search_result_location.py new file mode 100644 index 0000000..0cac01d --- /dev/null +++ b/src/otari/_client/models/mr_citations_web_search_result_location.py @@ -0,0 +1,121 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCitationsWebSearchResultLocation(BaseModel): + """ + MRCitationsWebSearchResultLocation + """ # noqa: E501 + cited_text: StrictStr + encrypted_index: StrictStr + title: Optional[StrictStr] = None + type: StrictStr + url: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cited_text", "encrypted_index", "title", "type", "url"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_search_result_location']): + raise ValueError("must be one of enum values ('web_search_result_location')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCitationsWebSearchResultLocation from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if title (nullable) is None + # and model_fields_set contains the field + if self.title is None and "title" in self.model_fields_set: + _dict['title'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCitationsWebSearchResultLocation from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cited_text": obj.get("cited_text"), + "encrypted_index": obj.get("encrypted_index"), + "title": obj.get("title"), + "type": obj.get("type"), + "url": obj.get("url") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_code_execution_output_block.py b/src/otari/_client/models/mr_code_execution_output_block.py new file mode 100644 index 0000000..f7ec443 --- /dev/null +++ b/src/otari/_client/models/mr_code_execution_output_block.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCodeExecutionOutputBlock(BaseModel): + """ + MRCodeExecutionOutputBlock + """ # noqa: E501 + file_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["file_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['code_execution_output']): + raise ValueError("must be one of enum values ('code_execution_output')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCodeExecutionOutputBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCodeExecutionOutputBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "file_id": obj.get("file_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_code_execution_result_block.py b/src/otari/_client/models/mr_code_execution_result_block.py new file mode 100644 index 0000000..d806e2a --- /dev/null +++ b/src/otari/_client/models/mr_code_execution_result_block.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.mr_code_execution_output_block import MRCodeExecutionOutputBlock +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCodeExecutionResultBlock(BaseModel): + """ + MRCodeExecutionResultBlock + """ # noqa: E501 + content: List[MRCodeExecutionOutputBlock] + return_code: StrictInt + stderr: StrictStr + stdout: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "return_code", "stderr", "stdout", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['code_execution_result']): + raise ValueError("must be one of enum values ('code_execution_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCodeExecutionResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in content (list) + _items = [] + if self.content: + for _item_content in self.content: + if _item_content: + _items.append(_item_content.to_dict()) + _dict['content'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCodeExecutionResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": [MRCodeExecutionOutputBlock.from_dict(_item) for _item in obj["content"]] if obj.get("content") is not None else None, + "return_code": obj.get("return_code"), + "stderr": obj.get("stderr"), + "stdout": obj.get("stdout"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_code_execution_tool_result_block.py b/src/otari/_client/models/mr_code_execution_tool_result_block.py new file mode 100644 index 0000000..4425e2c --- /dev/null +++ b/src/otari/_client/models/mr_code_execution_tool_result_block.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.content4 import Content4 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCodeExecutionToolResultBlock(BaseModel): + """ + MRCodeExecutionToolResultBlock + """ # noqa: E501 + content: Content4 + tool_use_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "tool_use_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['code_execution_tool_result']): + raise ValueError("must be one of enum values ('code_execution_tool_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCodeExecutionToolResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCodeExecutionToolResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content4.from_dict(obj["content"]) if obj.get("content") is not None else None, + "tool_use_id": obj.get("tool_use_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_code_execution_tool_result_error.py b/src/otari/_client/models/mr_code_execution_tool_result_error.py new file mode 100644 index 0000000..9607d88 --- /dev/null +++ b/src/otari/_client/models/mr_code_execution_tool_result_error.py @@ -0,0 +1,117 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRCodeExecutionToolResultError(BaseModel): + """ + MRCodeExecutionToolResultError + """ # noqa: E501 + error_code: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["error_code", "type"] + + @field_validator('error_code') + def error_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded']): + raise ValueError("must be one of enum values ('invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['code_execution_tool_result_error']): + raise ValueError("must be one of enum values ('code_execution_tool_result_error')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRCodeExecutionToolResultError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRCodeExecutionToolResultError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "error_code": obj.get("error_code"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_container.py b/src/otari/_client/models/mr_container.py new file mode 100644 index 0000000..f6138a1 --- /dev/null +++ b/src/otari/_client/models/mr_container.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRContainer(BaseModel): + """ + Information about the container used in the request (for the code execution tool) + """ # noqa: E501 + id: StrictStr + expires_at: datetime + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "expires_at"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRContainer from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRContainer from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "expires_at": obj.get("expires_at") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_container_upload_block.py b/src/otari/_client/models/mr_container_upload_block.py new file mode 100644 index 0000000..71c88b7 --- /dev/null +++ b/src/otari/_client/models/mr_container_upload_block.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRContainerUploadBlock(BaseModel): + """ + Response model for a file uploaded to the container. + """ # noqa: E501 + file_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["file_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['container_upload']): + raise ValueError("must be one of enum values ('container_upload')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRContainerUploadBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRContainerUploadBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "file_id": obj.get("file_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_direct_caller.py b/src/otari/_client/models/mr_direct_caller.py new file mode 100644 index 0000000..89402a7 --- /dev/null +++ b/src/otari/_client/models/mr_direct_caller.py @@ -0,0 +1,108 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRDirectCaller(BaseModel): + """ + Tool invocation directly from the model. + """ # noqa: E501 + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['direct']): + raise ValueError("must be one of enum values ('direct')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRDirectCaller from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRDirectCaller from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_document_block.py b/src/otari/_client/models/mr_document_block.py new file mode 100644 index 0000000..659ffe3 --- /dev/null +++ b/src/otari/_client/models/mr_document_block.py @@ -0,0 +1,132 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.mr_citations_config import MRCitationsConfig +from otari._client.models.source import Source +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRDocumentBlock(BaseModel): + """ + MRDocumentBlock + """ # noqa: E501 + citations: Optional[MRCitationsConfig] = None + source: Source + title: Optional[StrictStr] = None + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["citations", "source", "title", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['document']): + raise ValueError("must be one of enum values ('document')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRDocumentBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of citations + if self.citations: + _dict['citations'] = self.citations.to_dict() + # override the default output from pydantic by calling `to_dict()` of source + if self.source: + _dict['source'] = self.source.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if citations (nullable) is None + # and model_fields_set contains the field + if self.citations is None and "citations" in self.model_fields_set: + _dict['citations'] = None + + # set to None if title (nullable) is None + # and model_fields_set contains the field + if self.title is None and "title" in self.model_fields_set: + _dict['title'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRDocumentBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "citations": MRCitationsConfig.from_dict(obj["citations"]) if obj.get("citations") is not None else None, + "source": Source.from_dict(obj["source"]) if obj.get("source") is not None else None, + "title": obj.get("title"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_encrypted_code_execution_result_block.py b/src/otari/_client/models/mr_encrypted_code_execution_result_block.py new file mode 100644 index 0000000..3b19632 --- /dev/null +++ b/src/otari/_client/models/mr_encrypted_code_execution_result_block.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.mr_code_execution_output_block import MRCodeExecutionOutputBlock +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MREncryptedCodeExecutionResultBlock(BaseModel): + """ + Code execution result with encrypted stdout for PFC + web_search results. + """ # noqa: E501 + content: List[MRCodeExecutionOutputBlock] + encrypted_stdout: StrictStr + return_code: StrictInt + stderr: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "encrypted_stdout", "return_code", "stderr", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['encrypted_code_execution_result']): + raise ValueError("must be one of enum values ('encrypted_code_execution_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MREncryptedCodeExecutionResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in content (list) + _items = [] + if self.content: + for _item_content in self.content: + if _item_content: + _items.append(_item_content.to_dict()) + _dict['content'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MREncryptedCodeExecutionResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": [MRCodeExecutionOutputBlock.from_dict(_item) for _item in obj["content"]] if obj.get("content") is not None else None, + "encrypted_stdout": obj.get("encrypted_stdout"), + "return_code": obj.get("return_code"), + "stderr": obj.get("stderr"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_plain_text_source.py b/src/otari/_client/models/mr_plain_text_source.py new file mode 100644 index 0000000..0f8c0cf --- /dev/null +++ b/src/otari/_client/models/mr_plain_text_source.py @@ -0,0 +1,119 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRPlainTextSource(BaseModel): + """ + MRPlainTextSource + """ # noqa: E501 + data: StrictStr + media_type: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["data", "media_type", "type"] + + @field_validator('media_type') + def media_type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text/plain']): + raise ValueError("must be one of enum values ('text/plain')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text']): + raise ValueError("must be one of enum values ('text')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRPlainTextSource from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRPlainTextSource from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "data": obj.get("data"), + "media_type": obj.get("media_type"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_redacted_thinking_block.py b/src/otari/_client/models/mr_redacted_thinking_block.py new file mode 100644 index 0000000..d7f9321 --- /dev/null +++ b/src/otari/_client/models/mr_redacted_thinking_block.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRRedactedThinkingBlock(BaseModel): + """ + MRRedactedThinkingBlock + """ # noqa: E501 + data: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["data", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['redacted_thinking']): + raise ValueError("must be one of enum values ('redacted_thinking')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRRedactedThinkingBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRRedactedThinkingBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "data": obj.get("data"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_refusal_stop_details.py b/src/otari/_client/models/mr_refusal_stop_details.py new file mode 100644 index 0000000..aa50caf --- /dev/null +++ b/src/otari/_client/models/mr_refusal_stop_details.py @@ -0,0 +1,132 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRRefusalStopDetails(BaseModel): + """ + Structured information about a refusal. + """ # noqa: E501 + category: Optional[StrictStr] = None + explanation: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["category", "explanation", "type"] + + @field_validator('category') + def category_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['cyber', 'bio']): + raise ValueError("must be one of enum values ('cyber', 'bio')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['refusal']): + raise ValueError("must be one of enum values ('refusal')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRRefusalStopDetails from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if category (nullable) is None + # and model_fields_set contains the field + if self.category is None and "category" in self.model_fields_set: + _dict['category'] = None + + # set to None if explanation (nullable) is None + # and model_fields_set contains the field + if self.explanation is None and "explanation" in self.model_fields_set: + _dict['explanation'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRRefusalStopDetails from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "category": obj.get("category"), + "explanation": obj.get("explanation"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_server_tool_caller.py b/src/otari/_client/models/mr_server_tool_caller.py new file mode 100644 index 0000000..7d7c1c2 --- /dev/null +++ b/src/otari/_client/models/mr_server_tool_caller.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRServerToolCaller(BaseModel): + """ + Tool invocation generated by a server-side tool. + """ # noqa: E501 + tool_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["tool_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['code_execution_20250825']): + raise ValueError("must be one of enum values ('code_execution_20250825')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRServerToolCaller from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRServerToolCaller from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "tool_id": obj.get("tool_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_server_tool_caller20260120.py b/src/otari/_client/models/mr_server_tool_caller20260120.py new file mode 100644 index 0000000..32cefc1 --- /dev/null +++ b/src/otari/_client/models/mr_server_tool_caller20260120.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRServerToolCaller20260120(BaseModel): + """ + MRServerToolCaller20260120 + """ # noqa: E501 + tool_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["tool_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['code_execution_20260120']): + raise ValueError("must be one of enum values ('code_execution_20260120')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRServerToolCaller20260120 from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRServerToolCaller20260120 from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "tool_id": obj.get("tool_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_server_tool_usage.py b/src/otari/_client/models/mr_server_tool_usage.py new file mode 100644 index 0000000..33e9b68 --- /dev/null +++ b/src/otari/_client/models/mr_server_tool_usage.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRServerToolUsage(BaseModel): + """ + MRServerToolUsage + """ # noqa: E501 + web_fetch_requests: StrictInt + web_search_requests: StrictInt + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["web_fetch_requests", "web_search_requests"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRServerToolUsage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRServerToolUsage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "web_fetch_requests": obj.get("web_fetch_requests"), + "web_search_requests": obj.get("web_search_requests") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_server_tool_use_block.py b/src/otari/_client/models/mr_server_tool_use_block.py new file mode 100644 index 0000000..85e3bb8 --- /dev/null +++ b/src/otari/_client/models/mr_server_tool_use_block.py @@ -0,0 +1,132 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.caller import Caller +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRServerToolUseBlock(BaseModel): + """ + MRServerToolUseBlock + """ # noqa: E501 + id: StrictStr + caller: Optional[Caller] = None + input: Dict[str, Any] + name: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "caller", "input", "name", "type"] + + @field_validator('name') + def name_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_search', 'web_fetch', 'code_execution', 'bash_code_execution', 'text_editor_code_execution', 'tool_search_tool_regex', 'tool_search_tool_bm25']): + raise ValueError("must be one of enum values ('web_search', 'web_fetch', 'code_execution', 'bash_code_execution', 'text_editor_code_execution', 'tool_search_tool_regex', 'tool_search_tool_bm25')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['server_tool_use']): + raise ValueError("must be one of enum values ('server_tool_use')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRServerToolUseBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of caller + if self.caller: + _dict['caller'] = self.caller.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if caller (nullable) is None + # and model_fields_set contains the field + if self.caller is None and "caller" in self.model_fields_set: + _dict['caller'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRServerToolUseBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "caller": Caller.from_dict(obj["caller"]) if obj.get("caller") is not None else None, + "input": obj.get("input"), + "name": obj.get("name"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_text_block.py b/src/otari/_client/models/mr_text_block.py new file mode 100644 index 0000000..68f23d3 --- /dev/null +++ b/src/otari/_client/models/mr_text_block.py @@ -0,0 +1,125 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.mr_text_block_citations_inner import MRTextBlockCitationsInner +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRTextBlock(BaseModel): + """ + MRTextBlock + """ # noqa: E501 + citations: Optional[List[MRTextBlockCitationsInner]] = None + text: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["citations", "text", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text']): + raise ValueError("must be one of enum values ('text')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRTextBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in citations (list) + _items = [] + if self.citations: + for _item_citations in self.citations: + if _item_citations: + _items.append(_item_citations.to_dict()) + _dict['citations'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if citations (nullable) is None + # and model_fields_set contains the field + if self.citations is None and "citations" in self.model_fields_set: + _dict['citations'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRTextBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "citations": [MRTextBlockCitationsInner.from_dict(_item) for _item in obj["citations"]] if obj.get("citations") is not None else None, + "text": obj.get("text"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_text_block_citations_inner.py b/src/otari/_client/models/mr_text_block_citations_inner.py new file mode 100644 index 0000000..0f9c048 --- /dev/null +++ b/src/otari/_client/models/mr_text_block_citations_inner.py @@ -0,0 +1,179 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_citation_char_location import MRCitationCharLocation +from otari._client.models.mr_citation_content_block_location import MRCitationContentBlockLocation +from otari._client.models.mr_citation_page_location import MRCitationPageLocation +from otari._client.models.mr_citations_search_result_location import MRCitationsSearchResultLocation +from otari._client.models.mr_citations_web_search_result_location import MRCitationsWebSearchResultLocation +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +MRTEXTBLOCKCITATIONSINNER_ANY_OF_SCHEMAS = ["MRCitationCharLocation", "MRCitationContentBlockLocation", "MRCitationPageLocation", "MRCitationsSearchResultLocation", "MRCitationsWebSearchResultLocation"] + +class MRTextBlockCitationsInner(BaseModel): + """ + MRTextBlockCitationsInner + """ + + # data type: MRCitationCharLocation + anyof_schema_1_validator: Optional[MRCitationCharLocation] = None + # data type: MRCitationPageLocation + anyof_schema_2_validator: Optional[MRCitationPageLocation] = None + # data type: MRCitationContentBlockLocation + anyof_schema_3_validator: Optional[MRCitationContentBlockLocation] = None + # data type: MRCitationsWebSearchResultLocation + anyof_schema_4_validator: Optional[MRCitationsWebSearchResultLocation] = None + # data type: MRCitationsSearchResultLocation + anyof_schema_5_validator: Optional[MRCitationsSearchResultLocation] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRCitationCharLocation, MRCitationContentBlockLocation, MRCitationPageLocation, MRCitationsSearchResultLocation, MRCitationsWebSearchResultLocation]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRCitationCharLocation", "MRCitationContentBlockLocation", "MRCitationPageLocation", "MRCitationsSearchResultLocation", "MRCitationsWebSearchResultLocation" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = MRTextBlockCitationsInner.model_construct() + error_messages = [] + # validate data type: MRCitationCharLocation + if not isinstance(v, MRCitationCharLocation): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCitationCharLocation`") + else: + return v + + # validate data type: MRCitationPageLocation + if not isinstance(v, MRCitationPageLocation): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCitationPageLocation`") + else: + return v + + # validate data type: MRCitationContentBlockLocation + if not isinstance(v, MRCitationContentBlockLocation): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCitationContentBlockLocation`") + else: + return v + + # validate data type: MRCitationsWebSearchResultLocation + if not isinstance(v, MRCitationsWebSearchResultLocation): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCitationsWebSearchResultLocation`") + else: + return v + + # validate data type: MRCitationsSearchResultLocation + if not isinstance(v, MRCitationsSearchResultLocation): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRCitationsSearchResultLocation`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in MRTextBlockCitationsInner with anyOf schemas: MRCitationCharLocation, MRCitationContentBlockLocation, MRCitationPageLocation, MRCitationsSearchResultLocation, MRCitationsWebSearchResultLocation. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRCitationCharLocation] = None + try: + instance.actual_instance = MRCitationCharLocation.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRCitationPageLocation] = None + try: + instance.actual_instance = MRCitationPageLocation.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_3_validator: Optional[MRCitationContentBlockLocation] = None + try: + instance.actual_instance = MRCitationContentBlockLocation.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_4_validator: Optional[MRCitationsWebSearchResultLocation] = None + try: + instance.actual_instance = MRCitationsWebSearchResultLocation.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_5_validator: Optional[MRCitationsSearchResultLocation] = None + try: + instance.actual_instance = MRCitationsSearchResultLocation.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into MRTextBlockCitationsInner with anyOf schemas: MRCitationCharLocation, MRCitationContentBlockLocation, MRCitationPageLocation, MRCitationsSearchResultLocation, MRCitationsWebSearchResultLocation. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRCitationCharLocation, MRCitationContentBlockLocation, MRCitationPageLocation, MRCitationsSearchResultLocation, MRCitationsWebSearchResultLocation]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/mr_text_editor_code_execution_create_result_block.py b/src/otari/_client/models/mr_text_editor_code_execution_create_result_block.py new file mode 100644 index 0000000..aff6721 --- /dev/null +++ b/src/otari/_client/models/mr_text_editor_code_execution_create_result_block.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRTextEditorCodeExecutionCreateResultBlock(BaseModel): + """ + MRTextEditorCodeExecutionCreateResultBlock + """ # noqa: E501 + is_file_update: StrictBool + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["is_file_update", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text_editor_code_execution_create_result']): + raise ValueError("must be one of enum values ('text_editor_code_execution_create_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionCreateResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionCreateResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "is_file_update": obj.get("is_file_update"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_text_editor_code_execution_str_replace_result_block.py b/src/otari/_client/models/mr_text_editor_code_execution_str_replace_result_block.py new file mode 100644 index 0000000..c87747a --- /dev/null +++ b/src/otari/_client/models/mr_text_editor_code_execution_str_replace_result_block.py @@ -0,0 +1,143 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRTextEditorCodeExecutionStrReplaceResultBlock(BaseModel): + """ + MRTextEditorCodeExecutionStrReplaceResultBlock + """ # noqa: E501 + lines: Optional[List[StrictStr]] = None + new_lines: Optional[StrictInt] = None + new_start: Optional[StrictInt] = None + old_lines: Optional[StrictInt] = None + old_start: Optional[StrictInt] = None + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["lines", "new_lines", "new_start", "old_lines", "old_start", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text_editor_code_execution_str_replace_result']): + raise ValueError("must be one of enum values ('text_editor_code_execution_str_replace_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionStrReplaceResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if lines (nullable) is None + # and model_fields_set contains the field + if self.lines is None and "lines" in self.model_fields_set: + _dict['lines'] = None + + # set to None if new_lines (nullable) is None + # and model_fields_set contains the field + if self.new_lines is None and "new_lines" in self.model_fields_set: + _dict['new_lines'] = None + + # set to None if new_start (nullable) is None + # and model_fields_set contains the field + if self.new_start is None and "new_start" in self.model_fields_set: + _dict['new_start'] = None + + # set to None if old_lines (nullable) is None + # and model_fields_set contains the field + if self.old_lines is None and "old_lines" in self.model_fields_set: + _dict['old_lines'] = None + + # set to None if old_start (nullable) is None + # and model_fields_set contains the field + if self.old_start is None and "old_start" in self.model_fields_set: + _dict['old_start'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionStrReplaceResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "lines": obj.get("lines"), + "new_lines": obj.get("new_lines"), + "new_start": obj.get("new_start"), + "old_lines": obj.get("old_lines"), + "old_start": obj.get("old_start"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_text_editor_code_execution_tool_result_block.py b/src/otari/_client/models/mr_text_editor_code_execution_tool_result_block.py new file mode 100644 index 0000000..df4a3b9 --- /dev/null +++ b/src/otari/_client/models/mr_text_editor_code_execution_tool_result_block.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.content5 import Content5 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRTextEditorCodeExecutionToolResultBlock(BaseModel): + """ + MRTextEditorCodeExecutionToolResultBlock + """ # noqa: E501 + content: Content5 + tool_use_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "tool_use_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text_editor_code_execution_tool_result']): + raise ValueError("must be one of enum values ('text_editor_code_execution_tool_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionToolResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionToolResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content5.from_dict(obj["content"]) if obj.get("content") is not None else None, + "tool_use_id": obj.get("tool_use_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_text_editor_code_execution_tool_result_error.py b/src/otari/_client/models/mr_text_editor_code_execution_tool_result_error.py new file mode 100644 index 0000000..835e761 --- /dev/null +++ b/src/otari/_client/models/mr_text_editor_code_execution_tool_result_error.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRTextEditorCodeExecutionToolResultError(BaseModel): + """ + MRTextEditorCodeExecutionToolResultError + """ # noqa: E501 + error_code: StrictStr + error_message: Optional[StrictStr] = None + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["error_code", "error_message", "type"] + + @field_validator('error_code') + def error_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded', 'file_not_found']): + raise ValueError("must be one of enum values ('invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded', 'file_not_found')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text_editor_code_execution_tool_result_error']): + raise ValueError("must be one of enum values ('text_editor_code_execution_tool_result_error')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionToolResultError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if error_message (nullable) is None + # and model_fields_set contains the field + if self.error_message is None and "error_message" in self.model_fields_set: + _dict['error_message'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionToolResultError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "error_code": obj.get("error_code"), + "error_message": obj.get("error_message"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_text_editor_code_execution_view_result_block.py b/src/otari/_client/models/mr_text_editor_code_execution_view_result_block.py new file mode 100644 index 0000000..cb3dfa1 --- /dev/null +++ b/src/otari/_client/models/mr_text_editor_code_execution_view_result_block.py @@ -0,0 +1,140 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRTextEditorCodeExecutionViewResultBlock(BaseModel): + """ + MRTextEditorCodeExecutionViewResultBlock + """ # noqa: E501 + content: StrictStr + file_type: StrictStr + num_lines: Optional[StrictInt] = None + start_line: Optional[StrictInt] = None + total_lines: Optional[StrictInt] = None + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "file_type", "num_lines", "start_line", "total_lines", "type"] + + @field_validator('file_type') + def file_type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text', 'image', 'pdf']): + raise ValueError("must be one of enum values ('text', 'image', 'pdf')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text_editor_code_execution_view_result']): + raise ValueError("must be one of enum values ('text_editor_code_execution_view_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionViewResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if num_lines (nullable) is None + # and model_fields_set contains the field + if self.num_lines is None and "num_lines" in self.model_fields_set: + _dict['num_lines'] = None + + # set to None if start_line (nullable) is None + # and model_fields_set contains the field + if self.start_line is None and "start_line" in self.model_fields_set: + _dict['start_line'] = None + + # set to None if total_lines (nullable) is None + # and model_fields_set contains the field + if self.total_lines is None and "total_lines" in self.model_fields_set: + _dict['total_lines'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRTextEditorCodeExecutionViewResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content"), + "file_type": obj.get("file_type"), + "num_lines": obj.get("num_lines"), + "start_line": obj.get("start_line"), + "total_lines": obj.get("total_lines"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_thinking_block.py b/src/otari/_client/models/mr_thinking_block.py new file mode 100644 index 0000000..a0596bd --- /dev/null +++ b/src/otari/_client/models/mr_thinking_block.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRThinkingBlock(BaseModel): + """ + MRThinkingBlock + """ # noqa: E501 + signature: StrictStr + thinking: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["signature", "thinking", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['thinking']): + raise ValueError("must be one of enum values ('thinking')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRThinkingBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRThinkingBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "signature": obj.get("signature"), + "thinking": obj.get("thinking"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_tool_reference_block.py b/src/otari/_client/models/mr_tool_reference_block.py new file mode 100644 index 0000000..0f9190c --- /dev/null +++ b/src/otari/_client/models/mr_tool_reference_block.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRToolReferenceBlock(BaseModel): + """ + MRToolReferenceBlock + """ # noqa: E501 + tool_name: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["tool_name", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['tool_reference']): + raise ValueError("must be one of enum values ('tool_reference')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRToolReferenceBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRToolReferenceBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "tool_name": obj.get("tool_name"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_tool_search_tool_result_block.py b/src/otari/_client/models/mr_tool_search_tool_result_block.py new file mode 100644 index 0000000..ba42f16 --- /dev/null +++ b/src/otari/_client/models/mr_tool_search_tool_result_block.py @@ -0,0 +1,116 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.content6 import Content6 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRToolSearchToolResultBlock(BaseModel): + """ + MRToolSearchToolResultBlock + """ # noqa: E501 + content: Content6 + tool_use_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "tool_use_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['tool_search_tool_result']): + raise ValueError("must be one of enum values ('tool_search_tool_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRToolSearchToolResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRToolSearchToolResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content6.from_dict(obj["content"]) if obj.get("content") is not None else None, + "tool_use_id": obj.get("tool_use_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_tool_search_tool_result_error.py b/src/otari/_client/models/mr_tool_search_tool_result_error.py new file mode 100644 index 0000000..9d456e6 --- /dev/null +++ b/src/otari/_client/models/mr_tool_search_tool_result_error.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRToolSearchToolResultError(BaseModel): + """ + MRToolSearchToolResultError + """ # noqa: E501 + error_code: StrictStr + error_message: Optional[StrictStr] = None + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["error_code", "error_message", "type"] + + @field_validator('error_code') + def error_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded']): + raise ValueError("must be one of enum values ('invalid_tool_input', 'unavailable', 'too_many_requests', 'execution_time_exceeded')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['tool_search_tool_result_error']): + raise ValueError("must be one of enum values ('tool_search_tool_result_error')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRToolSearchToolResultError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if error_message (nullable) is None + # and model_fields_set contains the field + if self.error_message is None and "error_message" in self.model_fields_set: + _dict['error_message'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRToolSearchToolResultError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "error_code": obj.get("error_code"), + "error_message": obj.get("error_message"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_tool_search_tool_search_result_block.py b/src/otari/_client/models/mr_tool_search_tool_search_result_block.py new file mode 100644 index 0000000..7e6ec0d --- /dev/null +++ b/src/otari/_client/models/mr_tool_search_tool_search_result_block.py @@ -0,0 +1,118 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.mr_tool_reference_block import MRToolReferenceBlock +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRToolSearchToolSearchResultBlock(BaseModel): + """ + MRToolSearchToolSearchResultBlock + """ # noqa: E501 + tool_references: List[MRToolReferenceBlock] + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["tool_references", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['tool_search_tool_search_result']): + raise ValueError("must be one of enum values ('tool_search_tool_search_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRToolSearchToolSearchResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in tool_references (list) + _items = [] + if self.tool_references: + for _item_tool_references in self.tool_references: + if _item_tool_references: + _items.append(_item_tool_references.to_dict()) + _dict['tool_references'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRToolSearchToolSearchResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "tool_references": [MRToolReferenceBlock.from_dict(_item) for _item in obj["tool_references"]] if obj.get("tool_references") is not None else None, + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_tool_use_block.py b/src/otari/_client/models/mr_tool_use_block.py new file mode 100644 index 0000000..f291389 --- /dev/null +++ b/src/otari/_client/models/mr_tool_use_block.py @@ -0,0 +1,125 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.caller import Caller +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRToolUseBlock(BaseModel): + """ + MRToolUseBlock + """ # noqa: E501 + id: StrictStr + caller: Optional[Caller] = None + input: Dict[str, Any] + name: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "caller", "input", "name", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['tool_use']): + raise ValueError("must be one of enum values ('tool_use')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRToolUseBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of caller + if self.caller: + _dict['caller'] = self.caller.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if caller (nullable) is None + # and model_fields_set contains the field + if self.caller is None and "caller" in self.model_fields_set: + _dict['caller'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRToolUseBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "caller": Caller.from_dict(obj["caller"]) if obj.get("caller") is not None else None, + "input": obj.get("input"), + "name": obj.get("name"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_usage.py b/src/otari/_client/models/mr_usage.py new file mode 100644 index 0000000..d9f799c --- /dev/null +++ b/src/otari/_client/models/mr_usage.py @@ -0,0 +1,163 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.mr_cache_creation import MRCacheCreation +from otari._client.models.mr_server_tool_usage import MRServerToolUsage +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRUsage(BaseModel): + """ + MRUsage + """ # noqa: E501 + cache_creation: Optional[MRCacheCreation] = None + cache_creation_input_tokens: Optional[StrictInt] = None + cache_read_input_tokens: Optional[StrictInt] = None + inference_geo: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + input_tokens: StrictInt + output_tokens: StrictInt + server_tool_use: Optional[MRServerToolUsage] = None + service_tier: Optional[StrictStr] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["cache_creation", "cache_creation_input_tokens", "cache_read_input_tokens", "inference_geo", "input_tokens", "output_tokens", "server_tool_use", "service_tier"] + + @field_validator('service_tier') + def service_tier_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['standard', 'priority', 'batch']): + raise ValueError("must be one of enum values ('standard', 'priority', 'batch')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRUsage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of cache_creation + if self.cache_creation: + _dict['cache_creation'] = self.cache_creation.to_dict() + # override the default output from pydantic by calling `to_dict()` of server_tool_use + if self.server_tool_use: + _dict['server_tool_use'] = self.server_tool_use.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if cache_creation (nullable) is None + # and model_fields_set contains the field + if self.cache_creation is None and "cache_creation" in self.model_fields_set: + _dict['cache_creation'] = None + + # set to None if cache_creation_input_tokens (nullable) is None + # and model_fields_set contains the field + if self.cache_creation_input_tokens is None and "cache_creation_input_tokens" in self.model_fields_set: + _dict['cache_creation_input_tokens'] = None + + # set to None if cache_read_input_tokens (nullable) is None + # and model_fields_set contains the field + if self.cache_read_input_tokens is None and "cache_read_input_tokens" in self.model_fields_set: + _dict['cache_read_input_tokens'] = None + + # set to None if inference_geo (nullable) is None + # and model_fields_set contains the field + if self.inference_geo is None and "inference_geo" in self.model_fields_set: + _dict['inference_geo'] = None + + # set to None if server_tool_use (nullable) is None + # and model_fields_set contains the field + if self.server_tool_use is None and "server_tool_use" in self.model_fields_set: + _dict['server_tool_use'] = None + + # set to None if service_tier (nullable) is None + # and model_fields_set contains the field + if self.service_tier is None and "service_tier" in self.model_fields_set: + _dict['service_tier'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRUsage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "cache_creation": MRCacheCreation.from_dict(obj["cache_creation"]) if obj.get("cache_creation") is not None else None, + "cache_creation_input_tokens": obj.get("cache_creation_input_tokens"), + "cache_read_input_tokens": obj.get("cache_read_input_tokens"), + "inference_geo": obj.get("inference_geo"), + "input_tokens": obj.get("input_tokens"), + "output_tokens": obj.get("output_tokens"), + "server_tool_use": MRServerToolUsage.from_dict(obj["server_tool_use"]) if obj.get("server_tool_use") is not None else None, + "service_tier": obj.get("service_tier") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_web_fetch_block.py b/src/otari/_client/models/mr_web_fetch_block.py new file mode 100644 index 0000000..9008b44 --- /dev/null +++ b/src/otari/_client/models/mr_web_fetch_block.py @@ -0,0 +1,123 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.mr_document_block import MRDocumentBlock +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRWebFetchBlock(BaseModel): + """ + MRWebFetchBlock + """ # noqa: E501 + content: MRDocumentBlock + retrieved_at: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + type: StrictStr + url: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["content", "retrieved_at", "type", "url"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_fetch_result']): + raise ValueError("must be one of enum values ('web_fetch_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRWebFetchBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if retrieved_at (nullable) is None + # and model_fields_set contains the field + if self.retrieved_at is None and "retrieved_at" in self.model_fields_set: + _dict['retrieved_at'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRWebFetchBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": MRDocumentBlock.from_dict(obj["content"]) if obj.get("content") is not None else None, + "retrieved_at": obj.get("retrieved_at"), + "type": obj.get("type"), + "url": obj.get("url") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_web_fetch_tool_result_block.py b/src/otari/_client/models/mr_web_fetch_tool_result_block.py new file mode 100644 index 0000000..be167d8 --- /dev/null +++ b/src/otari/_client/models/mr_web_fetch_tool_result_block.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.caller import Caller +from otari._client.models.content7 import Content7 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRWebFetchToolResultBlock(BaseModel): + """ + MRWebFetchToolResultBlock + """ # noqa: E501 + caller: Optional[Caller] = None + content: Content7 + tool_use_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["caller", "content", "tool_use_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_fetch_tool_result']): + raise ValueError("must be one of enum values ('web_fetch_tool_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRWebFetchToolResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of caller + if self.caller: + _dict['caller'] = self.caller.to_dict() + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if caller (nullable) is None + # and model_fields_set contains the field + if self.caller is None and "caller" in self.model_fields_set: + _dict['caller'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRWebFetchToolResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "caller": Caller.from_dict(obj["caller"]) if obj.get("caller") is not None else None, + "content": Content7.from_dict(obj["content"]) if obj.get("content") is not None else None, + "tool_use_id": obj.get("tool_use_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_web_fetch_tool_result_error_block.py b/src/otari/_client/models/mr_web_fetch_tool_result_error_block.py new file mode 100644 index 0000000..ae3c349 --- /dev/null +++ b/src/otari/_client/models/mr_web_fetch_tool_result_error_block.py @@ -0,0 +1,117 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRWebFetchToolResultErrorBlock(BaseModel): + """ + MRWebFetchToolResultErrorBlock + """ # noqa: E501 + error_code: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["error_code", "type"] + + @field_validator('error_code') + def error_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['invalid_tool_input', 'url_too_long', 'url_not_allowed', 'url_not_accessible', 'unsupported_content_type', 'too_many_requests', 'max_uses_exceeded', 'unavailable']): + raise ValueError("must be one of enum values ('invalid_tool_input', 'url_too_long', 'url_not_allowed', 'url_not_accessible', 'unsupported_content_type', 'too_many_requests', 'max_uses_exceeded', 'unavailable')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_fetch_tool_result_error']): + raise ValueError("must be one of enum values ('web_fetch_tool_result_error')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRWebFetchToolResultErrorBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRWebFetchToolResultErrorBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "error_code": obj.get("error_code"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_web_search_result_block.py b/src/otari/_client/models/mr_web_search_result_block.py new file mode 100644 index 0000000..7aea46b --- /dev/null +++ b/src/otari/_client/models/mr_web_search_result_block.py @@ -0,0 +1,121 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRWebSearchResultBlock(BaseModel): + """ + MRWebSearchResultBlock + """ # noqa: E501 + encrypted_content: StrictStr + page_age: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + title: StrictStr + type: StrictStr + url: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["encrypted_content", "page_age", "title", "type", "url"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_search_result']): + raise ValueError("must be one of enum values ('web_search_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRWebSearchResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if page_age (nullable) is None + # and model_fields_set contains the field + if self.page_age is None and "page_age" in self.model_fields_set: + _dict['page_age'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRWebSearchResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "encrypted_content": obj.get("encrypted_content"), + "page_age": obj.get("page_age"), + "title": obj.get("title"), + "type": obj.get("type"), + "url": obj.get("url") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_web_search_tool_result_block.py b/src/otari/_client/models/mr_web_search_tool_result_block.py new file mode 100644 index 0000000..a50cf76 --- /dev/null +++ b/src/otari/_client/models/mr_web_search_tool_result_block.py @@ -0,0 +1,127 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.caller import Caller +from otari._client.models.content8 import Content8 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRWebSearchToolResultBlock(BaseModel): + """ + MRWebSearchToolResultBlock + """ # noqa: E501 + caller: Optional[Caller] = None + content: Content8 + tool_use_id: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["caller", "content", "tool_use_id", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_search_tool_result']): + raise ValueError("must be one of enum values ('web_search_tool_result')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRWebSearchToolResultBlock from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of caller + if self.caller: + _dict['caller'] = self.caller.to_dict() + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if caller (nullable) is None + # and model_fields_set contains the field + if self.caller is None and "caller" in self.model_fields_set: + _dict['caller'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRWebSearchToolResultBlock from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "caller": Caller.from_dict(obj["caller"]) if obj.get("caller") is not None else None, + "content": Content8.from_dict(obj["content"]) if obj.get("content") is not None else None, + "tool_use_id": obj.get("tool_use_id"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/mr_web_search_tool_result_error.py b/src/otari/_client/models/mr_web_search_tool_result_error.py new file mode 100644 index 0000000..85797c0 --- /dev/null +++ b/src/otari/_client/models/mr_web_search_tool_result_error.py @@ -0,0 +1,117 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MRWebSearchToolResultError(BaseModel): + """ + MRWebSearchToolResultError + """ # noqa: E501 + error_code: StrictStr + type: StrictStr + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["error_code", "type"] + + @field_validator('error_code') + def error_code_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['invalid_tool_input', 'unavailable', 'max_uses_exceeded', 'too_many_requests', 'query_too_long', 'request_too_large']): + raise ValueError("must be one of enum values ('invalid_tool_input', 'unavailable', 'max_uses_exceeded', 'too_many_requests', 'query_too_long', 'request_too_large')") + return value + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['web_search_tool_result_error']): + raise ValueError("must be one of enum values ('web_search_tool_result_error')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MRWebSearchToolResultError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MRWebSearchToolResultError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "error_code": obj.get("error_code"), + "type": obj.get("type") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/msg_audio.py b/src/otari/_client/models/msg_audio.py new file mode 100644 index 0000000..ae38f46 --- /dev/null +++ b/src/otari/_client/models/msg_audio.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGAudio(BaseModel): + """ + Data about a previous audio response from the model. [Learn more](https://platform.openai.com/docs/guides/audio). + """ # noqa: E501 + id: StrictStr + __properties: ClassVar[List[str]] = ["id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGAudio from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGAudio from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_assistant_message_param.py b/src/otari/_client/models/msg_chat_completion_assistant_message_param.py new file mode 100644 index 0000000..c00d128 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_assistant_message_param.py @@ -0,0 +1,147 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.content import Content +from otari._client.models.msg_audio import MSGAudio +from otari._client.models.msg_function_call import MSGFunctionCall +from otari._client.models.tool_calls_inner import ToolCallsInner +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionAssistantMessageParam(BaseModel): + """ + Messages sent by the model in response to user messages. + """ # noqa: E501 + role: StrictStr + audio: Optional[MSGAudio] = None + content: Optional[Content] = None + function_call: Optional[MSGFunctionCall] = None + name: Optional[StrictStr] = None + refusal: Optional[StrictStr] = None + tool_calls: Optional[List[ToolCallsInner]] = None + __properties: ClassVar[List[str]] = ["role", "audio", "content", "function_call", "name", "refusal", "tool_calls"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['assistant']): + raise ValueError("must be one of enum values ('assistant')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionAssistantMessageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of audio + if self.audio: + _dict['audio'] = self.audio.to_dict() + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + # override the default output from pydantic by calling `to_dict()` of function_call + if self.function_call: + _dict['function_call'] = self.function_call.to_dict() + # override the default output from pydantic by calling `to_dict()` of each item in tool_calls (list) + _items = [] + if self.tool_calls: + for _item_tool_calls in self.tool_calls: + if _item_tool_calls: + _items.append(_item_tool_calls.to_dict()) + _dict['tool_calls'] = _items + # set to None if audio (nullable) is None + # and model_fields_set contains the field + if self.audio is None and "audio" in self.model_fields_set: + _dict['audio'] = None + + # set to None if content (nullable) is None + # and model_fields_set contains the field + if self.content is None and "content" in self.model_fields_set: + _dict['content'] = None + + # set to None if function_call (nullable) is None + # and model_fields_set contains the field + if self.function_call is None and "function_call" in self.model_fields_set: + _dict['function_call'] = None + + # set to None if refusal (nullable) is None + # and model_fields_set contains the field + if self.refusal is None and "refusal" in self.model_fields_set: + _dict['refusal'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionAssistantMessageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "role": obj.get("role"), + "audio": MSGAudio.from_dict(obj["audio"]) if obj.get("audio") is not None else None, + "content": Content.from_dict(obj["content"]) if obj.get("content") is not None else None, + "function_call": MSGFunctionCall.from_dict(obj["function_call"]) if obj.get("function_call") is not None else None, + "name": obj.get("name"), + "refusal": obj.get("refusal"), + "tool_calls": [ToolCallsInner.from_dict(_item) for _item in obj["tool_calls"]] if obj.get("tool_calls") is not None else None + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_content_part_image_param.py b/src/otari/_client/models/msg_chat_completion_content_part_image_param.py new file mode 100644 index 0000000..5efe5de --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_content_part_image_param.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.msg_image_url import MSGImageURL +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionContentPartImageParam(BaseModel): + """ + Learn about [image inputs](https://platform.openai.com/docs/guides/vision). + """ # noqa: E501 + image_url: MSGImageURL + type: StrictStr + __properties: ClassVar[List[str]] = ["image_url", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['image_url']): + raise ValueError("must be one of enum values ('image_url')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartImageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of image_url + if self.image_url: + _dict['image_url'] = self.image_url.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartImageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "image_url": MSGImageURL.from_dict(obj["image_url"]) if obj.get("image_url") is not None else None, + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_content_part_input_audio_param.py b/src/otari/_client/models/msg_chat_completion_content_part_input_audio_param.py new file mode 100644 index 0000000..6ea1b92 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_content_part_input_audio_param.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.msg_input_audio import MSGInputAudio +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionContentPartInputAudioParam(BaseModel): + """ + Learn about [audio inputs](https://platform.openai.com/docs/guides/audio). + """ # noqa: E501 + input_audio: MSGInputAudio + type: StrictStr + __properties: ClassVar[List[str]] = ["input_audio", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['input_audio']): + raise ValueError("must be one of enum values ('input_audio')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartInputAudioParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of input_audio + if self.input_audio: + _dict['input_audio'] = self.input_audio.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartInputAudioParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "input_audio": MSGInputAudio.from_dict(obj["input_audio"]) if obj.get("input_audio") is not None else None, + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_content_part_refusal_param.py b/src/otari/_client/models/msg_chat_completion_content_part_refusal_param.py new file mode 100644 index 0000000..05eaf05 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_content_part_refusal_param.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionContentPartRefusalParam(BaseModel): + """ + MSGChatCompletionContentPartRefusalParam + """ # noqa: E501 + refusal: StrictStr + type: StrictStr + __properties: ClassVar[List[str]] = ["refusal", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['refusal']): + raise ValueError("must be one of enum values ('refusal')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartRefusalParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartRefusalParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "refusal": obj.get("refusal"), + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_content_part_text_param.py b/src/otari/_client/models/msg_chat_completion_content_part_text_param.py new file mode 100644 index 0000000..77092fc --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_content_part_text_param.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionContentPartTextParam(BaseModel): + """ + Learn about [text inputs](https://platform.openai.com/docs/guides/text-generation). + """ # noqa: E501 + text: StrictStr + type: StrictStr + __properties: ClassVar[List[str]] = ["text", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['text']): + raise ValueError("must be one of enum values ('text')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartTextParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionContentPartTextParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "text": obj.get("text"), + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_developer_message_param.py b/src/otari/_client/models/msg_chat_completion_developer_message_param.py new file mode 100644 index 0000000..26a85c7 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_developer_message_param.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.content1 import Content1 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionDeveloperMessageParam(BaseModel): + """ + Developer-provided instructions that the model should follow, regardless of messages sent by the user. With o1 models and newer, `developer` messages replace the previous `system` messages. + """ # noqa: E501 + content: Content1 + role: StrictStr + name: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["content", "role", "name"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['developer']): + raise ValueError("must be one of enum values ('developer')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionDeveloperMessageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionDeveloperMessageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content1.from_dict(obj["content"]) if obj.get("content") is not None else None, + "role": obj.get("role"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_function_message_param.py b/src/otari/_client/models/msg_chat_completion_function_message_param.py new file mode 100644 index 0000000..25dc541 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_function_message_param.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionFunctionMessageParam(BaseModel): + """ + MSGChatCompletionFunctionMessageParam + """ # noqa: E501 + content: Optional[StrictStr] + name: StrictStr + role: StrictStr + __properties: ClassVar[List[str]] = ["content", "name", "role"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['function']): + raise ValueError("must be one of enum values ('function')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionFunctionMessageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if content (nullable) is None + # and model_fields_set contains the field + if self.content is None and "content" in self.model_fields_set: + _dict['content'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionFunctionMessageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content"), + "name": obj.get("name"), + "role": obj.get("role") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_message_custom_tool_call_param.py b/src/otari/_client/models/msg_chat_completion_message_custom_tool_call_param.py new file mode 100644 index 0000000..668e929 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_message_custom_tool_call_param.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.msg_custom import MSGCustom +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionMessageCustomToolCallParam(BaseModel): + """ + A call to a custom tool created by the model. + """ # noqa: E501 + id: StrictStr + custom: MSGCustom + type: StrictStr + __properties: ClassVar[List[str]] = ["id", "custom", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['custom']): + raise ValueError("must be one of enum values ('custom')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionMessageCustomToolCallParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of custom + if self.custom: + _dict['custom'] = self.custom.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionMessageCustomToolCallParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "custom": MSGCustom.from_dict(obj["custom"]) if obj.get("custom") is not None else None, + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_message_function_tool_call_param.py b/src/otari/_client/models/msg_chat_completion_message_function_tool_call_param.py new file mode 100644 index 0000000..e3bfea3 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_message_function_tool_call_param.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.msg_function import MSGFunction +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionMessageFunctionToolCallParam(BaseModel): + """ + A call to a function tool created by the model. + """ # noqa: E501 + id: StrictStr + function: MSGFunction + type: StrictStr + __properties: ClassVar[List[str]] = ["id", "function", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['function']): + raise ValueError("must be one of enum values ('function')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionMessageFunctionToolCallParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of function + if self.function: + _dict['function'] = self.function.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionMessageFunctionToolCallParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "function": MSGFunction.from_dict(obj["function"]) if obj.get("function") is not None else None, + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_system_message_param.py b/src/otari/_client/models/msg_chat_completion_system_message_param.py new file mode 100644 index 0000000..8545409 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_system_message_param.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.content1 import Content1 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionSystemMessageParam(BaseModel): + """ + Developer-provided instructions that the model should follow, regardless of messages sent by the user. With o1 models and newer, use `developer` messages for this purpose instead. + """ # noqa: E501 + content: Content1 + role: StrictStr + name: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["content", "role", "name"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['system']): + raise ValueError("must be one of enum values ('system')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionSystemMessageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionSystemMessageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content1.from_dict(obj["content"]) if obj.get("content") is not None else None, + "role": obj.get("role"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_tool_message_param.py b/src/otari/_client/models/msg_chat_completion_tool_message_param.py new file mode 100644 index 0000000..05c7cb7 --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_tool_message_param.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.content1 import Content1 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionToolMessageParam(BaseModel): + """ + MSGChatCompletionToolMessageParam + """ # noqa: E501 + content: Content1 + role: StrictStr + tool_call_id: StrictStr + __properties: ClassVar[List[str]] = ["content", "role", "tool_call_id"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['tool']): + raise ValueError("must be one of enum values ('tool')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionToolMessageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionToolMessageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content1.from_dict(obj["content"]) if obj.get("content") is not None else None, + "role": obj.get("role"), + "tool_call_id": obj.get("tool_call_id") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_chat_completion_user_message_param.py b/src/otari/_client/models/msg_chat_completion_user_message_param.py new file mode 100644 index 0000000..22a41bc --- /dev/null +++ b/src/otari/_client/models/msg_chat_completion_user_message_param.py @@ -0,0 +1,103 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.content2 import Content2 +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGChatCompletionUserMessageParam(BaseModel): + """ + Messages sent by an end user, containing prompts or additional context information. + """ # noqa: E501 + content: Content2 + role: StrictStr + name: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["content", "role", "name"] + + @field_validator('role') + def role_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['user']): + raise ValueError("must be one of enum values ('user')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGChatCompletionUserMessageParam from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of content + if self.content: + _dict['content'] = self.content.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGChatCompletionUserMessageParam from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": Content2.from_dict(obj["content"]) if obj.get("content") is not None else None, + "role": obj.get("role"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_custom.py b/src/otari/_client/models/msg_custom.py new file mode 100644 index 0000000..745476c --- /dev/null +++ b/src/otari/_client/models/msg_custom.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGCustom(BaseModel): + """ + The custom tool that the model called. + """ # noqa: E501 + input: StrictStr + name: StrictStr + __properties: ClassVar[List[str]] = ["input", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGCustom from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGCustom from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "input": obj.get("input"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_file.py b/src/otari/_client/models/msg_file.py new file mode 100644 index 0000000..a2a2bb0 --- /dev/null +++ b/src/otari/_client/models/msg_file.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from otari._client.models.msg_file_file import MSGFileFile +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGFile(BaseModel): + """ + Learn about [file inputs](https://platform.openai.com/docs/guides/text) for text generation. + """ # noqa: E501 + file: MSGFileFile + type: StrictStr + __properties: ClassVar[List[str]] = ["file", "type"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['file']): + raise ValueError("must be one of enum values ('file')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGFile from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of file + if self.file: + _dict['file'] = self.file.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGFile from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "file": MSGFileFile.from_dict(obj["file"]) if obj.get("file") is not None else None, + "type": obj.get("type") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_file_file.py b/src/otari/_client/models/msg_file_file.py new file mode 100644 index 0000000..22d968d --- /dev/null +++ b/src/otari/_client/models/msg_file_file.py @@ -0,0 +1,92 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGFileFile(BaseModel): + """ + MSGFileFile + """ # noqa: E501 + file_data: Optional[StrictStr] = None + file_id: Optional[StrictStr] = None + filename: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["file_data", "file_id", "filename"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGFileFile from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGFileFile from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "file_data": obj.get("file_data"), + "file_id": obj.get("file_id"), + "filename": obj.get("filename") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_function.py b/src/otari/_client/models/msg_function.py new file mode 100644 index 0000000..819d208 --- /dev/null +++ b/src/otari/_client/models/msg_function.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGFunction(BaseModel): + """ + The function that the model called. + """ # noqa: E501 + arguments: StrictStr + name: StrictStr + __properties: ClassVar[List[str]] = ["arguments", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGFunction from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGFunction from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "arguments": obj.get("arguments"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_function_call.py b/src/otari/_client/models/msg_function_call.py new file mode 100644 index 0000000..4ffa450 --- /dev/null +++ b/src/otari/_client/models/msg_function_call.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGFunctionCall(BaseModel): + """ + Deprecated and replaced by `tool_calls`. The name and arguments of a function that should be called, as generated by the model. + """ # noqa: E501 + arguments: StrictStr + name: StrictStr + __properties: ClassVar[List[str]] = ["arguments", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGFunctionCall from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGFunctionCall from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "arguments": obj.get("arguments"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_image_url.py b/src/otari/_client/models/msg_image_url.py new file mode 100644 index 0000000..12b3dec --- /dev/null +++ b/src/otari/_client/models/msg_image_url.py @@ -0,0 +1,100 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGImageURL(BaseModel): + """ + MSGImageURL + """ # noqa: E501 + url: StrictStr + detail: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["url", "detail"] + + @field_validator('detail') + def detail_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['auto', 'low', 'high']): + raise ValueError("must be one of enum values ('auto', 'low', 'high')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGImageURL from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGImageURL from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "url": obj.get("url"), + "detail": obj.get("detail") + }) + return _obj + + diff --git a/src/otari/_client/models/msg_input_audio.py b/src/otari/_client/models/msg_input_audio.py new file mode 100644 index 0000000..7f70699 --- /dev/null +++ b/src/otari/_client/models/msg_input_audio.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MSGInputAudio(BaseModel): + """ + MSGInputAudio + """ # noqa: E501 + data: StrictStr + format: StrictStr + __properties: ClassVar[List[str]] = ["data", "format"] + + @field_validator('format') + def format_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['wav', 'mp3']): + raise ValueError("must be one of enum values ('wav', 'mp3')") + return value + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MSGInputAudio from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MSGInputAudio from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "data": obj.get("data"), + "format": obj.get("format") + }) + return _obj + + diff --git a/src/otari/_control_plane/models/pricing_response.py b/src/otari/_client/models/pricing_response.py similarity index 100% rename from src/otari/_control_plane/models/pricing_response.py rename to src/otari/_client/models/pricing_response.py diff --git a/src/otari/_client/models/rerank_request.py b/src/otari/_client/models/rerank_request.py new file mode 100644 index 0000000..3e210cf --- /dev/null +++ b/src/otari/_client/models/rerank_request.py @@ -0,0 +1,114 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class RerankRequest(BaseModel): + """ + Rerank request. + """ # noqa: E501 + documents: Annotated[List[StrictStr], Field(min_length=1)] = Field(description="List of document strings to rerank") + max_tokens_per_doc: Optional[Annotated[int, Field(strict=True, gt=0)]] = Field(default=None, description="Per-document truncation limit") + model: StrictStr = Field(description="Provider-prefixed model ID, e.g. 'cohere:rerank-v3.5'") + query: StrictStr = Field(description="The search query to rerank documents against") + top_n: Optional[Annotated[int, Field(strict=True, gt=0)]] = Field(default=None, description="Maximum number of results to return") + user: Optional[StrictStr] = Field(default=None, description="User ID for usage attribution") + __properties: ClassVar[List[str]] = ["documents", "max_tokens_per_doc", "model", "query", "top_n", "user"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RerankRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if max_tokens_per_doc (nullable) is None + # and model_fields_set contains the field + if self.max_tokens_per_doc is None and "max_tokens_per_doc" in self.model_fields_set: + _dict['max_tokens_per_doc'] = None + + # set to None if top_n (nullable) is None + # and model_fields_set contains the field + if self.top_n is None and "top_n" in self.model_fields_set: + _dict['top_n'] = None + + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RerankRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "documents": obj.get("documents"), + "max_tokens_per_doc": obj.get("max_tokens_per_doc"), + "model": obj.get("model"), + "query": obj.get("query"), + "top_n": obj.get("top_n"), + "user": obj.get("user") + }) + return _obj + + diff --git a/src/otari/_client/models/rerank_response.py b/src/otari/_client/models/rerank_response.py new file mode 100644 index 0000000..0d78070 --- /dev/null +++ b/src/otari/_client/models/rerank_response.py @@ -0,0 +1,125 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from otari._client.models.rr_rerank_meta import RRRerankMeta +from otari._client.models.rr_rerank_result import RRRerankResult +from otari._client.models.rr_rerank_usage import RRRerankUsage +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class RerankResponse(BaseModel): + """ + Normalized rerank response, provider-agnostic. + """ # noqa: E501 + id: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + results: List[RRRerankResult] = Field(description="Results sorted by relevance_score descending") + meta: Optional[RRRerankMeta] = None + usage: Optional[RRRerankUsage] = None + __properties: ClassVar[List[str]] = ["id", "results", "meta", "usage"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RerankResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in results (list) + _items = [] + if self.results: + for _item_results in self.results: + if _item_results: + _items.append(_item_results.to_dict()) + _dict['results'] = _items + # override the default output from pydantic by calling `to_dict()` of meta + if self.meta: + _dict['meta'] = self.meta.to_dict() + # override the default output from pydantic by calling `to_dict()` of usage + if self.usage: + _dict['usage'] = self.usage.to_dict() + # set to None if id (nullable) is None + # and model_fields_set contains the field + if self.id is None and "id" in self.model_fields_set: + _dict['id'] = None + + # set to None if meta (nullable) is None + # and model_fields_set contains the field + if self.meta is None and "meta" in self.model_fields_set: + _dict['meta'] = None + + # set to None if usage (nullable) is None + # and model_fields_set contains the field + if self.usage is None and "usage" in self.model_fields_set: + _dict['usage'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RerankResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "results": [RRRerankResult.from_dict(_item) for _item in obj["results"]] if obj.get("results") is not None else None, + "meta": RRRerankMeta.from_dict(obj["meta"]) if obj.get("meta") is not None else None, + "usage": RRRerankUsage.from_dict(obj["usage"]) if obj.get("usage") is not None else None + }) + return _obj + + diff --git a/src/otari/_client/models/responses_request.py b/src/otari/_client/models/responses_request.py new file mode 100644 index 0000000..881440a --- /dev/null +++ b/src/otari/_client/models/responses_request.py @@ -0,0 +1,177 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from uuid import UUID +from otari._client.models.guardrail_config import GuardrailConfig +from otari._client.models.mcp_server_config import McpServerConfig +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class ResponsesRequest(BaseModel): + """ + OpenAI Responses API-compatible request. Gateway-internal fields (``mcp_servers``, ``mcp_server_ids``, ``guardrails``, ``tools_header``, ``max_tool_iterations``) opt the request into gateway-managed MCP / sandbox / web_search / guardrails without changing the upstream wire shape. They're stripped before the request is forwarded. + """ # noqa: E501 + guardrails: Optional[Annotated[List[GuardrailConfig], Field(max_length=8)]] = None + input: Optional[Any] + max_tool_iterations: Optional[Annotated[int, Field(le=25, strict=True, ge=1)]] = None + mcp_server_ids: Optional[List[UUID]] = None + mcp_servers: Optional[List[McpServerConfig]] = None + model: StrictStr + stream: Optional[StrictBool] = False + tools: Optional[List[Dict[str, Any]]] = None + tools_header: Optional[StrictStr] = None + user: Optional[StrictStr] = None + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["guardrails", "input", "max_tool_iterations", "mcp_server_ids", "mcp_servers", "model", "stream", "tools", "tools_header", "user"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ResponsesRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in guardrails (list) + _items = [] + if self.guardrails: + for _item_guardrails in self.guardrails: + if _item_guardrails: + _items.append(_item_guardrails.to_dict()) + _dict['guardrails'] = _items + # override the default output from pydantic by calling `to_dict()` of each item in mcp_servers (list) + _items = [] + if self.mcp_servers: + for _item_mcp_servers in self.mcp_servers: + if _item_mcp_servers: + _items.append(_item_mcp_servers.to_dict()) + _dict['mcp_servers'] = _items + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + # set to None if guardrails (nullable) is None + # and model_fields_set contains the field + if self.guardrails is None and "guardrails" in self.model_fields_set: + _dict['guardrails'] = None + + # set to None if input (nullable) is None + # and model_fields_set contains the field + if self.input is None and "input" in self.model_fields_set: + _dict['input'] = None + + # set to None if max_tool_iterations (nullable) is None + # and model_fields_set contains the field + if self.max_tool_iterations is None and "max_tool_iterations" in self.model_fields_set: + _dict['max_tool_iterations'] = None + + # set to None if mcp_server_ids (nullable) is None + # and model_fields_set contains the field + if self.mcp_server_ids is None and "mcp_server_ids" in self.model_fields_set: + _dict['mcp_server_ids'] = None + + # set to None if mcp_servers (nullable) is None + # and model_fields_set contains the field + if self.mcp_servers is None and "mcp_servers" in self.model_fields_set: + _dict['mcp_servers'] = None + + # set to None if tools (nullable) is None + # and model_fields_set contains the field + if self.tools is None and "tools" in self.model_fields_set: + _dict['tools'] = None + + # set to None if tools_header (nullable) is None + # and model_fields_set contains the field + if self.tools_header is None and "tools_header" in self.model_fields_set: + _dict['tools_header'] = None + + # set to None if user (nullable) is None + # and model_fields_set contains the field + if self.user is None and "user" in self.model_fields_set: + _dict['user'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ResponsesRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "guardrails": [GuardrailConfig.from_dict(_item) for _item in obj["guardrails"]] if obj.get("guardrails") is not None else None, + "input": obj.get("input"), + "max_tool_iterations": obj.get("max_tool_iterations"), + "mcp_server_ids": obj.get("mcp_server_ids"), + "mcp_servers": [McpServerConfig.from_dict(_item) for _item in obj["mcp_servers"]] if obj.get("mcp_servers") is not None else None, + "model": obj.get("model"), + "stream": obj.get("stream") if obj.get("stream") is not None else False, + "tools": obj.get("tools"), + "tools_header": obj.get("tools_header"), + "user": obj.get("user") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/src/otari/_client/models/rr_rerank_meta.py b/src/otari/_client/models/rr_rerank_meta.py new file mode 100644 index 0000000..865c2a7 --- /dev/null +++ b/src/otari/_client/models/rr_rerank_meta.py @@ -0,0 +1,100 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt +from typing import Any, ClassVar, Dict, List, Optional, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class RRRerankMeta(BaseModel): + """ + Provider-specific billing metadata (optional, preserved as-is). + """ # noqa: E501 + billed_units: Optional[Dict[str, Union[StrictFloat, StrictInt]]] = None + tokens: Optional[Dict[str, StrictInt]] = None + __properties: ClassVar[List[str]] = ["billed_units", "tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RRRerankMeta from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if billed_units (nullable) is None + # and model_fields_set contains the field + if self.billed_units is None and "billed_units" in self.model_fields_set: + _dict['billed_units'] = None + + # set to None if tokens (nullable) is None + # and model_fields_set contains the field + if self.tokens is None and "tokens" in self.model_fields_set: + _dict['tokens'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RRRerankMeta from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "billed_units": obj.get("billed_units"), + "tokens": obj.get("tokens") + }) + return _obj + + diff --git a/src/otari/_client/models/rr_rerank_result.py b/src/otari/_client/models/rr_rerank_result.py new file mode 100644 index 0000000..9aad3e9 --- /dev/null +++ b/src/otari/_client/models/rr_rerank_result.py @@ -0,0 +1,90 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt +from typing import Any, ClassVar, Dict, List, Union +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class RRRerankResult(BaseModel): + """ + A single document's relevance score. + """ # noqa: E501 + index: StrictInt = Field(description="Zero-based index into the original documents list") + relevance_score: Union[StrictFloat, StrictInt] = Field(description="Relevance score, higher is more relevant") + __properties: ClassVar[List[str]] = ["index", "relevance_score"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RRRerankResult from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RRRerankResult from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "index": obj.get("index"), + "relevance_score": obj.get("relevance_score") + }) + return _obj + + diff --git a/src/otari/_client/models/rr_rerank_usage.py b/src/otari/_client/models/rr_rerank_usage.py new file mode 100644 index 0000000..d4bd875 --- /dev/null +++ b/src/otari/_client/models/rr_rerank_usage.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class RRRerankUsage(BaseModel): + """ + Normalized token usage for gateway logging. + """ # noqa: E501 + total_tokens: Optional[StrictInt] = None + __properties: ClassVar[List[str]] = ["total_tokens"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RRRerankUsage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if total_tokens (nullable) is None + # and model_fields_set contains the field + if self.total_tokens is None and "total_tokens" in self.model_fields_set: + _dict['total_tokens'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RRRerankUsage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "total_tokens": obj.get("total_tokens") + }) + return _obj + + diff --git a/src/otari/_control_plane/models/set_pricing_request.py b/src/otari/_client/models/set_pricing_request.py similarity index 100% rename from src/otari/_control_plane/models/set_pricing_request.py rename to src/otari/_client/models/set_pricing_request.py diff --git a/src/otari/_client/models/source.py b/src/otari/_client/models/source.py new file mode 100644 index 0000000..33f951b --- /dev/null +++ b/src/otari/_client/models/source.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.mr_base64_pdf_source import MRBase64PDFSource +from otari._client.models.mr_plain_text_source import MRPlainTextSource +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +SOURCE_ANY_OF_SCHEMAS = ["MRBase64PDFSource", "MRPlainTextSource"] + +class Source(BaseModel): + """ + Source + """ + + # data type: MRBase64PDFSource + anyof_schema_1_validator: Optional[MRBase64PDFSource] = None + # data type: MRPlainTextSource + anyof_schema_2_validator: Optional[MRPlainTextSource] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MRBase64PDFSource, MRPlainTextSource]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MRBase64PDFSource", "MRPlainTextSource" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = Source.model_construct() + error_messages = [] + # validate data type: MRBase64PDFSource + if not isinstance(v, MRBase64PDFSource): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRBase64PDFSource`") + else: + return v + + # validate data type: MRPlainTextSource + if not isinstance(v, MRPlainTextSource): + error_messages.append(f"Error! Input type `{type(v)}` is not `MRPlainTextSource`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in Source with anyOf schemas: MRBase64PDFSource, MRPlainTextSource. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MRBase64PDFSource] = None + try: + instance.actual_instance = MRBase64PDFSource.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MRPlainTextSource] = None + try: + instance.actual_instance = MRPlainTextSource.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into Source with anyOf schemas: MRBase64PDFSource, MRPlainTextSource. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MRBase64PDFSource, MRPlainTextSource]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/system.py b/src/otari/_client/models/system.py new file mode 100644 index 0000000..80d4e22 --- /dev/null +++ b/src/otari/_client/models/system.py @@ -0,0 +1,144 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Any, Dict, List, Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +SYSTEM_ANY_OF_SCHEMAS = ["List[Dict[str, object]]", "str"] + +class System(BaseModel): + """ + System + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + # data type: List[Dict[str, object]] + anyof_schema_2_validator: Optional[List[Dict[str, Any]]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[List[Dict[str, object]], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "List[Dict[str, object]]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + if v is None: + return v + + instance = System.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: List[Dict[str, object]] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in System with anyOf schemas: List[Dict[str, object]], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + if json_str is None: + return instance + + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into List[Dict[str, object]] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into System with anyOf schemas: List[Dict[str, object]], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], List[Dict[str, object]], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/tool_calls_inner.py b/src/otari/_client/models/tool_calls_inner.py new file mode 100644 index 0000000..0136089 --- /dev/null +++ b/src/otari/_client/models/tool_calls_inner.py @@ -0,0 +1,134 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Optional +from otari._client.models.msg_chat_completion_message_custom_tool_call_param import MSGChatCompletionMessageCustomToolCallParam +from otari._client.models.msg_chat_completion_message_function_tool_call_param import MSGChatCompletionMessageFunctionToolCallParam +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +TOOLCALLSINNER_ANY_OF_SCHEMAS = ["MSGChatCompletionMessageCustomToolCallParam", "MSGChatCompletionMessageFunctionToolCallParam"] + +class ToolCallsInner(BaseModel): + """ + ToolCallsInner + """ + + # data type: MSGChatCompletionMessageFunctionToolCallParam + anyof_schema_1_validator: Optional[MSGChatCompletionMessageFunctionToolCallParam] = None + # data type: MSGChatCompletionMessageCustomToolCallParam + anyof_schema_2_validator: Optional[MSGChatCompletionMessageCustomToolCallParam] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[MSGChatCompletionMessageCustomToolCallParam, MSGChatCompletionMessageFunctionToolCallParam]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "MSGChatCompletionMessageCustomToolCallParam", "MSGChatCompletionMessageFunctionToolCallParam" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = ToolCallsInner.model_construct() + error_messages = [] + # validate data type: MSGChatCompletionMessageFunctionToolCallParam + if not isinstance(v, MSGChatCompletionMessageFunctionToolCallParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionMessageFunctionToolCallParam`") + else: + return v + + # validate data type: MSGChatCompletionMessageCustomToolCallParam + if not isinstance(v, MSGChatCompletionMessageCustomToolCallParam): + error_messages.append(f"Error! Input type `{type(v)}` is not `MSGChatCompletionMessageCustomToolCallParam`") + else: + return v + + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in ToolCallsInner with anyOf schemas: MSGChatCompletionMessageCustomToolCallParam, MSGChatCompletionMessageFunctionToolCallParam. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # anyof_schema_1_validator: Optional[MSGChatCompletionMessageFunctionToolCallParam] = None + try: + instance.actual_instance = MSGChatCompletionMessageFunctionToolCallParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # anyof_schema_2_validator: Optional[MSGChatCompletionMessageCustomToolCallParam] = None + try: + instance.actual_instance = MSGChatCompletionMessageCustomToolCallParam.from_json(json_str) + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into ToolCallsInner with anyOf schemas: MSGChatCompletionMessageCustomToolCallParam, MSGChatCompletionMessageFunctionToolCallParam. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], MSGChatCompletionMessageCustomToolCallParam, MSGChatCompletionMessageFunctionToolCallParam]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_client/models/tool_choice.py b/src/otari/_client/models/tool_choice.py new file mode 100644 index 0000000..107d6c6 --- /dev/null +++ b/src/otari/_client/models/tool_choice.py @@ -0,0 +1,144 @@ +# coding: utf-8 + +""" + otari-gateway + + A clean FastAPI gateway for otari with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator +from typing import Any, Dict, Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +TOOLCHOICE_ANY_OF_SCHEMAS = ["Dict[str, object]", "str"] + +class ToolChoice(BaseModel): + """ + ToolChoice + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = Field(default=None, description="Filter models by provider name") + # data type: Dict[str, object] + anyof_schema_2_validator: Optional[Dict[str, Any]] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[Dict[str, object], str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "Dict[str, object]", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + if v is None: + return v + + instance = ToolChoice.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: Dict[str, object] + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in ToolChoice with anyOf schemas: Dict[str, object], str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + if json_str is None: + return instance + + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into Dict[str, object] + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into ToolChoice with anyOf schemas: Dict[str, object], str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], Dict[str, object], str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/src/otari/_control_plane/models/update_budget_request.py b/src/otari/_client/models/update_budget_request.py similarity index 100% rename from src/otari/_control_plane/models/update_budget_request.py rename to src/otari/_client/models/update_budget_request.py diff --git a/src/otari/_control_plane/models/update_key_request.py b/src/otari/_client/models/update_key_request.py similarity index 100% rename from src/otari/_control_plane/models/update_key_request.py rename to src/otari/_client/models/update_key_request.py diff --git a/src/otari/_control_plane/models/update_user_request.py b/src/otari/_client/models/update_user_request.py similarity index 100% rename from src/otari/_control_plane/models/update_user_request.py rename to src/otari/_client/models/update_user_request.py diff --git a/src/otari/_control_plane/models/usage_entry.py b/src/otari/_client/models/usage_entry.py similarity index 100% rename from src/otari/_control_plane/models/usage_entry.py rename to src/otari/_client/models/usage_entry.py diff --git a/src/otari/_control_plane/models/usage_log_response.py b/src/otari/_client/models/usage_log_response.py similarity index 100% rename from src/otari/_control_plane/models/usage_log_response.py rename to src/otari/_client/models/usage_log_response.py diff --git a/src/otari/_control_plane/models/user_response.py b/src/otari/_client/models/user_response.py similarity index 100% rename from src/otari/_control_plane/models/user_response.py rename to src/otari/_client/models/user_response.py diff --git a/src/otari/_control_plane/models/validation_error.py b/src/otari/_client/models/validation_error.py similarity index 97% rename from src/otari/_control_plane/models/validation_error.py rename to src/otari/_client/models/validation_error.py index 7bc0d46..cd002e7 100644 --- a/src/otari/_control_plane/models/validation_error.py +++ b/src/otari/_client/models/validation_error.py @@ -19,7 +19,7 @@ from pydantic import BaseModel, ConfigDict, StrictStr from typing import Any, ClassVar, Dict, List, Optional -from otari._control_plane.models.location_inner import LocationInner +from otari._client.models.location_inner import LocationInner from typing import Optional, Set from typing_extensions import Self from pydantic_core import to_jsonable_python diff --git a/src/otari/_control_plane/py.typed b/src/otari/_client/py.typed similarity index 100% rename from src/otari/_control_plane/py.typed rename to src/otari/_client/py.typed diff --git a/src/otari/_control_plane/rest.py b/src/otari/_client/rest.py similarity index 99% rename from src/otari/_control_plane/rest.py rename to src/otari/_client/rest.py index a35c676..c9ab7a9 100644 --- a/src/otari/_control_plane/rest.py +++ b/src/otari/_client/rest.py @@ -19,7 +19,7 @@ import urllib3 -from otari._control_plane.exceptions import ApiException, ApiValueError +from otari._client.exceptions import ApiException, ApiValueError SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"} RESTResponseType = urllib3.HTTPResponse diff --git a/src/otari/_control_plane/__init__.py b/src/otari/_control_plane/__init__.py deleted file mode 100644 index ced6b18..0000000 --- a/src/otari/_control_plane/__init__.py +++ /dev/null @@ -1,90 +0,0 @@ -# coding: utf-8 - -# flake8: noqa - -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -__version__ = "1.0.0" - -# Define package exports -__all__ = [ - "BudgetsApi", - "KeysApi", - "PricingApi", - "UsageApi", - "UsersApi", - "ApiResponse", - "ApiClient", - "Configuration", - "OpenApiException", - "ApiTypeError", - "ApiValueError", - "ApiKeyError", - "ApiAttributeError", - "ApiException", - "BudgetResponse", - "CreateBudgetRequest", - "CreateKeyRequest", - "CreateKeyResponse", - "CreateUserRequest", - "HTTPValidationError", - "KeyInfo", - "LocationInner", - "PricingResponse", - "SetPricingRequest", - "UpdateBudgetRequest", - "UpdateKeyRequest", - "UpdateUserRequest", - "UsageEntry", - "UsageLogResponse", - "UserResponse", - "ValidationError", -] - -# import apis into sdk package -from otari._control_plane.api.budgets_api import BudgetsApi as BudgetsApi -from otari._control_plane.api.keys_api import KeysApi as KeysApi -from otari._control_plane.api.pricing_api import PricingApi as PricingApi -from otari._control_plane.api.usage_api import UsageApi as UsageApi -from otari._control_plane.api.users_api import UsersApi as UsersApi - -# import ApiClient -from otari._control_plane.api_response import ApiResponse as ApiResponse -from otari._control_plane.api_client import ApiClient as ApiClient -from otari._control_plane.configuration import Configuration as Configuration -from otari._control_plane.exceptions import OpenApiException as OpenApiException -from otari._control_plane.exceptions import ApiTypeError as ApiTypeError -from otari._control_plane.exceptions import ApiValueError as ApiValueError -from otari._control_plane.exceptions import ApiKeyError as ApiKeyError -from otari._control_plane.exceptions import ApiAttributeError as ApiAttributeError -from otari._control_plane.exceptions import ApiException as ApiException - -# import models into sdk package -from otari._control_plane.models.budget_response import BudgetResponse as BudgetResponse -from otari._control_plane.models.create_budget_request import CreateBudgetRequest as CreateBudgetRequest -from otari._control_plane.models.create_key_request import CreateKeyRequest as CreateKeyRequest -from otari._control_plane.models.create_key_response import CreateKeyResponse as CreateKeyResponse -from otari._control_plane.models.create_user_request import CreateUserRequest as CreateUserRequest -from otari._control_plane.models.http_validation_error import HTTPValidationError as HTTPValidationError -from otari._control_plane.models.key_info import KeyInfo as KeyInfo -from otari._control_plane.models.location_inner import LocationInner as LocationInner -from otari._control_plane.models.pricing_response import PricingResponse as PricingResponse -from otari._control_plane.models.set_pricing_request import SetPricingRequest as SetPricingRequest -from otari._control_plane.models.update_budget_request import UpdateBudgetRequest as UpdateBudgetRequest -from otari._control_plane.models.update_key_request import UpdateKeyRequest as UpdateKeyRequest -from otari._control_plane.models.update_user_request import UpdateUserRequest as UpdateUserRequest -from otari._control_plane.models.usage_entry import UsageEntry as UsageEntry -from otari._control_plane.models.usage_log_response import UsageLogResponse as UsageLogResponse -from otari._control_plane.models.user_response import UserResponse as UserResponse -from otari._control_plane.models.validation_error import ValidationError as ValidationError - diff --git a/src/otari/_control_plane/api/__init__.py b/src/otari/_control_plane/api/__init__.py deleted file mode 100644 index 449fed3..0000000 --- a/src/otari/_control_plane/api/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# flake8: noqa - -# import apis into api package -from otari._control_plane.api.budgets_api import BudgetsApi -from otari._control_plane.api.keys_api import KeysApi -from otari._control_plane.api.pricing_api import PricingApi -from otari._control_plane.api.usage_api import UsageApi -from otari._control_plane.api.users_api import UsersApi - diff --git a/src/otari/_control_plane/models/__init__.py b/src/otari/_control_plane/models/__init__.py deleted file mode 100644 index 33c553c..0000000 --- a/src/otari/_control_plane/models/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# coding: utf-8 - -# flake8: noqa -""" - otari-gateway - - A clean FastAPI gateway for otari with API key management - - The version of the OpenAPI document: 0.0.0-dev - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - -# import models into model package -from otari._control_plane.models.budget_response import BudgetResponse -from otari._control_plane.models.create_budget_request import CreateBudgetRequest -from otari._control_plane.models.create_key_request import CreateKeyRequest -from otari._control_plane.models.create_key_response import CreateKeyResponse -from otari._control_plane.models.create_user_request import CreateUserRequest -from otari._control_plane.models.http_validation_error import HTTPValidationError -from otari._control_plane.models.key_info import KeyInfo -from otari._control_plane.models.location_inner import LocationInner -from otari._control_plane.models.pricing_response import PricingResponse -from otari._control_plane.models.set_pricing_request import SetPricingRequest -from otari._control_plane.models.update_budget_request import UpdateBudgetRequest -from otari._control_plane.models.update_key_request import UpdateKeyRequest -from otari._control_plane.models.update_user_request import UpdateUserRequest -from otari._control_plane.models.usage_entry import UsageEntry -from otari._control_plane.models.usage_log_response import UsageLogResponse -from otari._control_plane.models.user_response import UserResponse -from otari._control_plane.models.validation_error import ValidationError - diff --git a/src/otari/_streaming.py b/src/otari/_streaming.py new file mode 100644 index 0000000..a081e33 --- /dev/null +++ b/src/otari/_streaming.py @@ -0,0 +1,107 @@ +"""Server-Sent-Events (SSE) streaming shim for the otari gateway clients. + +The OpenAPI-generated core in :mod:`otari._client` buffers the full HTTP +response before deserializing, so it *cannot* stream. (This is a known upstream +OpenAPI Generator limitation.) For ``stream=True`` on chat, responses, and +messages, the SDK hand-writes the stream here: a raw streaming POST via +``httpx`` that parses ``text/event-stream`` framing and yields typed chunks. + +Wire format (gateway emits the OpenAI / Anthropic SSE convention): + + data: {"id": "...", ...}\\n + \\n + data: {"id": "...", ...}\\n + \\n + data: [DONE]\\n + \\n + +Each event is ``data: ``; a blank line terminates an event; the +sentinel ``data: [DONE]`` ends the stream. ``event:``/``id:``/``:``-comment +lines are ignored (the gateway does not use named events for chat). + +``parse_chunk`` decides the yielded type per endpoint: + +- chat -> typed :class:`otari._client.models.ChatCompletionChunk` +- responses / messages -> the parsed JSON ``dict`` (no single typed chunk model + exists for these provider-shaped event streams; callers get the raw event). +""" + +from __future__ import annotations + +import json +from typing import TYPE_CHECKING, Any, Literal + +from otari._client.models.chat_completion_chunk import ChatCompletionChunk + +if TYPE_CHECKING: + from collections.abc import AsyncIterator, Iterator + + import httpx + +StreamKind = Literal["chat", "responses", "messages"] + +_DONE = "[DONE]" +_DATA_PREFIX = "data:" + + +def parse_chunk(kind: StreamKind, payload: str) -> Any: + """Parse one SSE ``data:`` payload into the chunk type for ``kind``. + + Chat yields a typed :class:`ChatCompletionChunk`; responses/messages yield + the parsed JSON ``dict`` (their event streams have no single typed model). + """ + if kind == "chat": + chunk = ChatCompletionChunk.from_json(payload) + if chunk is None: # pragma: no cover - from_json only returns None for empty input + msg = "received empty chat completion chunk payload" + raise ValueError(msg) + return chunk + return json.loads(payload) + + +def _iter_data_lines(line: str) -> str | None: + """Return the ``data:`` payload of an SSE line, or ``None`` to skip it. + + Returns the sentinel string ``"[DONE]"`` unchanged so the caller can stop. + """ + stripped = line.rstrip("\n").rstrip("\r") + if not stripped or stripped.startswith(":"): + return None + if not stripped.startswith(_DATA_PREFIX): + # event:/id:/retry: framing lines carry no chunk data for our streams. + return None + return stripped[len(_DATA_PREFIX) :].strip() + + +def iter_sse( + response: httpx.Response, + kind: StreamKind, +) -> Iterator[Any]: + """Yield parsed chunks from a *synchronous* streaming httpx response. + + Stops on the ``data: [DONE]`` sentinel and on end-of-stream. + """ + for line in response.iter_lines(): + payload = _iter_data_lines(line) + if payload is None: + continue + if payload == _DONE: + return + yield parse_chunk(kind, payload) + + +async def aiter_sse( + response: httpx.Response, + kind: StreamKind, +) -> AsyncIterator[Any]: + """Yield parsed chunks from an *asynchronous* streaming httpx response. + + Stops on the ``data: [DONE]`` sentinel and on end-of-stream. + """ + async for line in response.aiter_lines(): + payload = _iter_data_lines(line) + if payload is None: + continue + if payload == _DONE: + return + yield parse_chunk(kind, payload) diff --git a/src/otari/async_client.py b/src/otari/async_client.py index c171f5a..04dd821 100644 --- a/src/otari/async_client.py +++ b/src/otari/async_client.py @@ -1,8 +1,11 @@ """AsyncOtariClient: asynchronous Python client for the otari gateway. -Wraps the OpenAI Python SDK (``AsyncOpenAI``), adding gateway-specific auth -handling and error mapping for platform mode. Extracted from the -``GatewayProvider`` in `any-llm `_. +Option C: a thin async shell over the OpenAPI-generated core in +:mod:`otari._client`. The generated core is synchronous (urllib3-based), so +non-streaming calls are dispatched to a worker thread via ``asyncio.to_thread``; +streaming is natively async over ``httpx.AsyncClient`` and the SSE shim in +:mod:`otari._streaming`. Generated ``ApiException``\\s are mapped to the typed +errors in :mod:`otari.errors`. Example:: @@ -22,25 +25,42 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, overload +import asyncio +from functools import cached_property +from typing import TYPE_CHECKING, Any, cast, overload import httpx -from openai import AsyncOpenAI -from otari._base import _BaseOtariClient, _url_encode +from otari._base import _BaseOtariClient, build_request +from otari._client import ApiClient, Configuration +from otari._client.api.batches_api import BatchesApi +from otari._client.api.chat_api import ChatApi +from otari._client.api.embeddings_api import EmbeddingsApi +from otari._client.api.messages_api import MessagesApi +from otari._client.api.models_api import ModelsApi +from otari._client.api.moderations_api import ModerationsApi +from otari._client.api.rerank_api import RerankApi +from otari._client.api.responses_api import ResponsesApi +from otari._client.exceptions import ApiException +from otari._client.models.chat_completion_request import ChatCompletionRequest +from otari._client.models.create_batch_request import CreateBatchRequest +from otari._client.models.embedding_request import EmbeddingRequest +from otari._client.models.messages_request import MessagesRequest +from otari._client.models.moderation_request import ModerationRequest +from otari._client.models.rerank_request import RerankRequest +from otari._streaming import aiter_sse +from otari.control_plane import ControlPlane +from otari.errors import OtariError if TYPE_CHECKING: - from openai import AsyncStream - from openai.types import CreateEmbeddingResponse, Model - from openai.types.chat import ( - ChatCompletion, - ChatCompletionChunk, - ) - from openai.types.responses import ( - Response, - ResponseStreamEvent, - ) - + from collections.abc import AsyncIterator, Callable + + from otari._client.models.chat_completion import ChatCompletion + from otari._client.models.chat_completion_chunk import ChatCompletionChunk + from otari._client.models.create_embedding_response import CreateEmbeddingResponse + from otari._client.models.model_object import ModelObject + from otari._client.models.moderation_response import ModerationResponse + from otari._client.models.rerank_response import RerankResponse from otari.types import ( BatchResult, CreateBatchParams, @@ -51,69 +71,75 @@ class AsyncOtariClient(_BaseOtariClient): """Asynchronous client for the otari gateway. - Supports two authentication modes (mirroring the TypeScript SDK and - the Python ``GatewayProvider``): + Supports the same two authentication modes as + :class:`~otari.client.OtariClient`: - - **Platform mode**: A Bearer token is sent in the standard Authorization - header. Errors are mapped to typed otari exceptions. - - **Non-platform mode**: An API key is sent via a custom ``Otari-Key`` - header. Errors from the OpenAI SDK pass through unmodified. + - **Platform mode**: Bearer token in the ``Authorization`` header. + - **Non-platform mode**: API key in the custom ``Otari-Key`` header. - Args: - api_base: Base URL of the gateway (e.g. ``"http://localhost:8000"``). - Falls back to the ``GATEWAY_API_BASE`` environment variable. In - platform mode it defaults to the hosted gateway at - ``https://api.otari.ai`` when neither is supplied. - api_key: API key for non-platform mode. - Falls back to ``GATEWAY_API_KEY`` env var. - platform_token: Platform token for platform mode. - Falls back to the canonical ``OTARI_AI_TOKEN`` env var (or the - legacy ``GATEWAY_PLATFORM_TOKEN`` alias). - default_headers: Additional default headers to send with every request. - openai_options: Extra keyword arguments forwarded to the underlying - ``AsyncOpenAI`` constructor. - - Example:: - - client = AsyncOtariClient( - api_base="http://localhost:8000", - platform_token="tk_xxx", - ) + The generated core is synchronous; non-streaming calls run in a worker + thread (``asyncio.to_thread``) while streaming is natively async. - response = await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "Hello!"}], - ) - print(response.choices[0].message.content) + Args: + api_base: Base URL of the gateway. Falls back to ``GATEWAY_API_BASE``; + in platform mode defaults to ``https://api.otari.ai``. + api_key: API key for non-platform mode (``GATEWAY_API_KEY``). + platform_token: Platform token (``OTARI_AI_TOKEN`` / legacy + ``GATEWAY_PLATFORM_TOKEN``). + admin_key: Master/admin key for the control-plane (``GATEWAY_ADMIN_KEY``). + default_headers: Additional default headers sent with every request. + timeout: Per-request timeout (seconds) for the streaming shim. """ - openai: AsyncOpenAI - """The underlying OpenAI client instance.""" - def __init__( self, api_base: str | None = None, *, api_key: str | None = None, platform_token: str | None = None, + admin_key: str | None = None, default_headers: dict[str, str] | None = None, - openai_options: dict[str, Any] | None = None, + timeout: float | None = None, ) -> None: super().__init__( api_base, api_key=api_key, platform_token=platform_token, + admin_key=admin_key, default_headers=default_headers, - openai_options=openai_options, - ) - self.openai = AsyncOpenAI( - api_key=self._openai_api_key, - base_url=self._openai_base_url, - default_headers=self._openai_default_headers, - **self._openai_extra_kwargs, ) - # httpx client for raw HTTP calls (batch, etc.) - self._http = httpx.AsyncClient() + self._timeout = timeout + config = Configuration(host=self._gateway_root_url) + self._api = ApiClient(config) + # set_default_header is generated (untyped); seed the per-mode auth header. + api_any = cast("Any", self._api) + for name, value in self._default_headers.items(): + api_any.set_default_header(name, value) + self._http = httpx.AsyncClient(timeout=timeout) + + self._chat = ChatApi(self._api) + self._responses = ResponsesApi(self._api) + self._embeddings = EmbeddingsApi(self._api) + self._moderations = ModerationsApi(self._api) + self._rerank = RerankApi(self._api) + self._messages = MessagesApi(self._api) + self._models = ModelsApi(self._api) + self._batches = BatchesApi(self._api) + + @cached_property + def control_plane(self) -> ControlPlane: + """Typed client for the management endpoints (keys, users, budgets, pricing, usage). + + Requires an admin credential: pass ``admin_key`` (the gateway master key), + set ``GATEWAY_ADMIN_KEY``, or use ``platform_token``. + """ + if not self._admin_token: + msg = ( + "control-plane management requires an admin credential; pass " + "admin_key=... (the gateway master key) or use platform_token=..." + ) + raise OtariError(msg) + return ControlPlane(self._gateway_root_url, self._admin_token) # -- Chat completions --------------------------------------------------- @@ -133,9 +159,9 @@ async def completion( *, model: str, messages: list[dict[str, Any]], - stream: bool = ..., + stream: bool, **kwargs: Any, - ) -> ChatCompletion | AsyncStream[ChatCompletionChunk]: ... + ) -> ChatCompletion | AsyncIterator[ChatCompletionChunk]: ... async def completion( self, @@ -147,25 +173,17 @@ async def completion( ) -> Any: """Create a chat completion. - When ``stream=True`` is set, returns an async iterable of chunks. - - Args: - model: Model identifier (e.g. ``"openai:gpt-4o-mini"``). - messages: List of message dicts with ``role`` and ``content``. - stream: Whether to stream the response. - **kwargs: Additional parameters forwarded to the OpenAI API. - - Returns: - A ``ChatCompletion`` or an async stream of ``ChatCompletionChunk``. + When ``stream=True``, returns an async iterator of typed + ``ChatCompletionChunk``; otherwise a typed ``ChatCompletion``. """ - try: - params: dict[str, Any] = {"model": model, "messages": messages, **kwargs} - if stream is not None: - params["stream"] = stream - return await self.openai.chat.completions.create(**params) - except Exception as exc: - self._handle_error(exc) - raise + body = {"model": model, "messages": messages, **kwargs} + if stream: + body["stream"] = True + return self._stream("/chat/completions", body, "chat") + request = build_request(ChatCompletionRequest, body) + return await self._call( + lambda: self._chat.chat_completions_v1_chat_completions_post(request) + ) # -- Responses API ------------------------------------------------------ @@ -176,28 +194,42 @@ async def response( input: Any, # noqa: A002 stream: bool | None = None, **kwargs: Any, - ) -> Response | AsyncStream[ResponseStreamEvent]: - """Create a response using the OpenAI Responses API. + ) -> Any: + """Create a response via the OpenAI-style Responses API. + + When ``stream=True``, returns an async iterator of raw event dicts; + otherwise the parsed response object. + """ + body = {"model": model, "input": input, **kwargs} + if stream: + body["stream"] = True + return self._stream("/responses", body, "responses") + return await self._call( + lambda: self._responses.create_response_v1_responses_post(body) # type: ignore[arg-type] + ) + + # -- Messages API (Anthropic-shaped /messages) -------------------------- - Args: - model: Model identifier (e.g. ``"openai:gpt-4o-mini"``). - input: The input for the response. - stream: Whether to stream the response. - **kwargs: Additional parameters forwarded to the OpenAI API. + async def message( + self, + *, + model: str, + messages: list[dict[str, Any]], + max_tokens: int, + stream: bool | None = None, + **kwargs: Any, + ) -> Any: + """Create an Anthropic-style message via the gateway ``/messages`` endpoint. - Returns: - A ``Response`` or an async stream of ``ResponseStreamEvent``. + When ``stream=True``, returns an async iterator of raw event dicts; + otherwise a typed ``MessageResponse``. """ - try: - params: dict[str, Any] = {"model": model, "input": input, **kwargs} - if stream is not None: - params["stream"] = stream - result: Response | AsyncStream[ResponseStreamEvent] = await self.openai.responses.create(**params) - except Exception as exc: - self._handle_error(exc) - raise - else: - return result + body = {"model": model, "messages": messages, "max_tokens": max_tokens, **kwargs} + if stream: + body["stream"] = True + return self._stream("/messages", body, "messages") + request = build_request(MessagesRequest, body) + return await self._call(lambda: self._messages.create_message_v1_messages_post(request)) # -- Embeddings --------------------------------------------------------- @@ -208,177 +240,144 @@ async def embedding( input: str | list[str], # noqa: A002 **kwargs: Any, ) -> CreateEmbeddingResponse: - """Create embeddings for the given input. - - Args: - model: Model identifier (e.g. ``"openai:text-embedding-3-small"``). - input: Text or list of texts to embed. - **kwargs: Additional parameters forwarded to the OpenAI API. - - Returns: - An ``CreateEmbeddingResponse``. - """ - try: - return await self.openai.embeddings.create(model=model, input=input, **kwargs) - except Exception as exc: - self._handle_error(exc) - raise - - # -- Models ------------------------------------------------------------- + """Create embeddings for the given input.""" + request = build_request(EmbeddingRequest, {"model": model, "input": input, **kwargs}) + result = await self._call( + lambda: self._embeddings.create_embedding_v1_embeddings_post(request) + ) + return cast("CreateEmbeddingResponse", result) - async def list_models(self) -> list[Model]: - """List available models from the gateway. + # -- Moderations -------------------------------------------------------- - Returns: - A list of ``Model`` objects. - """ - try: - page = await self.openai.models.list() - except Exception as exc: - self._handle_error(exc) - raise - else: - return [model async for model in page] + async def moderation( + self, + *, + model: str, + input: str | list[str], # noqa: A002 + **kwargs: Any, + ) -> ModerationResponse: + """Classify text against the gateway moderation endpoint.""" + request = build_request(ModerationRequest, {"model": model, "input": input, **kwargs}) + result = await self._call( + lambda: self._moderations.create_moderation_v1_moderations_post(request) + ) + return cast("ModerationResponse", result) - # -- Batch operations --------------------------------------------------- + # -- Rerank ------------------------------------------------------------- - async def create_batch(self, params: CreateBatchParams) -> dict[str, Any]: - """Create a batch job. + async def rerank( + self, + *, + model: str, + query: str, + documents: list[str], + **kwargs: Any, + ) -> RerankResponse: + """Rerank ``documents`` by relevance to ``query``.""" + request = build_request( + RerankRequest, {"model": model, "query": query, "documents": documents, **kwargs} + ) + result = await self._call(lambda: self._rerank.create_rerank_v1_rerank_post(request)) + return cast("RerankResponse", result) - Args: - params: Batch creation parameters including model and requests array. + # -- Models ------------------------------------------------------------- - Returns: - The created batch object. - """ - return await self._batch_request("POST", "/batches", body=dict(params)) + async def list_models(self) -> list[ModelObject]: + """List available models from the gateway.""" + result = await self._call(self._models.list_models_v1_models_get) + return list(result.data) - async def retrieve_batch(self, batch_id: str, provider: str) -> dict[str, Any]: - """Retrieve the status of a batch job. + # -- Batch operations --------------------------------------------------- - Args: - batch_id: The ID of the batch to retrieve. - provider: The provider name (e.g. ``"openai"``). + async def create_batch(self, params: CreateBatchParams) -> Any: + """Create a batch job.""" + request = build_request(CreateBatchRequest, dict(params)) + return await self._call(lambda: self._batches.create_batch_v1_batches_post(request)) - Returns: - The batch object with current status. - """ - encoded_id = httpx.URL(f"/batches/{batch_id}").raw_path.decode() - return await self._batch_request( - "GET", - f"{encoded_id}?provider={_url_encode(provider)}", + async def retrieve_batch(self, batch_id: str, provider: str) -> Any: + """Retrieve the status of a batch job.""" + return await self._call( + lambda: self._batches.retrieve_batch_v1_batches_batch_id_get(batch_id, provider) ) - async def cancel_batch(self, batch_id: str, provider: str) -> dict[str, Any]: - """Cancel a batch job. - - Args: - batch_id: The ID of the batch to cancel. - provider: The provider name (e.g. ``"openai"``). - - Returns: - The batch object with updated status. - """ - encoded_id = httpx.URL(f"/batches/{batch_id}").raw_path.decode() - return await self._batch_request( - "POST", - f"{encoded_id}/cancel?provider={_url_encode(provider)}", + async def cancel_batch(self, batch_id: str, provider: str) -> Any: + """Cancel a batch job.""" + return await self._call( + lambda: self._batches.cancel_batch_v1_batches_batch_id_cancel_post(batch_id, provider) ) async def list_batches( self, provider: str, options: ListBatchesOptions | None = None, - ) -> list[dict[str, Any]]: - """List batch jobs for a provider. - - Args: - provider: The provider name (e.g. ``"openai"``). - options: Optional pagination parameters. + ) -> list[Any]: + """List batch jobs for a provider.""" + options = options or {} + result = await self._call( + lambda: self._batches.list_batches_v1_batches_get( + provider, + after=options.get("after"), + limit=options.get("limit"), + ) + ) + data = result.get("data", []) if isinstance(result, dict) else [] + return list(data) - Returns: - List of batch objects. - """ - params_parts = [f"provider={_url_encode(provider)}"] - if options: - if "after" in options: - params_parts.append(f"after={_url_encode(options['after'])}") - if "limit" in options: - params_parts.append(f"limit={options['limit']}") - query = "&".join(params_parts) - response = await self._batch_request("GET", f"/batches?{query}") - data: list[dict[str, Any]] = response.get("data", []) - return data - - async def retrieve_batch_results( - self, - batch_id: str, - provider: str, - ) -> BatchResult: + async def retrieve_batch_results(self, batch_id: str, provider: str) -> BatchResult: """Retrieve the results of a completed batch job. - Args: - batch_id: The ID of the batch. - provider: The provider name (e.g. ``"openai"``). - - Returns: - The batch results containing per-request outcomes. - Raises: - BatchNotCompleteError: If the batch is not yet complete. + BatchNotCompleteError: If the batch is not yet complete (HTTP 409). """ from otari.types import BatchResult as BatchResultType # noqa: PLC0415 from otari.types import BatchResultItem # noqa: PLC0415 - encoded_id = httpx.URL(f"/batches/{batch_id}").raw_path.decode() - data = await self._batch_request( - "GET", - f"{encoded_id}/results?provider={_url_encode(provider)}", + data = await self._call( + lambda: self._batches.retrieve_batch_results_v1_batches_batch_id_results_get( + batch_id, provider + ) ) + results = data.get("results", []) if isinstance(data, dict) else [] items = [ BatchResultItem( custom_id=entry["custom_id"], result=entry.get("result"), error=entry.get("error"), ) - for entry in data.get("results", []) + for entry in results ] return BatchResultType(results=items) - # -- Batch HTTP helpers ------------------------------------------------- + # -- Internal helpers --------------------------------------------------- - async def _batch_request( - self, - method: str, - path: str, - *, - body: dict[str, Any] | None = None, - ) -> dict[str, Any]: - """Make a direct HTTP request for batch operations. + async def _call(self, fn: Callable[[], Any]) -> Any: + """Run a synchronous generated call off-thread, mapping its errors.""" + try: + return await asyncio.to_thread(fn) + except ApiException as exc: + raise self._map_api_exception(exc) from exc - Unlike completion/embedding which use ``self.openai``, batch methods - use direct HTTP because the gateway batch API has a custom JSON format. - """ + async def _stream(self, path: str, body: dict[str, Any], kind: Any) -> AsyncIterator[Any]: + """Open a raw async streaming POST and yield parsed SSE chunks.""" url = f"{self._base_url}{path}" - response = await self._http.request( - method, - url, - headers=self._build_batch_headers(), - json=body if body is not None else None, - ) - - if not response.is_success: - self._map_batch_error(response) - - result: dict[str, Any] = response.json() - return result + headers = { + "Content-Type": "application/json", + "Accept": "text/event-stream", + **self._default_headers, + } + async with self._http.stream("POST", url, json=body, headers=headers) as response: + if response.status_code >= 400: + raw = await response.aread() + raise self._map_streaming_response(response, raw) + async for chunk in aiter_sse(response, kind): + yield chunk # -- Cleanup ------------------------------------------------------------ async def close(self) -> None: """Close the underlying HTTP clients.""" await self._http.aclose() - await self.openai.close() + await asyncio.to_thread(cast("Any", self._api).__exit__, None, None, None) async def __aenter__(self) -> AsyncOtariClient: return self diff --git a/src/otari/client.py b/src/otari/client.py index 738a846..d64ed1b 100644 --- a/src/otari/client.py +++ b/src/otari/client.py @@ -1,8 +1,12 @@ """OtariClient: synchronous Python client for the otari gateway. -Wraps the OpenAI Python SDK (``OpenAI``), adding gateway-specific auth handling -and error mapping for platform mode. For an asynchronous client, see -:class:`~otari.async_client.AsyncOtariClient`. +Option C: a thin, ergonomic shell over the OpenAPI-generated core in +:mod:`otari._client`. Non-streaming calls go through the generated typed API +classes (returning typed models such as ``ChatCompletion``); streaming calls go +through the hand-written SSE shim in :mod:`otari._streaming`; generated +``ApiException``\\s are mapped to the typed errors in :mod:`otari.errors`. + +For an asynchronous client, see :class:`~otari.async_client.AsyncOtariClient`. Example:: @@ -23,27 +27,40 @@ from __future__ import annotations from functools import cached_property -from typing import TYPE_CHECKING, Any, overload +from typing import TYPE_CHECKING, Any, cast, overload import httpx -from openai import OpenAI -from otari._base import _BaseOtariClient, _url_encode +from otari._base import _BaseOtariClient, build_request +from otari._client import ApiClient, Configuration +from otari._client.api.batches_api import BatchesApi +from otari._client.api.chat_api import ChatApi +from otari._client.api.embeddings_api import EmbeddingsApi +from otari._client.api.messages_api import MessagesApi +from otari._client.api.models_api import ModelsApi +from otari._client.api.moderations_api import ModerationsApi +from otari._client.api.rerank_api import RerankApi +from otari._client.api.responses_api import ResponsesApi +from otari._client.exceptions import ApiException +from otari._client.models.chat_completion_request import ChatCompletionRequest +from otari._client.models.create_batch_request import CreateBatchRequest +from otari._client.models.embedding_request import EmbeddingRequest +from otari._client.models.messages_request import MessagesRequest +from otari._client.models.moderation_request import ModerationRequest +from otari._client.models.rerank_request import RerankRequest +from otari._streaming import iter_sse from otari.control_plane import ControlPlane from otari.errors import OtariError if TYPE_CHECKING: - from openai import Stream - from openai.types import CreateEmbeddingResponse, Model - from openai.types.chat import ( - ChatCompletion, - ChatCompletionChunk, - ) - from openai.types.responses import ( - Response, - ResponseStreamEvent, - ) - + from collections.abc import Callable, Iterator + + from otari._client.models.chat_completion import ChatCompletion + from otari._client.models.chat_completion_chunk import ChatCompletionChunk + from otari._client.models.create_embedding_response import CreateEmbeddingResponse + from otari._client.models.model_object import ModelObject + from otari._client.models.moderation_response import ModerationResponse + from otari._client.models.rerank_response import RerankResponse from otari.types import ( BatchResult, CreateBatchParams, @@ -54,47 +71,30 @@ class OtariClient(_BaseOtariClient): """Synchronous client for the otari gateway. - Supports two authentication modes (mirroring the TypeScript SDK and - the Python ``GatewayProvider``): + Supports two authentication modes (mirroring the TypeScript SDK and the + Python ``GatewayProvider``): - - **Platform mode**: A Bearer token is sent in the standard Authorization - header. Errors are mapped to typed otari exceptions. - - **Non-platform mode**: An API key is sent via a custom ``Otari-Key`` - header. Errors from the OpenAI SDK pass through unmodified. + - **Platform mode**: a Bearer token is sent in the standard ``Authorization`` + header (activated by ``platform_token`` / ``OTARI_AI_TOKEN``). + - **Non-platform mode**: an API key is sent via the custom ``Otari-Key`` + header (``api_key`` / ``GATEWAY_API_KEY``). - For asynchronous usage, see :class:`~otari.async_client.AsyncOtariClient`. + In both modes, gateway errors are mapped to the typed exceptions in + :mod:`otari.errors`. Args: api_base: Base URL of the gateway (e.g. ``"http://localhost:8000"``). - Falls back to the ``GATEWAY_API_BASE`` environment variable. In - platform mode it defaults to the hosted gateway at - ``https://api.otari.ai`` when neither is supplied. - api_key: API key for non-platform mode. - Falls back to ``GATEWAY_API_KEY`` env var. - platform_token: Platform token for platform mode. - Falls back to the canonical ``OTARI_AI_TOKEN`` env var (or the - legacy ``GATEWAY_PLATFORM_TOKEN`` alias). - default_headers: Additional default headers to send with every request. - openai_options: Extra keyword arguments forwarded to the underlying - ``OpenAI`` constructor. - - Example:: - - client = OtariClient( - api_base="http://localhost:8000", - platform_token="tk_xxx", - ) - - response = client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "Hello!"}], - ) - print(response.choices[0].message.content) + Falls back to ``GATEWAY_API_BASE``. In platform mode it defaults to + the hosted gateway at ``https://api.otari.ai`` when neither is set. + api_key: API key for non-platform mode. Falls back to ``GATEWAY_API_KEY``. + platform_token: Platform token for platform mode. Falls back to the + canonical ``OTARI_AI_TOKEN`` (or legacy ``GATEWAY_PLATFORM_TOKEN``). + admin_key: Master/admin key for the control-plane endpoints. Falls back + to ``GATEWAY_ADMIN_KEY`` (or the platform token in platform mode). + default_headers: Additional default headers sent with every request. + timeout: Per-request timeout (seconds) for the streaming shim. """ - openai: OpenAI - """The underlying OpenAI client instance.""" - def __init__( self, api_base: str | None = None, @@ -103,7 +103,7 @@ def __init__( platform_token: str | None = None, admin_key: str | None = None, default_headers: dict[str, str] | None = None, - openai_options: dict[str, Any] | None = None, + timeout: float | None = None, ) -> None: super().__init__( api_base, @@ -111,16 +111,26 @@ def __init__( platform_token=platform_token, admin_key=admin_key, default_headers=default_headers, - openai_options=openai_options, ) - self.openai = OpenAI( - api_key=self._openai_api_key, - base_url=self._openai_base_url, - default_headers=self._openai_default_headers, - **self._openai_extra_kwargs, - ) - # httpx client for raw HTTP calls (batch, etc.) - self._http = httpx.Client() + self._timeout = timeout + config = Configuration(host=self._gateway_root_url) + self._api = ApiClient(config) + # set_default_header is generated (untyped); seed the per-mode auth header. + api_any = cast("Any", self._api) + for name, value in self._default_headers.items(): + api_any.set_default_header(name, value) + # Raw httpx client used only for the SSE streaming shim (the generated + # core buffers and cannot stream). + self._http = httpx.Client(timeout=timeout) + + self._chat = ChatApi(self._api) + self._responses = ResponsesApi(self._api) + self._embeddings = EmbeddingsApi(self._api) + self._moderations = ModerationsApi(self._api) + self._rerank = RerankApi(self._api) + self._messages = MessagesApi(self._api) + self._models = ModelsApi(self._api) + self._batches = BatchesApi(self._api) @cached_property def control_plane(self) -> ControlPlane: @@ -156,9 +166,9 @@ def completion( *, model: str, messages: list[dict[str, Any]], - stream: bool = ..., + stream: bool, **kwargs: Any, - ) -> ChatCompletion | Stream[ChatCompletionChunk]: ... + ) -> ChatCompletion | Iterator[ChatCompletionChunk]: ... def completion( self, @@ -170,25 +180,24 @@ def completion( ) -> Any: """Create a chat completion. - When ``stream=True`` is set, returns an iterable of chunks. + When ``stream=True``, returns an iterator of typed + :class:`~otari._client.models.chat_completion_chunk.ChatCompletionChunk`. + Otherwise returns a typed + :class:`~otari._client.models.chat_completion.ChatCompletion`. Args: model: Model identifier (e.g. ``"openai:gpt-4o-mini"``). messages: List of message dicts with ``role`` and ``content``. stream: Whether to stream the response. - **kwargs: Additional parameters forwarded to the OpenAI API. - - Returns: - A ``ChatCompletion`` or a stream of ``ChatCompletionChunk``. + **kwargs: Additional parameters modeled by the gateway chat schema + (e.g. ``temperature``, ``tools``, ``guardrails``). """ - try: - params: dict[str, Any] = {"model": model, "messages": messages, **kwargs} - if stream is not None: - params["stream"] = stream - return self.openai.chat.completions.create(**params) - except Exception as exc: - self._handle_error(exc) - raise + body = {"model": model, "messages": messages, **kwargs} + if stream: + body["stream"] = True + return self._stream("/chat/completions", body, "chat") + request = build_request(ChatCompletionRequest, body) + return self._call(lambda: self._chat.chat_completions_v1_chat_completions_post(request)) # -- Responses API ------------------------------------------------------ @@ -199,28 +208,51 @@ def response( input: Any, # noqa: A002 stream: bool | None = None, **kwargs: Any, - ) -> Response | Stream[ResponseStreamEvent]: - """Create a response using the OpenAI Responses API. + ) -> Any: + """Create a response via the OpenAI-style Responses API. + + When ``stream=True``, returns an iterator of raw response-stream event + dicts (the gateway's responses event stream has no single typed chunk + model). Otherwise returns the parsed response object. + """ + body = {"model": model, "input": input, **kwargs} + if stream: + body["stream"] = True + return self._stream("/responses", body, "responses") + return self._call(lambda: self._responses.create_response_v1_responses_post(body)) # type: ignore[arg-type] + + # -- Messages API (Anthropic-shaped /messages) -------------------------- + + def message( + self, + *, + model: str, + messages: list[dict[str, Any]], + max_tokens: int, + stream: bool | None = None, + **kwargs: Any, + ) -> Any: + """Create an Anthropic-style message via the gateway ``/messages`` endpoint. + + This endpoint has no OpenAI-SDK seam and was previously missing from the + SDK. When ``stream=True``, returns an iterator of raw message-stream + event dicts (no single typed chunk model exists). Otherwise returns a + typed :class:`~otari._client.models.message_response.MessageResponse`. Args: - model: Model identifier (e.g. ``"openai:gpt-4o-mini"``). - input: The input for the response. + model: Model identifier (e.g. ``"anthropic:claude-3-5-sonnet"``). + messages: Anthropic-style message list. + max_tokens: Maximum tokens to generate (required by ``/messages``). stream: Whether to stream the response. - **kwargs: Additional parameters forwarded to the OpenAI API. - - Returns: - A ``Response`` or a stream of ``ResponseStreamEvent``. + **kwargs: Additional ``/messages`` parameters (``system``, + ``temperature``, ``tools``, ``thinking``, ...). """ - try: - params: dict[str, Any] = {"model": model, "input": input, **kwargs} - if stream is not None: - params["stream"] = stream - result: Response | Stream[ResponseStreamEvent] = self.openai.responses.create(**params) - except Exception as exc: - self._handle_error(exc) - raise - else: - return result + body = {"model": model, "messages": messages, "max_tokens": max_tokens, **kwargs} + if stream: + body["stream"] = True + return self._stream("/messages", body, "messages") + request = build_request(MessagesRequest, body) + return self._call(lambda: self._messages.create_message_v1_messages_post(request)) # -- Embeddings --------------------------------------------------------- @@ -231,177 +263,143 @@ def embedding( input: str | list[str], # noqa: A002 **kwargs: Any, ) -> CreateEmbeddingResponse: - """Create embeddings for the given input. + """Create embeddings for the given input.""" + request = build_request(EmbeddingRequest, {"model": model, "input": input, **kwargs}) + result = self._call(lambda: self._embeddings.create_embedding_v1_embeddings_post(request)) + return cast("CreateEmbeddingResponse", result) - Args: - model: Model identifier (e.g. ``"openai:text-embedding-3-small"``). - input: Text or list of texts to embed. - **kwargs: Additional parameters forwarded to the OpenAI API. + # -- Moderations -------------------------------------------------------- - Returns: - An ``CreateEmbeddingResponse``. - """ - try: - return self.openai.embeddings.create(model=model, input=input, **kwargs) - except Exception as exc: - self._handle_error(exc) - raise - - # -- Models ------------------------------------------------------------- - - def list_models(self) -> list[Model]: - """List available models from the gateway. - - Returns: - A list of ``Model`` objects. - """ - try: - page = self.openai.models.list() - except Exception as exc: - self._handle_error(exc) - raise - else: - return list(page) + def moderation( + self, + *, + model: str, + input: str | list[str], # noqa: A002 + **kwargs: Any, + ) -> ModerationResponse: + """Classify text against the gateway moderation endpoint.""" + request = build_request(ModerationRequest, {"model": model, "input": input, **kwargs}) + result = self._call(lambda: self._moderations.create_moderation_v1_moderations_post(request)) + return cast("ModerationResponse", result) - # -- Batch operations --------------------------------------------------- + # -- Rerank ------------------------------------------------------------- - def create_batch(self, params: CreateBatchParams) -> dict[str, Any]: - """Create a batch job. + def rerank( + self, + *, + model: str, + query: str, + documents: list[str], + **kwargs: Any, + ) -> RerankResponse: + """Rerank ``documents`` by relevance to ``query``.""" + request = build_request( + RerankRequest, {"model": model, "query": query, "documents": documents, **kwargs} + ) + result = self._call(lambda: self._rerank.create_rerank_v1_rerank_post(request)) + return cast("RerankResponse", result) - Args: - params: Batch creation parameters including model and requests array. + # -- Models ------------------------------------------------------------- - Returns: - The created batch object. - """ - return self._batch_request("POST", "/batches", body=dict(params)) + def list_models(self) -> list[ModelObject]: + """List available models from the gateway.""" + result = self._call(self._models.list_models_v1_models_get) + return list(result.data) - def retrieve_batch(self, batch_id: str, provider: str) -> dict[str, Any]: - """Retrieve the status of a batch job. + # -- Batch operations --------------------------------------------------- - Args: - batch_id: The ID of the batch to retrieve. - provider: The provider name (e.g. ``"openai"``). + def create_batch(self, params: CreateBatchParams) -> Any: + """Create a batch job.""" + request = build_request(CreateBatchRequest, dict(params)) + return self._call(lambda: self._batches.create_batch_v1_batches_post(request)) - Returns: - The batch object with current status. - """ - encoded_id = httpx.URL(f"/batches/{batch_id}").raw_path.decode() - return self._batch_request( - "GET", - f"{encoded_id}?provider={_url_encode(provider)}", + def retrieve_batch(self, batch_id: str, provider: str) -> Any: + """Retrieve the status of a batch job.""" + return self._call( + lambda: self._batches.retrieve_batch_v1_batches_batch_id_get(batch_id, provider) ) - def cancel_batch(self, batch_id: str, provider: str) -> dict[str, Any]: - """Cancel a batch job. - - Args: - batch_id: The ID of the batch to cancel. - provider: The provider name (e.g. ``"openai"``). - - Returns: - The batch object with updated status. - """ - encoded_id = httpx.URL(f"/batches/{batch_id}").raw_path.decode() - return self._batch_request( - "POST", - f"{encoded_id}/cancel?provider={_url_encode(provider)}", + def cancel_batch(self, batch_id: str, provider: str) -> Any: + """Cancel a batch job.""" + return self._call( + lambda: self._batches.cancel_batch_v1_batches_batch_id_cancel_post(batch_id, provider) ) def list_batches( self, provider: str, options: ListBatchesOptions | None = None, - ) -> list[dict[str, Any]]: - """List batch jobs for a provider. - - Args: - provider: The provider name (e.g. ``"openai"``). - options: Optional pagination parameters. + ) -> list[Any]: + """List batch jobs for a provider.""" + options = options or {} + result = self._call( + lambda: self._batches.list_batches_v1_batches_get( + provider, + after=options.get("after"), + limit=options.get("limit"), + ) + ) + data = result.get("data", []) if isinstance(result, dict) else [] + return list(data) - Returns: - List of batch objects. - """ - params_parts = [f"provider={_url_encode(provider)}"] - if options: - if "after" in options: - params_parts.append(f"after={_url_encode(options['after'])}") - if "limit" in options: - params_parts.append(f"limit={options['limit']}") - query = "&".join(params_parts) - response = self._batch_request("GET", f"/batches?{query}") - data: list[dict[str, Any]] = response.get("data", []) - return data - - def retrieve_batch_results( - self, - batch_id: str, - provider: str, - ) -> BatchResult: + def retrieve_batch_results(self, batch_id: str, provider: str) -> BatchResult: """Retrieve the results of a completed batch job. - Args: - batch_id: The ID of the batch. - provider: The provider name (e.g. ``"openai"``). - - Returns: - The batch results containing per-request outcomes. - Raises: - BatchNotCompleteError: If the batch is not yet complete. + BatchNotCompleteError: If the batch is not yet complete (HTTP 409). """ from otari.types import BatchResult as BatchResultType # noqa: PLC0415 from otari.types import BatchResultItem # noqa: PLC0415 - encoded_id = httpx.URL(f"/batches/{batch_id}").raw_path.decode() - data = self._batch_request( - "GET", - f"{encoded_id}/results?provider={_url_encode(provider)}", + data = self._call( + lambda: self._batches.retrieve_batch_results_v1_batches_batch_id_results_get( + batch_id, provider + ) ) + results = data.get("results", []) if isinstance(data, dict) else [] items = [ BatchResultItem( custom_id=entry["custom_id"], result=entry.get("result"), error=entry.get("error"), ) - for entry in data.get("results", []) + for entry in results ] return BatchResultType(results=items) - # -- Batch HTTP helpers ------------------------------------------------- + # -- Internal helpers --------------------------------------------------- - def _batch_request( - self, - method: str, - path: str, - *, - body: dict[str, Any] | None = None, - ) -> dict[str, Any]: - """Make a direct HTTP request for batch operations. + def _call(self, fn: Callable[[], Any]) -> Any: + """Run a generated call, mapping its ``ApiException`` to a typed error.""" + try: + return fn() + except ApiException as exc: + raise self._map_api_exception(exc) from exc - Unlike completion/embedding which use ``self.openai``, batch methods - use direct HTTP because the gateway batch API has a custom JSON format. + def _stream(self, path: str, body: dict[str, Any], kind: Any) -> Iterator[Any]: + """Open a raw streaming POST and yield parsed SSE chunks. + + The generated core buffers responses, so streaming is hand-written here: + a raw httpx streaming request parsed by :mod:`otari._streaming`. """ url = f"{self._base_url}{path}" - response = self._http.request( - method, - url, - headers=self._build_batch_headers(), - json=body if body is not None else None, - ) - - if not response.is_success: - self._map_batch_error(response) - - result: dict[str, Any] = response.json() - return result + headers = { + "Content-Type": "application/json", + "Accept": "text/event-stream", + **self._default_headers, + } + with self._http.stream("POST", url, json=body, headers=headers) as response: + if response.status_code >= 400: + raw = response.read() + raise self._map_streaming_response(response, raw) + yield from iter_sse(response, kind) # -- Cleanup ------------------------------------------------------------ def close(self) -> None: """Close the underlying HTTP clients.""" self._http.close() - self.openai.close() + cast("Any", self._api).__exit__(None, None, None) def __enter__(self) -> OtariClient: return self diff --git a/src/otari/control_plane.py b/src/otari/control_plane.py index f2fde6d..27a37ea 100644 --- a/src/otari/control_plane.py +++ b/src/otari/control_plane.py @@ -1,7 +1,8 @@ """Typed client for the gateway control-plane (management) endpoints. -Wraps the generated :mod:`otari._control_plane` client. The control-plane -endpoints (API keys, users, budgets, pricing, usage) authenticate with +Wraps the OpenAPI-generated :mod:`otari._client` core (the same core that backs +the inference path under Option C). The control-plane endpoints (API keys, +users, budgets, pricing, usage) authenticate with ``Authorization: Bearer ``, which is distinct from the ``Otari-Key`` virtual key used for inference. Obtain an instance via :attr:`otari.OtariClient.control_plane`. @@ -12,12 +13,12 @@ from functools import cached_property from typing import Any, cast -from otari import _control_plane as _cp -from otari._control_plane.api.budgets_api import BudgetsApi -from otari._control_plane.api.keys_api import KeysApi -from otari._control_plane.api.pricing_api import PricingApi -from otari._control_plane.api.usage_api import UsageApi -from otari._control_plane.api.users_api import UsersApi +from otari import _client as _cp +from otari._client.api.budgets_api import BudgetsApi +from otari._client.api.keys_api import KeysApi +from otari._client.api.pricing_api import PricingApi +from otari._client.api.usage_api import UsageApi +from otari._client.api.users_api import UsersApi class ControlPlane: diff --git a/src/otari/types.py b/src/otari/types.py index 578dfd3..15b1a02 100644 --- a/src/otari/types.py +++ b/src/otari/types.py @@ -1,6 +1,8 @@ """Configuration and type re-exports for the otari gateway client. -Re-exports OpenAI SDK types so consumers don't need to import ``openai`` directly. +Re-exports the OpenAPI-generated response/chunk models from +:mod:`otari._client` so consumers can name them without reaching into the +generated package, plus the SDK's own batch/option types. """ from __future__ import annotations @@ -9,21 +11,18 @@ from typing import Any, TypedDict # --------------------------------------------------------------------------- -# Re-export OpenAI types that callers interact with directly. -# These use explicit `as` aliases to make the re-exports public per PEP 484. -# The TC002 / PLC0414 warnings are intentionally suppressed because these -# imports exist solely for re-export. +# Re-export the generated models that callers interact with directly. +# Explicit ``as`` aliases make these public re-exports per PEP 484. # --------------------------------------------------------------------------- -from openai import AsyncStream as AsyncStream # noqa: PLC0414 -from openai import Stream as Stream # noqa: PLC0414 -from openai.types import CreateEmbeddingResponse as CreateEmbeddingResponse # noqa: PLC0414 -from openai.types import EmbeddingCreateParams as EmbeddingCreateParams # noqa: PLC0414 -from openai.types import Model as Model # noqa: PLC0414 -from openai.types.chat import ChatCompletion as ChatCompletion # noqa: PLC0414, TC002 -from openai.types.chat import ChatCompletionChunk as ChatCompletionChunk # noqa: PLC0414 -from openai.types.chat import ChatCompletionMessageParam as ChatCompletionMessageParam # noqa: PLC0414 -from openai.types.responses import Response as Response # noqa: PLC0414 -from openai.types.responses import ResponseStreamEvent as ResponseStreamEvent # noqa: PLC0414 +from otari._client.models.chat_completion import ChatCompletion as ChatCompletion # noqa: PLC0414 +from otari._client.models.chat_completion_chunk import ChatCompletionChunk as ChatCompletionChunk # noqa: PLC0414 +from otari._client.models.create_embedding_response import ( + CreateEmbeddingResponse as CreateEmbeddingResponse, # noqa: PLC0414 +) +from otari._client.models.message_response import MessageResponse as MessageResponse # noqa: PLC0414 +from otari._client.models.model_object import ModelObject as ModelObject # noqa: PLC0414 +from otari._client.models.moderation_response import ModerationResponse as ModerationResponse # noqa: PLC0414 +from otari._client.models.rerank_response import RerankResponse as RerankResponse # noqa: PLC0414 # --------------------------------------------------------------------------- # Client options @@ -34,7 +33,7 @@ class OtariClientOptions(TypedDict, total=False): """Options for constructing an :class:`~otari.client.OtariClient`. Auth resolution order (mirrors the TypeScript SDK / Python GatewayProvider): - 1. Explicit ``platform_token`` -> platform mode (Bearer token in Authorization header) + 1. Explicit ``platform_token`` -> platform mode (Bearer in Authorization header) 2. ``OTARI_AI_TOKEN`` (or legacy ``GATEWAY_PLATFORM_TOKEN``) env var (when no ``api_key``) -> platform mode 3. ``api_key`` or ``GATEWAY_API_KEY`` env var -> non-platform mode (``Otari-Key`` header) @@ -46,24 +45,20 @@ class OtariClientOptions(TypedDict, total=False): """ api_base: str - """Base URL of the gateway (e.g. ``"http://localhost:8000"``). - - Defaults to ``https://api.otari.ai`` in platform mode.""" + """Base URL of the gateway (defaults to ``https://api.otari.ai`` in platform mode).""" api_key: str """API key for non-platform mode. Sent via ``Otari-Key: Bearer ``.""" platform_token: str - """Platform token for platform mode. Sent as Bearer in the Authorization header. + """Platform token for platform mode. Sent as Bearer in the Authorization header.""" - Falls back to ``OTARI_AI_TOKEN`` (or legacy ``GATEWAY_PLATFORM_TOKEN``).""" + admin_key: str + """Master/admin key for the control-plane endpoints.""" default_headers: dict[str, str] """Additional default headers to send with every request.""" - openai_options: dict[str, Any] - """Extra options forwarded to the underlying ``AsyncOpenAI`` constructor.""" - # --------------------------------------------------------------------------- # Batch types @@ -105,7 +100,7 @@ class BatchResultItem: """Result of a single request within a batch.""" custom_id: str - result: ChatCompletion | None = None + result: dict[str, Any] | None = None error: BatchResultError | None = None diff --git a/tests/integration/test_control_plane_generated.py b/tests/integration/test_control_plane_generated.py index 0481c5f..4125ccf 100644 --- a/tests/integration/test_control_plane_generated.py +++ b/tests/integration/test_control_plane_generated.py @@ -31,14 +31,14 @@ import pytest from otari import OtariClient -from otari._control_plane.exceptions import NotFoundException -from otari._control_plane.models.create_budget_request import CreateBudgetRequest -from otari._control_plane.models.create_key_request import CreateKeyRequest -from otari._control_plane.models.create_user_request import CreateUserRequest -from otari._control_plane.models.set_pricing_request import SetPricingRequest -from otari._control_plane.models.update_budget_request import UpdateBudgetRequest -from otari._control_plane.models.update_key_request import UpdateKeyRequest -from otari._control_plane.models.update_user_request import UpdateUserRequest +from otari._client.exceptions import NotFoundException +from otari._client.models.create_budget_request import CreateBudgetRequest +from otari._client.models.create_key_request import CreateKeyRequest +from otari._client.models.create_user_request import CreateUserRequest +from otari._client.models.set_pricing_request import SetPricingRequest +from otari._client.models.update_budget_request import UpdateBudgetRequest +from otari._client.models.update_key_request import UpdateKeyRequest +from otari._client.models.update_user_request import UpdateUserRequest pytestmark = pytest.mark.integration diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py new file mode 100644 index 0000000..c3f028a --- /dev/null +++ b/tests/unit/conftest.py @@ -0,0 +1,108 @@ +"""Shared test helpers for mocking the generated core's transport. + +Option C wires the SDK over the OpenAPI-generated core (:mod:`otari._client`), +whose non-streaming calls go through ``RESTClientObject.request`` (urllib3) and +whose streaming path is a hand-written raw httpx request. These helpers mock both +seams without a live gateway: + +- :func:`mock_rest` patches ``RESTClientObject.request`` to return a canned + response, exercising the full generated deserialization + the shell's error + mapping. It records the last request (method/url/headers/body) for assertions. +- streaming tests use ``respx`` to mock the httpx transport directly. +""" + +from __future__ import annotations + +import json +from dataclasses import dataclass, field +from typing import Any + +import pytest + +from otari._client.rest import RESTClientObject, RESTResponse + + +@dataclass +class _Urllib3Like: + """Minimal stand-in for a urllib3 ``HTTPResponse`` that ``RESTResponse`` wraps.""" + + status: int + data: bytes + headers: dict[str, str] + reason: str = "OK" + + +@dataclass +class RecordedRequest: + """The last request the generated core issued through the patched transport.""" + + method: str = "" + url: str = "" + headers: dict[str, Any] = field(default_factory=dict) + body: Any = None + + @property + def json_body(self) -> dict[str, Any]: + if isinstance(self.body, (bytes, bytearray)): + return json.loads(self.body.decode()) + if isinstance(self.body, str): + return json.loads(self.body) + return self.body or {} + + +class RestMock: + """Captures the request and serves a canned response for the generated core.""" + + def __init__( + self, + *, + status: int, + body: Any, + headers: dict[str, str] | None = None, + reason: str = "OK", + ) -> None: + self.status = status + self.reason = reason + self.headers = headers or {} + if isinstance(body, (dict, list)): + self.payload = json.dumps(body).encode() + elif isinstance(body, str): + self.payload = body.encode() + else: + self.payload = body + self.last = RecordedRequest() + + def request( + self, + method: str, + url: str, + headers: dict[str, Any] | None = None, + body: Any = None, + post_params: Any = None, # noqa: ARG002 + _request_timeout: Any = None, + ) -> RESTResponse: + self.last = RecordedRequest( + method=method, url=url, headers=dict(headers or {}), body=body + ) + resp = _Urllib3Like( + status=self.status, data=self.payload, headers=self.headers, reason=self.reason + ) + return RESTResponse(resp) + + +@pytest.fixture +def mock_rest(monkeypatch: pytest.MonkeyPatch) -> Any: + """Return a factory that installs a :class:`RestMock` over the generated core.""" + + def _install( + *, + status: int = 200, + body: Any = None, + headers: dict[str, str] | None = None, + reason: str = "OK", + ) -> RestMock: + mock = RestMock(status=status, body=body, headers=headers, reason=reason) + monkeypatch.setattr(RESTClientObject, "request", mock.request) + return mock + + return _install diff --git a/tests/unit/test_async_client.py b/tests/unit/test_async_client.py index 5fb41f0..794e4ee 100644 --- a/tests/unit/test_async_client.py +++ b/tests/unit/test_async_client.py @@ -1,761 +1,165 @@ -"""Tests for AsyncOtariClient. +"""Tests for the asynchronous AsyncOtariClient (Option C: generated-core shell). -Mirrors the TypeScript SDK's ``client.test.ts`` covering constructor, -auth modes, error mapping, and method delegation. +The async client dispatches the (synchronous) generated calls off-thread via +``asyncio.to_thread`` and streams natively over ``httpx.AsyncClient``. Non- +streaming calls reuse the ``mock_rest`` fixture (it patches the same generated +``RESTClientObject.request``); streaming uses ``respx``. """ from __future__ import annotations -from unittest.mock import AsyncMock, MagicMock +from typing import Any import httpx -import openai import pytest +import respx +from otari._client.models.chat_completion import ChatCompletion +from otari._client.models.chat_completion_chunk import ChatCompletionChunk from otari.async_client import AsyncOtariClient from otari.errors import ( AuthenticationError, - BatchNotCompleteError, GatewayTimeoutError, InsufficientFundsError, ModelNotFoundError, OtariError, RateLimitError, - UnsupportedCapabilityError, UpstreamProviderError, ) - -# --------------------------------------------------------------------------- -# Helpers -# --------------------------------------------------------------------------- - - -def _make_api_error( - status: int, - message: str, - headers: dict[str, str] | None = None, -) -> openai.APIStatusError: - """Build a fake ``openai.APIStatusError`` for testing error mapping.""" - resp_headers = httpx.Headers(headers or {}) - request = httpx.Request("POST", "https://example.com/v1/chat/completions") - response = httpx.Response(status_code=status, headers=resp_headers, request=request) - return openai.APIStatusError( - message=message, - response=response, - body={"message": message}, - ) - - -# --------------------------------------------------------------------------- -# Constructor tests -# --------------------------------------------------------------------------- +from tests.unit.test_client import ( + CHAT_RESPONSE, + EMBEDDING_RESPONSE, + MESSAGE_RESPONSE, + MODELS_RESPONSE, + RERANK_RESPONSE, + _sse, +) class TestConstructor: def test_throws_when_api_base_missing(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.delenv("GATEWAY_API_BASE", raising=False) - with pytest.raises(ValueError, match="api_base is required"): - AsyncOtariClient() - - def test_uses_api_base_from_options(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000") - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" - - def test_does_not_double_append_v1(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000/v1") - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" - - def test_strips_trailing_slash(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000/") - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" - - def test_falls_back_to_env_var(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_API_BASE", "http://env-gateway:9000") - client = AsyncOtariClient() - assert str(client.openai.base_url).rstrip("/") == "http://env-gateway:9000/v1" - - -class TestPlatformMode: - def test_activates_with_explicit_token(self) -> None: - client = AsyncOtariClient( - api_base="http://localhost:8000", - platform_token="tk_test123", # noqa: S106 - ) - assert client.platform_mode is True - assert client.openai.api_key == "tk_test123" - - def test_activates_via_env_when_no_api_key(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_env_token") - client = AsyncOtariClient(api_base="http://localhost:8000") - assert client.platform_mode is True - assert client.openai.api_key == "tk_env_token" - - def test_does_not_activate_when_api_key_provided(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_env_token") - client = AsyncOtariClient(api_base="http://localhost:8000", api_key="my-key") - assert client.platform_mode is False - - -class TestHostedDefault: - """Hosted-gateway default + OTARI_AI_TOKEN precedence (parity with TS SDK).""" - - @staticmethod - def _clear_env(monkeypatch: pytest.MonkeyPatch) -> None: for name in ("GATEWAY_API_BASE", "OTARI_AI_TOKEN", "GATEWAY_PLATFORM_TOKEN"): monkeypatch.delenv(name, raising=False) - - def test_platform_token_uses_hosted_default_base(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - client = AsyncOtariClient(platform_token="tk_x") # noqa: S106 - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "https://api.otari.ai/v1" - - def test_otari_ai_token_env_uses_hosted_default(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - monkeypatch.setenv("OTARI_AI_TOKEN", "tk_env") - client = AsyncOtariClient() - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "https://api.otari.ai/v1" - - def test_api_key_only_no_base_still_raises(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) with pytest.raises(ValueError, match="api_base is required"): - AsyncOtariClient(api_key="k") - - def test_legacy_platform_token_env_uses_hosted_default(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_legacy") - client = AsyncOtariClient() - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "https://api.otari.ai/v1" - - def test_canonical_token_takes_precedence_over_legacy(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - monkeypatch.setenv("OTARI_AI_TOKEN", "tk_canonical") - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_legacy") - client = AsyncOtariClient() - assert client.platform_mode is True - assert client.openai.api_key == "tk_canonical" - assert client._auth_headers["Authorization"] == "Bearer tk_canonical" + AsyncOtariClient() - def test_explicit_api_base_overrides_hosted_default(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - client = AsyncOtariClient(api_base="http://localhost:8000", platform_token="tk_x") # noqa: S106 + def test_platform_mode_sets_bearer(self) -> None: + client = AsyncOtariClient(api_base="http://localhost:8000", platform_token="tk") # noqa: S106 assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" - + assert client._api.default_headers["Authorization"] == "Bearer tk" -class TestNonPlatformMode: - def test_is_default_without_platform_token(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.delenv("GATEWAY_PLATFORM_TOKEN", raising=False) - client = AsyncOtariClient(api_base="http://localhost:8000") + def test_non_platform_mode_sets_otari_key(self) -> None: + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") assert client.platform_mode is False + assert client._api.default_headers["Otari-Key"] == "Bearer vk" - def test_falls_back_to_api_key_env(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_API_KEY", "env-key") - monkeypatch.delenv("GATEWAY_PLATFORM_TOKEN", raising=False) - client = AsyncOtariClient(api_base="http://localhost:8000") - assert client.platform_mode is False - - def test_forwards_default_headers(self) -> None: - client = AsyncOtariClient( - api_base="http://localhost:8000", - default_headers={"X-Custom": "value"}, - ) - assert client is not None - - -# --------------------------------------------------------------------------- -# Error handling (platform mode) -# --------------------------------------------------------------------------- - - -class TestErrorHandlingPlatformMode: - @pytest.fixture - def client(self) -> AsyncOtariClient: - return AsyncOtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - @pytest.mark.asyncio - async def test_maps_401_to_authentication_error(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - with pytest.raises(AuthenticationError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_maps_403_to_authentication_error(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(403, "Forbidden"), - ) - with pytest.raises(AuthenticationError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_maps_404_to_model_not_found(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(404, "Not Found"), - ) - with pytest.raises(ModelNotFoundError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_maps_402_to_insufficient_funds(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(402, "Payment Required"), - ) - with pytest.raises(InsufficientFundsError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_maps_429_to_rate_limit_with_retry_after(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(429, "Too Many Requests", {"retry-after": "60"}), - ) - with pytest.raises(RateLimitError) as exc_info: - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.retry_after == "60" - - @pytest.mark.asyncio - async def test_maps_502_to_upstream_provider_error(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(502, "Bad Gateway"), - ) - with pytest.raises(UpstreamProviderError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_maps_504_to_gateway_timeout(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(504, "Gateway Timeout"), - ) - with pytest.raises(GatewayTimeoutError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_includes_correlation_id_in_message(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized", {"x-correlation-id": "abc-123"}), - ) - with pytest.raises(AuthenticationError, match="correlation_id=abc-123"): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_passes_through_unrecognized_status(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(418, "I'm a teapot"), - ) - with pytest.raises(openai.APIStatusError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_passes_through_non_api_error(self, client: AsyncOtariClient) -> None: - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=TypeError("network failure"), - ) - with pytest.raises(TypeError, match="network failure"): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_stores_original_error(self, client: AsyncOtariClient) -> None: - api_err = _make_api_error(401, "Unauthorized") - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=api_err, - ) - with pytest.raises(AuthenticationError) as exc_info: - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.original_error is api_err - assert exc_info.value.provider_name == "gateway" - assert exc_info.value.status_code == 401 - - -# --------------------------------------------------------------------------- -# Error handling (non-platform mode) -# --------------------------------------------------------------------------- - - -class TestErrorHandlingNonPlatformMode: - @pytest.mark.asyncio - async def test_does_not_map_errors(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - # In non-platform mode, the raw APIStatusError should pass through. - with pytest.raises(openai.APIStatusError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_error_is_not_otari_error(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - with pytest.raises(openai.APIStatusError) as exc_info: - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert not isinstance(exc_info.value, OtariError) - - -# --------------------------------------------------------------------------- -# Unsupported capability error (both modes) -# --------------------------------------------------------------------------- - - -class TestUnsupportedCapabilityError: - @pytest.mark.asyncio - async def test_surfaces_in_platform_mode(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", platform_token="tk_test") # noqa: S106 - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(400, "Provider anthropic does not support moderation"), - ) - with pytest.raises(UnsupportedCapabilityError) as exc_info: - await client.completion( - model="anthropic:claude-3", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.capability == "moderation" - assert exc_info.value.provider == "anthropic" - - @pytest.mark.asyncio - async def test_surfaces_in_non_platform_mode(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(400, "Provider anthropic does not support moderation"), - ) - with pytest.raises(UnsupportedCapabilityError) as exc_info: - await client.completion( - model="anthropic:claude-3", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.capability == "moderation" - - @pytest.mark.asyncio - async def test_multimodal_moderation(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", platform_token="tk_test") # noqa: S106 - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error( - 400, "Provider openai does not support multimodal moderation for this model" - ), - ) - with pytest.raises(UnsupportedCapabilityError) as exc_info: - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.capability == "multimodal_moderation" - - @pytest.mark.asyncio - async def test_unrelated_400_passes_through_in_non_platform(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(400, "Invalid request parameters"), - ) - with pytest.raises(openai.APIStatusError): - await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - -# --------------------------------------------------------------------------- -# Method delegation -# --------------------------------------------------------------------------- - - -class TestMethodDelegation: - @pytest.fixture - def client(self) -> AsyncOtariClient: - return AsyncOtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - @pytest.mark.asyncio - async def test_completion_delegates(self, client: AsyncOtariClient) -> None: - mock_response = MagicMock() - mock_response.id = "chatcmpl-123" - mock_response.choices = [] - client.openai.chat.completions.create = AsyncMock(return_value=mock_response) # type: ignore[method-assign] +class TestInference: + async def test_completion_returns_typed(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=CHAT_RESPONSE) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") result = await client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert result is mock_response - client.openai.chat.completions.create.assert_called_once_with( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - @pytest.mark.asyncio - async def test_embedding_delegates(self, client: AsyncOtariClient) -> None: - mock_response = MagicMock() - client.openai.embeddings.create = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.embedding( - model="openai:text-embedding-3-small", - input="hello", - ) - assert result is mock_response - client.openai.embeddings.create.assert_called_once_with( - model="openai:text-embedding-3-small", - input="hello", - ) - - @pytest.mark.asyncio - async def test_response_delegates(self, client: AsyncOtariClient) -> None: - mock_response = MagicMock() - client.openai.responses.create = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.response( - model="openai:gpt-4o-mini", - input="hello", - ) - assert result is mock_response - - @pytest.mark.asyncio - async def test_list_models_delegates(self, client: AsyncOtariClient) -> None: - mock_models = [ - MagicMock(id="model-1"), - MagicMock(id="model-2"), - ] - - mock_page = MagicMock() - - async def _aiter(_self: object) -> None: - for m in mock_models: - yield m - - mock_page.__aiter__ = _aiter - client.openai.models.list = AsyncMock(return_value=mock_page) # type: ignore[method-assign] - - result = await client.list_models() - assert result == mock_models - - @pytest.mark.asyncio - async def test_error_mapping_on_embedding(self, client: AsyncOtariClient) -> None: - client.openai.embeddings.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - with pytest.raises(AuthenticationError): - await client.embedding(model="openai:text-embedding-3-small", input="hello") - - @pytest.mark.asyncio - async def test_error_mapping_on_response(self, client: AsyncOtariClient) -> None: - client.openai.responses.create = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(429, "Rate limited"), + model="openai:gpt-4o-mini", messages=[{"role": "user", "content": "Hi"}] + ) + assert isinstance(result, ChatCompletion) + assert result.choices[0].message.content == "Hi" + assert mock.last.url.endswith("/v1/chat/completions") + assert mock.last.headers.get("Otari-Key") == "Bearer vk" + + async def test_embedding_returns_typed(self, mock_rest: Any) -> None: + mock_rest(status=200, body=EMBEDDING_RESPONSE) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + result = await client.embedding(model="m", input="hi") + assert result.data[0].embedding == [0.1, 0.2] + + async def test_rerank_returns_typed(self, mock_rest: Any) -> None: + mock_rest(status=200, body=RERANK_RESPONSE) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + result = await client.rerank(model="m", query="q", documents=["a"]) + assert result.results[0].relevance_score == 0.9 + + async def test_message_returns_typed(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=MESSAGE_RESPONSE) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + result = await client.message( + model="anthropic:claude", messages=[{"role": "user", "content": "Hi"}], max_tokens=8 + ) + assert result.id == "msg-1" + assert mock.last.url.endswith("/v1/messages") + + async def test_list_models_returns_typed(self, mock_rest: Any) -> None: + mock_rest(status=200, body=MODELS_RESPONSE) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + models = await client.list_models() + assert models[0].id == "openai:gpt-4o" + + +@pytest.mark.parametrize( + ("status", "expected"), + [ + (401, AuthenticationError), + (402, InsufficientFundsError), + (404, ModelNotFoundError), + (429, RateLimitError), + (502, UpstreamProviderError), + (504, GatewayTimeoutError), + (418, OtariError), + ], +) +class TestErrorMapping: + async def test_status_maps( + self, mock_rest: Any, status: int, expected: type[OtariError] + ) -> None: + mock_rest(status=status, body={"detail": "boom"}, reason="err") + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + with pytest.raises(expected) as exc_info: + await client.completion(model="m", messages=[{"role": "user", "content": "Hi"}]) + assert exc_info.value.status_code == status + + +class TestStreaming: + @respx.mock + async def test_yields_typed_chunks_and_stops_on_done(self) -> None: + chunk1 = ( + '{"id":"c","object":"chat.completion.chunk","created":1,"model":"m",' + '"choices":[{"index":0,"delta":{"role":"assistant","content":"He"}}]}' + ) + chunk2 = ( + '{"id":"c","object":"chat.completion.chunk","created":1,"model":"m",' + '"choices":[{"index":0,"delta":{"content":"llo"}}]}' + ) + route = respx.post("http://localhost:8000/v1/chat/completions").mock( + return_value=httpx.Response( + 200, + headers={"content-type": "text/event-stream"}, + content=_sse(chunk1, chunk2), + ) + ) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + stream = await client.completion( + model="m", messages=[{"role": "user", "content": "Hi"}], stream=True + ) + chunks = [chunk async for chunk in stream] + assert all(isinstance(c, ChatCompletionChunk) for c in chunks) + assert [c.choices[0].delta.content for c in chunks] == ["He", "llo"] + assert route.calls.last.request.headers["accept"] == "text/event-stream" + assert route.calls.last.request.headers["otari-key"] == "Bearer vk" + + @respx.mock + async def test_streaming_error_maps(self) -> None: + respx.post("http://localhost:8000/v1/chat/completions").mock( + return_value=httpx.Response(429, json={"detail": "rate limited"}) + ) + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + stream = await client.completion( + model="m", messages=[{"role": "user", "content": "Hi"}], stream=True ) with pytest.raises(RateLimitError): - await client.response(model="openai:gpt-4o-mini", input="hello") - - @pytest.mark.asyncio - async def test_error_mapping_on_list_models(self, client: AsyncOtariClient) -> None: - client.openai.models.list = AsyncMock( # type: ignore[method-assign] - side_effect=_make_api_error(502, "Bad Gateway"), - ) - with pytest.raises(UpstreamProviderError): - await client.list_models() - - -# --------------------------------------------------------------------------- -# Batch operations -# --------------------------------------------------------------------------- - - -class TestBatchOperations: - @pytest.fixture - def client(self) -> AsyncOtariClient: - return AsyncOtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - @pytest.mark.asyncio - async def test_create_batch(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"id": "batch-123", "status": "created", "provider": "openai"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [{"custom_id": "r1", "body": {"messages": []}}], - }) - assert result["id"] == "batch-123" - - @pytest.mark.asyncio - async def test_retrieve_batch(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"id": "batch-123", "status": "completed"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.retrieve_batch("batch-123", "openai") - assert result["status"] == "completed" - - @pytest.mark.asyncio - async def test_cancel_batch(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"id": "batch-123", "status": "cancelled"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.cancel_batch("batch-123", "openai") - assert result["status"] == "cancelled" - - @pytest.mark.asyncio - async def test_list_batches(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"data": [{"id": "b1"}, {"id": "b2"}]}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.list_batches("openai") - assert len(result) == 2 - - @pytest.mark.asyncio - async def test_retrieve_batch_results(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 200, - json={ - "results": [ - {"custom_id": "r1", "result": {"id": "cmpl-1", "choices": []}}, - {"custom_id": "r2", "error": {"code": "err", "message": "failed"}}, - ] - }, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - result = await client.retrieve_batch_results("batch-123", "openai") - assert len(result.results) == 2 - assert result.results[0].custom_id == "r1" - assert result.results[1].error is not None - - -class TestBatchErrorHandling: - @pytest.fixture - def client(self) -> AsyncOtariClient: - return AsyncOtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - @pytest.mark.asyncio - async def test_409_maps_to_batch_not_complete(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 409, - json={"detail": "Batch 'batch-123' is not complete (status: in_progress)"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(BatchNotCompleteError) as exc_info: - await client.retrieve_batch_results("batch-123", "openai") - assert exc_info.value.batch_id == "batch-123" - assert exc_info.value.batch_status == "in_progress" - - @pytest.mark.asyncio - async def test_404_suggests_upgrade(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 404, - json={"detail": "Not supported"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(OtariError, match="Upgrade your gateway"): - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - @pytest.mark.asyncio - async def test_404_passes_through_not_found(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 404, - json={"detail": "Batch not found"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(OtariError, match="not found"): - await client.retrieve_batch("batch-xyz", "openai") - - @pytest.mark.asyncio - async def test_401_maps_to_authentication_error(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 401, - json={"detail": "Invalid key"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(AuthenticationError): - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - @pytest.mark.asyncio - async def test_429_maps_to_rate_limit(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 429, - headers={"retry-after": "30"}, - json={"detail": "Rate limited"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(RateLimitError) as exc_info: - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - assert exc_info.value.retry_after == "30" - - @pytest.mark.asyncio - async def test_502_maps_to_upstream_error(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 502, - json={"detail": "Bad Gateway"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(UpstreamProviderError): - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - @pytest.mark.asyncio - async def test_504_maps_to_gateway_timeout(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 504, - json={"detail": "Gateway Timeout"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(GatewayTimeoutError): - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - @pytest.mark.asyncio - async def test_correlation_id_in_batch_error(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 401, - headers={"x-correlation-id": "corr-456"}, - json={"detail": "Invalid key"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(AuthenticationError, match="correlation_id=corr-456"): - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - @pytest.mark.asyncio - async def test_unknown_status_maps_to_otari_error(self, client: AsyncOtariClient) -> None: - mock_response = httpx.Response( - 418, - json={"detail": "I'm a teapot"}, - ) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(OtariError): - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - -# --------------------------------------------------------------------------- -# Batch auth modes -# --------------------------------------------------------------------------- - - -class TestBatchAuthModes: - @pytest.mark.asyncio - async def test_non_platform_sends_otari_key(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", api_key="my-key") - mock_response = httpx.Response(200, json={"id": "b1", "provider": "openai"}) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - call_kwargs = client._http.request.call_args - headers = call_kwargs.kwargs.get("headers") or call_kwargs[1].get("headers", {}) - assert headers.get("Otari-Key") == "Bearer my-key" - assert "Authorization" not in headers - - @pytest.mark.asyncio - async def test_platform_sends_authorization(self) -> None: - client = AsyncOtariClient(api_base="http://localhost:8000", platform_token="tk_123") # noqa: S106 - mock_response = httpx.Response(200, json={"id": "b1", "provider": "openai"}) - client._http.request = AsyncMock(return_value=mock_response) # type: ignore[method-assign] - - await client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - call_kwargs = client._http.request.call_args - headers = call_kwargs.kwargs.get("headers") or call_kwargs[1].get("headers", {}) - assert headers.get("Authorization") == "Bearer tk_123" - assert "Otari-Key" not in headers - - -# --------------------------------------------------------------------------- -# Context manager -# --------------------------------------------------------------------------- + _ = [chunk async for chunk in stream] -class TestContextManager: - @pytest.mark.asyncio - async def test_async_context_manager(self) -> None: - async with AsyncOtariClient(api_base="http://localhost:8000") as client: - assert client.platform_mode is False +class TestControlPlane: + def test_requires_admin_credential(self) -> None: + client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk") + with pytest.raises(OtariError, match="admin credential"): + _ = client.control_plane diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 50a97f0..dc8d4c8 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -1,21 +1,25 @@ -"""Tests for the synchronous OtariClient. +"""Tests for the synchronous OtariClient (Option C: generated-core shell). -Mirrors the TypeScript SDK's ``client.test.ts`` covering constructor, -auth modes, error mapping, and method delegation. +Covers constructor / auth-mode wiring, request shaping, typed response parsing, +generated ``ApiException`` -> typed error mapping, and the hand-written SSE +streaming shim. Non-streaming calls are mocked at the generated transport +(``RESTClientObject.request``, see ``conftest.py``); streaming is mocked with +``respx`` over the httpx layer the shim uses. """ from __future__ import annotations -from unittest.mock import MagicMock +from typing import Any import httpx -import openai import pytest +import respx +from otari._client.models.chat_completion import ChatCompletion +from otari._client.models.chat_completion_chunk import ChatCompletionChunk from otari.client import OtariClient from otari.errors import ( AuthenticationError, - BatchNotCompleteError, GatewayTimeoutError, InsufficientFundsError, ModelNotFoundError, @@ -26,690 +30,347 @@ ) # --------------------------------------------------------------------------- -# Helpers +# Response fixtures (validated against the generated models) # --------------------------------------------------------------------------- - -def _make_api_error( - status: int, - message: str, - headers: dict[str, str] | None = None, -) -> openai.APIStatusError: - """Build a fake ``openai.APIStatusError`` for testing error mapping.""" - resp_headers = httpx.Headers(headers or {}) - request = httpx.Request("POST", "https://example.com/v1/chat/completions") - response = httpx.Response(status_code=status, headers=resp_headers, request=request) - return openai.APIStatusError( - message=message, - response=response, - body={"message": message}, - ) +CHAT_RESPONSE: dict[str, Any] = { + "id": "chatcmpl-1", + "object": "chat.completion", + "created": 1, + "model": "openai:gpt-4o-mini", + "choices": [ + {"index": 0, "finish_reason": "stop", "message": {"role": "assistant", "content": "Hi"}} + ], +} + +EMBEDDING_RESPONSE: dict[str, Any] = { + "object": "list", + "model": "openai:text-embedding-3-small", + "data": [{"object": "embedding", "index": 0, "embedding": [0.1, 0.2]}], + "usage": {"prompt_tokens": 1, "total_tokens": 1}, +} + +RERANK_RESPONSE: dict[str, Any] = { + "id": "rerank-1", + "results": [{"index": 0, "relevance_score": 0.9}], +} + +MESSAGE_RESPONSE: dict[str, Any] = { + "id": "msg-1", + "type": "message", + "role": "assistant", + "model": "anthropic:claude-3-5-sonnet", + "content": [{"type": "text", "text": "Hi"}], + "usage": {"input_tokens": 1, "output_tokens": 1}, +} + +MODERATION_RESPONSE: dict[str, Any] = { + "id": "modr-1", + "model": "openai:omni-moderation-latest", + "results": [{"flagged": False, "categories": {}, "category_scores": {}}], +} + +MODELS_RESPONSE: dict[str, Any] = { + "object": "list", + "data": [{"id": "openai:gpt-4o", "object": "model", "created": 1, "owned_by": "openai"}], +} + + +def _sse(*events: str) -> bytes: + """Build a ``text/event-stream`` body from JSON event strings + the DONE sentinel.""" + body = "".join(f"data: {e}\n\n" for e in events) + return (body + "data: [DONE]\n\n").encode() # --------------------------------------------------------------------------- -# Constructor tests +# Constructor / auth-mode wiring # --------------------------------------------------------------------------- class TestConstructor: def test_throws_when_api_base_missing(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.delenv("GATEWAY_API_BASE", raising=False) + for name in ("GATEWAY_API_BASE", "OTARI_AI_TOKEN", "GATEWAY_PLATFORM_TOKEN"): + monkeypatch.delenv(name, raising=False) with pytest.raises(ValueError, match="api_base is required"): OtariClient() def test_uses_api_base_from_options(self) -> None: client = OtariClient(api_base="http://localhost:8000") - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" + assert client._base_url == "http://localhost:8000/v1" + assert client._gateway_root_url == "http://localhost:8000" def test_does_not_double_append_v1(self) -> None: client = OtariClient(api_base="http://localhost:8000/v1") - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" + assert client._base_url == "http://localhost:8000/v1" def test_strips_trailing_slash(self) -> None: client = OtariClient(api_base="http://localhost:8000/") - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" + assert client._base_url == "http://localhost:8000/v1" def test_falls_back_to_env_var(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("GATEWAY_API_BASE", "http://env-gateway:9000") client = OtariClient() - assert str(client.openai.base_url).rstrip("/") == "http://env-gateway:9000/v1" + assert client._base_url == "http://env-gateway:9000/v1" -class TestPlatformMode: - def test_activates_with_explicit_token(self) -> None: - client = OtariClient( - api_base="http://localhost:8000", - platform_token="tk_test123", # noqa: S106 - ) +class TestAuthModes: + def test_platform_mode_sets_bearer_header(self) -> None: + client = OtariClient(api_base="http://localhost:8000", platform_token="tk_test") # noqa: S106 assert client.platform_mode is True - assert client.openai.api_key == "tk_test123" + assert client._default_headers["Authorization"] == "Bearer tk_test" + assert "Otari-Key" not in client._default_headers + # The header is fed into the generated ApiClient default headers. + assert client._api.default_headers["Authorization"] == "Bearer tk_test" - def test_activates_via_env_when_no_api_key(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_env_token") + def test_platform_mode_via_env(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("OTARI_AI_TOKEN", "tk_env") client = OtariClient(api_base="http://localhost:8000") assert client.platform_mode is True - assert client.openai.api_key == "tk_env_token" + assert client._default_headers["Authorization"] == "Bearer tk_env" - def test_does_not_activate_when_api_key_provided(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_env_token") - client = OtariClient(api_base="http://localhost:8000", api_key="my-key") + def test_non_platform_mode_sets_otari_key_header(self) -> None: + client = OtariClient(api_base="http://localhost:8000", api_key="vk_123") assert client.platform_mode is False + assert client._default_headers["Otari-Key"] == "Bearer vk_123" + assert "Authorization" not in client._default_headers + assert client._api.default_headers["Otari-Key"] == "Bearer vk_123" + def test_api_key_overrides_platform_token_env(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_env") + client = OtariClient(api_base="http://localhost:8000", api_key="vk_123") + assert client.platform_mode is False -class TestHostedDefault: - """Hosted-gateway default + OTARI_AI_TOKEN precedence (parity with TS SDK).""" - - @staticmethod - def _clear_env(monkeypatch: pytest.MonkeyPatch) -> None: + def test_hosted_default_base_in_platform_mode(self, monkeypatch: pytest.MonkeyPatch) -> None: for name in ("GATEWAY_API_BASE", "OTARI_AI_TOKEN", "GATEWAY_PLATFORM_TOKEN"): monkeypatch.delenv(name, raising=False) - - def test_platform_token_uses_hosted_default_base(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) client = OtariClient(platform_token="tk_x") # noqa: S106 - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "https://api.otari.ai/v1" - - def test_otari_ai_token_env_uses_hosted_default(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - monkeypatch.setenv("OTARI_AI_TOKEN", "tk_env") - client = OtariClient() - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "https://api.otari.ai/v1" - - def test_api_key_only_no_base_still_raises(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - with pytest.raises(ValueError, match="api_base is required"): - OtariClient(api_key="k") - - def test_legacy_platform_token_env_uses_hosted_default(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_legacy") - client = OtariClient() - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "https://api.otari.ai/v1" - - def test_canonical_token_takes_precedence_over_legacy(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - monkeypatch.setenv("OTARI_AI_TOKEN", "tk_canonical") - monkeypatch.setenv("GATEWAY_PLATFORM_TOKEN", "tk_legacy") - client = OtariClient() - assert client.platform_mode is True - assert client.openai.api_key == "tk_canonical" - assert client._auth_headers["Authorization"] == "Bearer tk_canonical" - - def test_explicit_api_base_overrides_hosted_default(self, monkeypatch: pytest.MonkeyPatch) -> None: - self._clear_env(monkeypatch) - client = OtariClient(api_base="http://localhost:8000", platform_token="tk_x") # noqa: S106 - assert client.platform_mode is True - assert str(client.openai.base_url).rstrip("/") == "http://localhost:8000/v1" - - -class TestNonPlatformMode: - def test_is_default_without_platform_token(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.delenv("GATEWAY_PLATFORM_TOKEN", raising=False) - client = OtariClient(api_base="http://localhost:8000") - assert client.platform_mode is False - - def test_falls_back_to_api_key_env(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("GATEWAY_API_KEY", "env-key") - monkeypatch.delenv("GATEWAY_PLATFORM_TOKEN", raising=False) - client = OtariClient(api_base="http://localhost:8000") - assert client.platform_mode is False - - def test_forwards_default_headers(self) -> None: - client = OtariClient( - api_base="http://localhost:8000", - default_headers={"X-Custom": "value"}, - ) - assert client is not None + assert client._base_url == "https://api.otari.ai/v1" # --------------------------------------------------------------------------- -# Error handling (platform mode) +# Request shaping + typed response parsing # --------------------------------------------------------------------------- -class TestErrorHandlingPlatformMode: - @pytest.fixture - def client(self) -> OtariClient: - return OtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - def test_maps_401_to_authentication_error(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - with pytest.raises(AuthenticationError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_maps_403_to_authentication_error(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(403, "Forbidden"), - ) - with pytest.raises(AuthenticationError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_maps_404_to_model_not_found(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(404, "Not Found"), - ) - with pytest.raises(ModelNotFoundError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_maps_402_to_insufficient_funds(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(402, "Payment Required"), - ) - with pytest.raises(InsufficientFundsError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_maps_429_to_rate_limit_with_retry_after(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(429, "Too Many Requests", {"retry-after": "60"}), - ) - with pytest.raises(RateLimitError) as exc_info: - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.retry_after == "60" - - def test_maps_502_to_upstream_provider_error(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(502, "Bad Gateway"), - ) - with pytest.raises(UpstreamProviderError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_maps_504_to_gateway_timeout(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(504, "Gateway Timeout"), - ) - with pytest.raises(GatewayTimeoutError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_includes_correlation_id_in_message(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized", {"x-correlation-id": "abc-123"}), - ) - with pytest.raises(AuthenticationError, match="correlation_id=abc-123"): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_passes_through_unrecognized_status(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(418, "I'm a teapot"), - ) - with pytest.raises(openai.APIStatusError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_passes_through_non_api_error(self, client: OtariClient) -> None: - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=TypeError("network failure"), - ) - with pytest.raises(TypeError, match="network failure"): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_stores_original_error(self, client: OtariClient) -> None: - api_err = _make_api_error(401, "Unauthorized") - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=api_err, - ) - with pytest.raises(AuthenticationError) as exc_info: - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.original_error is api_err - assert exc_info.value.provider_name == "gateway" - assert exc_info.value.status_code == 401 +class TestCompletion: + def test_returns_typed_chat_completion(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=CHAT_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + result = client.completion( + model="openai:gpt-4o-mini", + messages=[{"role": "user", "content": "Hi"}], + temperature=0.5, + ) + assert isinstance(result, ChatCompletion) + assert result.choices[0].message.content == "Hi" + # Request shaping: correct path + body, with the Otari-Key auth header. + assert mock.last.method == "POST" + assert mock.last.url.endswith("/v1/chat/completions") + body = mock.last.json_body + assert body["model"] == "openai:gpt-4o-mini" + assert body["temperature"] == 0.5 + assert mock.last.headers.get("Otari-Key") == "Bearer vk" + + def test_platform_mode_sends_bearer(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=CHAT_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", platform_token="tk") # noqa: S106 + client.completion(model="m", messages=[{"role": "user", "content": "Hi"}]) + assert mock.last.headers.get("Authorization") == "Bearer tk" + + +class TestEmbedding: + def test_returns_typed_embedding(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=EMBEDDING_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + result = client.embedding(model="openai:text-embedding-3-small", input="hello") + assert result.data[0].embedding == [0.1, 0.2] + assert mock.last.url.endswith("/v1/embeddings") + assert mock.last.json_body["input"] == "hello" + + +class TestRerank: + def test_returns_typed_rerank(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=RERANK_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + result = client.rerank(model="m", query="q", documents=["a", "b"]) + assert result.results[0].relevance_score == 0.9 + assert mock.last.url.endswith("/v1/rerank") + assert mock.last.json_body["documents"] == ["a", "b"] + + +class TestMessage: + def test_returns_typed_message_response(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=MESSAGE_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + result = client.message( + model="anthropic:claude-3-5-sonnet", + messages=[{"role": "user", "content": "Hi"}], + max_tokens=64, + ) + assert result.id == "msg-1" + assert mock.last.url.endswith("/v1/messages") + body = mock.last.json_body + assert body["max_tokens"] == 64 + assert body["model"] == "anthropic:claude-3-5-sonnet" + + +class TestModeration: + def test_returns_typed_moderation(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=MODERATION_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + result = client.moderation(model="m", input="text") + assert result.results[0].flagged is False + assert mock.last.url.endswith("/v1/moderations") + + +class TestListModels: + def test_returns_typed_models(self, mock_rest: Any) -> None: + mock = mock_rest(status=200, body=MODELS_RESPONSE) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + models = client.list_models() + assert models[0].id == "openai:gpt-4o" + assert mock.last.url.endswith("/v1/models") # --------------------------------------------------------------------------- -# Error handling (non-platform mode) +# Error mapping (generated ApiException -> typed otari errors) # --------------------------------------------------------------------------- -class TestErrorHandlingNonPlatformMode: - def test_does_not_map_errors(self) -> None: - client = OtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - # In non-platform mode, the raw APIStatusError should pass through. - with pytest.raises(openai.APIStatusError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_error_is_not_otari_error(self) -> None: - client = OtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), - ) - with pytest.raises(openai.APIStatusError) as exc_info: - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert not isinstance(exc_info.value, OtariError) - - -# --------------------------------------------------------------------------- -# Unsupported capability error (both modes) -# --------------------------------------------------------------------------- +@pytest.mark.parametrize( + ("status", "expected"), + [ + (401, AuthenticationError), + (403, AuthenticationError), + (402, InsufficientFundsError), + (404, ModelNotFoundError), + (429, RateLimitError), + (502, UpstreamProviderError), + (503, UpstreamProviderError), + (504, GatewayTimeoutError), + (418, OtariError), + ], +) +class TestErrorMapping: + def test_status_maps_to_error( + self, mock_rest: Any, status: int, expected: type[OtariError] + ) -> None: + mock_rest(status=status, body={"detail": "boom"}, reason="err") + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + with pytest.raises(expected) as exc_info: + client.completion(model="m", messages=[{"role": "user", "content": "Hi"}]) + assert exc_info.value.status_code == status + assert "boom" in str(exc_info.value) + + +class TestErrorDetails: + def test_rate_limit_carries_retry_after(self, mock_rest: Any) -> None: + mock_rest(status=429, body={"detail": "slow down"}, headers={"retry-after": "30"}) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + with pytest.raises(RateLimitError) as exc_info: + client.completion(model="m", messages=[{"role": "user", "content": "Hi"}]) + assert exc_info.value.retry_after == "30" + def test_correlation_id_in_message(self, mock_rest: Any) -> None: + mock_rest(status=402, body={"detail": "no funds"}, headers={"x-correlation-id": "abc-123"}) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + with pytest.raises(InsufficientFundsError) as exc_info: + client.completion(model="m", messages=[{"role": "user", "content": "Hi"}]) + assert "abc-123" in str(exc_info.value) -class TestUnsupportedCapabilityError: - def test_surfaces_in_platform_mode(self) -> None: - client = OtariClient(api_base="http://localhost:8000", platform_token="tk_test") # noqa: S106 - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(400, "Provider anthropic does not support moderation"), + def test_unsupported_moderation_maps_in_any_mode(self, mock_rest: Any) -> None: + mock_rest( + status=400, body={"detail": "Provider anthropic does not support moderation"} ) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") with pytest.raises(UnsupportedCapabilityError) as exc_info: - client.completion( - model="anthropic:claude-3", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.capability == "moderation" + client.moderation(model="anthropic:claude", input="text") assert exc_info.value.provider == "anthropic" - - def test_surfaces_in_non_platform_mode(self) -> None: - client = OtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(400, "Provider anthropic does not support moderation"), - ) - with pytest.raises(UnsupportedCapabilityError) as exc_info: - client.completion( - model="anthropic:claude-3", - messages=[{"role": "user", "content": "hi"}], - ) assert exc_info.value.capability == "moderation" - def test_multimodal_moderation(self) -> None: - client = OtariClient(api_base="http://localhost:8000", platform_token="tk_test") # noqa: S106 - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error( - 400, "Provider openai does not support multimodal moderation for this model" - ), - ) - with pytest.raises(UnsupportedCapabilityError) as exc_info: - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert exc_info.value.capability == "multimodal_moderation" - - def test_unrelated_400_passes_through_in_non_platform(self) -> None: - client = OtariClient(api_base="http://localhost:8000", api_key="my-key") - client.openai.chat.completions.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(400, "Invalid request parameters"), - ) - with pytest.raises(openai.APIStatusError): - client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - # --------------------------------------------------------------------------- -# Method delegation +# SSE streaming shim (chat = must-have) # --------------------------------------------------------------------------- -class TestMethodDelegation: - @pytest.fixture - def client(self) -> OtariClient: - return OtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - def test_completion_delegates(self, client: OtariClient) -> None: - mock_response = MagicMock() - mock_response.id = "chatcmpl-123" - mock_response.choices = [] - client.openai.chat.completions.create = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.completion( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - assert result is mock_response - client.openai.chat.completions.create.assert_called_once_with( - model="openai:gpt-4o-mini", - messages=[{"role": "user", "content": "hi"}], - ) - - def test_embedding_delegates(self, client: OtariClient) -> None: - mock_response = MagicMock() - client.openai.embeddings.create = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.embedding( - model="openai:text-embedding-3-small", - input="hello", +class TestChatStreaming: + @respx.mock + def test_yields_typed_chunks_and_stops_on_done(self) -> None: + chunk1 = ( + '{"id":"c","object":"chat.completion.chunk","created":1,"model":"m",' + '"choices":[{"index":0,"delta":{"role":"assistant","content":"He"}}]}' ) - assert result is mock_response - client.openai.embeddings.create.assert_called_once_with( - model="openai:text-embedding-3-small", - input="hello", + chunk2 = ( + '{"id":"c","object":"chat.completion.chunk","created":1,"model":"m",' + '"choices":[{"index":0,"delta":{"content":"llo"}}]}' ) - - def test_response_delegates(self, client: OtariClient) -> None: - mock_response = MagicMock() - client.openai.responses.create = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.response( - model="openai:gpt-4o-mini", - input="hello", + route = respx.post("http://localhost:8000/v1/chat/completions").mock( + return_value=httpx.Response( + 200, + headers={"content-type": "text/event-stream"}, + content=_sse(chunk1, chunk2), + ) ) - assert result is mock_response - - def test_list_models_delegates(self, client: OtariClient) -> None: - mock_models = [ - MagicMock(id="model-1"), - MagicMock(id="model-2"), - ] - - mock_page = MagicMock() - mock_page.__iter__.return_value = iter(mock_models) - client.openai.models.list = MagicMock(return_value=mock_page) # type: ignore[method-assign] - - result = client.list_models() - assert result == mock_models - - def test_error_mapping_on_embedding(self, client: OtariClient) -> None: - client.openai.embeddings.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(401, "Unauthorized"), + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + stream = client.completion( + model="m", messages=[{"role": "user", "content": "Hi"}], stream=True ) - with pytest.raises(AuthenticationError): - client.embedding(model="openai:text-embedding-3-small", input="hello") + chunks = list(stream) + assert all(isinstance(c, ChatCompletionChunk) for c in chunks) + assert [c.choices[0].delta.content for c in chunks] == ["He", "llo"] + # The streaming request set the SSE Accept + auth header and stream flag. + request = route.calls.last.request + assert request.headers["accept"] == "text/event-stream" + assert request.headers["otari-key"] == "Bearer vk" - def test_error_mapping_on_response(self, client: OtariClient) -> None: - client.openai.responses.create = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(429, "Rate limited"), + @respx.mock + def test_streaming_error_maps_to_typed_error(self) -> None: + respx.post("http://localhost:8000/v1/chat/completions").mock( + return_value=httpx.Response(429, json={"detail": "rate limited"}) ) + client = OtariClient(api_base="http://localhost:8000", api_key="vk") with pytest.raises(RateLimitError): - client.response(model="openai:gpt-4o-mini", input="hello") - - def test_error_mapping_on_list_models(self, client: OtariClient) -> None: - client.openai.models.list = MagicMock( # type: ignore[method-assign] - side_effect=_make_api_error(502, "Bad Gateway"), - ) - with pytest.raises(UpstreamProviderError): - client.list_models() - - -# --------------------------------------------------------------------------- -# Batch operations -# --------------------------------------------------------------------------- - - -class TestBatchOperations: - @pytest.fixture - def client(self) -> OtariClient: - return OtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - def test_create_batch(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"id": "batch-123", "status": "created", "provider": "openai"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [{"custom_id": "r1", "body": {"messages": []}}], - }) - assert result["id"] == "batch-123" - - def test_retrieve_batch(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"id": "batch-123", "status": "completed"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.retrieve_batch("batch-123", "openai") - assert result["status"] == "completed" - - def test_cancel_batch(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"id": "batch-123", "status": "cancelled"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.cancel_batch("batch-123", "openai") - assert result["status"] == "cancelled" - - def test_list_batches(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 200, - json={"data": [{"id": "b1"}, {"id": "b2"}]}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.list_batches("openai") - assert len(result) == 2 - - def test_retrieve_batch_results(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 200, - json={ - "results": [ - {"custom_id": "r1", "result": {"id": "cmpl-1", "choices": []}}, - {"custom_id": "r2", "error": {"code": "err", "message": "failed"}}, - ] - }, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - result = client.retrieve_batch_results("batch-123", "openai") - assert len(result.results) == 2 - assert result.results[0].custom_id == "r1" - assert result.results[1].error is not None - - -class TestBatchErrorHandling: - @pytest.fixture - def client(self) -> OtariClient: - return OtariClient( - api_base="http://localhost:8000", - platform_token="tk_test", # noqa: S106 - ) - - def test_409_maps_to_batch_not_complete(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 409, - json={"detail": "Batch 'batch-123' is not complete (status: in_progress)"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(BatchNotCompleteError) as exc_info: - client.retrieve_batch_results("batch-123", "openai") - assert exc_info.value.batch_id == "batch-123" - assert exc_info.value.batch_status == "in_progress" - - def test_404_suggests_upgrade(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 404, - json={"detail": "Not supported"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(OtariError, match="Upgrade your gateway"): - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - def test_404_passes_through_not_found(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 404, - json={"detail": "Batch not found"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(OtariError, match="not found"): - client.retrieve_batch("batch-xyz", "openai") - - def test_401_maps_to_authentication_error(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 401, - json={"detail": "Invalid key"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(AuthenticationError): - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - def test_429_maps_to_rate_limit(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 429, - headers={"retry-after": "30"}, - json={"detail": "Rate limited"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(RateLimitError) as exc_info: - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - assert exc_info.value.retry_after == "30" + list( + client.completion( + model="m", messages=[{"role": "user", "content": "Hi"}], stream=True + ) + ) - def test_502_maps_to_upstream_error(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 502, - json={"detail": "Bad Gateway"}, - ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(UpstreamProviderError): - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - def test_504_maps_to_gateway_timeout(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 504, - json={"detail": "Gateway Timeout"}, + @respx.mock + def test_platform_mode_streaming_sends_bearer(self) -> None: + chunk = ( + '{"id":"c","object":"chat.completion.chunk","created":1,"model":"m",' + '"choices":[{"index":0,"delta":{"content":"x"}}]}' ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(GatewayTimeoutError): - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - def test_correlation_id_in_batch_error(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 401, - headers={"x-correlation-id": "corr-456"}, - json={"detail": "Invalid key"}, + route = respx.post("http://localhost:8000/v1/chat/completions").mock( + return_value=httpx.Response( + 200, headers={"content-type": "text/event-stream"}, content=_sse(chunk) + ) ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(AuthenticationError, match="correlation_id=corr-456"): - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - - def test_unknown_status_maps_to_otari_error(self, client: OtariClient) -> None: - mock_response = httpx.Response( - 418, - json={"detail": "I'm a teapot"}, + client = OtariClient(api_base="http://localhost:8000", platform_token="tk") # noqa: S106 + list( + client.completion( + model="m", messages=[{"role": "user", "content": "Hi"}], stream=True + ) ) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - with pytest.raises(OtariError): - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) + assert route.calls.last.request.headers["authorization"] == "Bearer tk" # --------------------------------------------------------------------------- -# Batch auth modes +# Control-plane accessor # --------------------------------------------------------------------------- -class TestBatchAuthModes: - def test_non_platform_sends_otari_key(self) -> None: - client = OtariClient(api_base="http://localhost:8000", api_key="my-key") - mock_response = httpx.Response(200, json={"id": "b1", "provider": "openai"}) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - call_kwargs = client._http.request.call_args - headers = call_kwargs.kwargs.get("headers") or call_kwargs[1].get("headers", {}) - assert headers.get("Otari-Key") == "Bearer my-key" - assert "Authorization" not in headers - - def test_platform_sends_authorization(self) -> None: - client = OtariClient(api_base="http://localhost:8000", platform_token="tk_123") # noqa: S106 - mock_response = httpx.Response(200, json={"id": "b1", "provider": "openai"}) - client._http.request = MagicMock(return_value=mock_response) # type: ignore[method-assign] - - client.create_batch({ - "model": "openai:gpt-4o-mini", - "requests": [], - }) - call_kwargs = client._http.request.call_args - headers = call_kwargs.kwargs.get("headers") or call_kwargs[1].get("headers", {}) - assert headers.get("Authorization") == "Bearer tk_123" - assert "Otari-Key" not in headers - - -# --------------------------------------------------------------------------- -# Context manager -# --------------------------------------------------------------------------- - +class TestControlPlane: + def test_requires_admin_credential(self) -> None: + client = OtariClient(api_base="http://localhost:8000", api_key="vk") + with pytest.raises(OtariError, match="admin credential"): + _ = client.control_plane -class TestContextManager: - def test_context_manager(self) -> None: - with OtariClient(api_base="http://localhost:8000") as client: - assert client.platform_mode is False + def test_available_with_admin_key(self) -> None: + client = OtariClient(api_base="http://localhost:8000", admin_key="master") + cp = client.control_plane + assert cp.keys is not None + assert cp._api_client.default_headers["Authorization"] == "Bearer master" + cp.close() From ba39fa2783f8e0efecfccb0ab618e93660f10026 Mon Sep 17 00:00:00 2001 From: njbrake Date: Sat, 6 Jun 2026 17:01:29 +0000 Subject: [PATCH 6/6] Add endpoint-coverage drift gate Fail CI when the gateway OpenAPI spec exposes an endpoint the SDK's public API does not account for. A checked-in manifest (sdk-endpoints.txt) pins the covered and intentionally-excluded endpoint sets; a pytest test fetches the canonical spec and asserts spec is a subset of (covered + excluded), naming any unaccounted endpoint. Wired as a dedicated CI step. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 6 ++ sdk-endpoints.txt | 61 ++++++++++++++++ tests/unit/test_endpoint_coverage.py | 103 +++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 sdk-endpoints.txt create mode 100644 tests/unit/test_endpoint_coverage.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fca696c..9ea3a45 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,3 +35,9 @@ jobs: - name: Test # Integration tests skip automatically when no gateway is on PATH. run: uv run pytest + + - name: Endpoint-coverage drift gate + # Fetches the canonical gateway OpenAPI spec and fails if it exposes an + # endpoint absent from sdk-endpoints.txt ([covered] or [excluded]). + # Network is available in CI, so this must not skip here. + run: uv run pytest tests/unit/test_endpoint_coverage.py -v diff --git a/sdk-endpoints.txt b/sdk-endpoints.txt new file mode 100644 index 0000000..9da2578 --- /dev/null +++ b/sdk-endpoints.txt @@ -0,0 +1,61 @@ +# Endpoint-coverage drift manifest for the otari gateway. +# +# This file pins which gateway OpenAPI endpoints this SDK's PUBLIC API accounts +# for. CI fetches the canonical spec +# https://raw.githubusercontent.com/mozilla-ai/otari/main/docs/public/openapi.json +# computes its set of "METHOD path" pairs (excluding /health* meta routes), and +# asserts that set is a subset of (covered + excluded). A new gateway endpoint +# in neither section FAILS the build: add a wrapper and list it under [covered], +# or deliberately defer it under [excluded] with a one-word reason. +# +# All four otari SDKs (python/ts/go/rust) keep this list identical: they target +# the same gateway. Lines are "METHOD /path"; blank lines and # comments ignore. + +[covered] +# Inference +POST /v1/chat/completions +POST /v1/responses +POST /v1/messages +POST /v1/embeddings +POST /v1/moderations +POST /v1/rerank +GET /v1/models +# Batches +POST /v1/batches +GET /v1/batches +GET /v1/batches/{batch_id} +POST /v1/batches/{batch_id}/cancel +GET /v1/batches/{batch_id}/results +# Control plane: keys +POST /v1/keys +GET /v1/keys +GET /v1/keys/{key_id} +PATCH /v1/keys/{key_id} +DELETE /v1/keys/{key_id} +# Control plane: users +POST /v1/users +GET /v1/users +GET /v1/users/{user_id} +PATCH /v1/users/{user_id} +DELETE /v1/users/{user_id} +GET /v1/users/{user_id}/usage +# Control plane: budgets +POST /v1/budgets +GET /v1/budgets +GET /v1/budgets/{budget_id} +PATCH /v1/budgets/{budget_id} +DELETE /v1/budgets/{budget_id} +# Control plane: pricing +POST /v1/pricing +GET /v1/pricing +GET /v1/pricing/{model_key} +GET /v1/pricing/{model_key}/history +DELETE /v1/pricing/{model_key} +# Control plane: usage +GET /v1/usage + +[excluded] +POST /v1/audio/speech # binary, not yet wrapped +POST /v1/audio/transcriptions # binary, not yet wrapped +POST /v1/images/generations # binary, not yet wrapped +GET /v1/models/{model_id} # redundant, list_models covers discovery diff --git a/tests/unit/test_endpoint_coverage.py b/tests/unit/test_endpoint_coverage.py new file mode 100644 index 0000000..42866ad --- /dev/null +++ b/tests/unit/test_endpoint_coverage.py @@ -0,0 +1,103 @@ +"""Endpoint-coverage drift gate. + +Fetches the canonical otari gateway OpenAPI spec and asserts that every API +endpoint it exposes is accounted for in ``sdk-endpoints.txt`` -- either wrapped +by this SDK's public surface (``[covered]``) or deliberately deferred +(``[excluded]``). A new gateway endpoint in neither section fails this test, +so a future endpoint (as ``/messages`` once was) cannot silently go unsurfaced. + +The fetch uses :mod:`urllib.request` (stdlib) so the test runs in the normal +suite. It is skipped offline (network error / ``OTARI_SKIP_NETWORK_TESTS=1``) +but runs in CI, where the network is available. +""" + +from __future__ import annotations + +import json +import os +import urllib.error +import urllib.request +from pathlib import Path + +import pytest + +SPEC_URL = "https://raw.githubusercontent.com/mozilla-ai/otari/main/docs/public/openapi.json" +MANIFEST = Path(__file__).resolve().parents[2] / "sdk-endpoints.txt" +HTTP_METHODS = {"get", "post", "put", "patch", "delete"} + + +def parse_manifest(text: str) -> tuple[set[str], set[str]]: + """Return (covered, excluded) endpoint sets from manifest text. + + Format: ``[covered]`` / ``[excluded]`` sections; each entry is + ``METHOD /path`` with an optional ``# reason`` trailer; ``#`` lines and + blank lines are ignored. + """ + covered: set[str] = set() + excluded: set[str] = set() + section: set[str] | None = None + for raw in text.splitlines(): + line = raw.strip() + if not line or line.startswith("#"): + continue + if line == "[covered]": + section = covered + continue + if line == "[excluded]": + section = excluded + continue + entry = line.split("#", 1)[0].strip() + if not entry or section is None: + continue + method, path = entry.split(None, 1) + section.add(f"{method.upper()} {path.strip()}") + return covered, excluded + + +def spec_endpoints(spec: dict) -> set[str]: + """Extract ``METHOD /path`` pairs from an OpenAPI doc, dropping meta routes.""" + eps: set[str] = set() + for path, methods in spec.get("paths", {}).items(): + if path == "/health" or path.startswith("/health/"): + continue + for method in methods: + if method.lower() in HTTP_METHODS: + eps.add(f"{method.upper()} {path}") + return eps + + +def fetch_spec() -> dict: + if os.environ.get("OTARI_SKIP_NETWORK_TESTS") == "1": + pytest.skip("OTARI_SKIP_NETWORK_TESTS=1") + try: + with urllib.request.urlopen(SPEC_URL, timeout=30) as resp: # noqa: S310 + return json.loads(resp.read()) + except (urllib.error.URLError, TimeoutError) as exc: + pytest.skip(f"could not fetch otari OpenAPI spec from {SPEC_URL}: {exc}") + + +def test_manifest_parses() -> None: + covered, excluded = parse_manifest(MANIFEST.read_text()) + assert covered, "manifest [covered] section is empty" + assert not (covered & excluded), f"endpoints in both sections: {sorted(covered & excluded)}" + + +def test_spec_endpoints_are_accounted_for() -> None: + covered, excluded = parse_manifest(MANIFEST.read_text()) + spec = spec_endpoints(fetch_spec()) + accounted = covered | excluded + unaccounted = sorted(spec - accounted) + assert not unaccounted, ( + "Gateway OpenAPI exposes endpoint(s) the SDK does not account for: " + f"{unaccounted}. Add a public wrapper and list under [covered], or " + "defer it under [excluded] with a reason, in sdk-endpoints.txt." + ) + + +def test_manifest_has_no_stale_entries() -> None: + """Warn (not fail) if a manifest entry no longer exists in the spec.""" + covered, excluded = parse_manifest(MANIFEST.read_text()) + spec = spec_endpoints(fetch_spec()) + stale = sorted((covered | excluded) - spec) + if stale: + pytest.skip(f"manifest entries not present in current spec (review): {stale}")