diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0054954
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+# Generated by Scalar SDK Generator.
+__pycache__/
+*.py[cod]
+*.egg-info/
+.venv/
+dist/
+build/
+.mypy_cache/
+.pytest_cache/
+.ruff_cache/
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..b2f6c56
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changelog
+
+## 0.1.9
+
+- Initial generated SDK release.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a121855
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,3 @@
+SPDX-License-Identifier: MIT
+
+See the project repository for the full license text.
diff --git a/README.md b/README.md
index d6af3b4..977fae0 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,226 @@
-# scalar-python
\ No newline at end of file
+# Scalar API
+
+Generated Python SDK for Scalar API.
+API for managing Scalar platform resources.
+
+## TypeScript SDK
+
+For TypeScript, we provide a SDK that makes using our API even easier.
+
+### Install
+
+```bash
+npm add @scalar/sdk
+```
+
+### Get a Scalar API key
+
+Create an API key in your Scalar account:
+
+- Dashboard: https://dashboard.scalar.com/account
+- Store it in `.env`, for example:
+
+```bash
+SCALAR_API_KEY=your_personal_token
+```
+
+### Exchange your API key for an access token
+
+The personal token is not an access token. Exchange it first with `postv1AuthExchange`.
+
+If you use the personal token directly for authenticated API calls, the API returns `401 Invalid authentication token`.
+
+```ts
+import { Scalar } from '@scalar/sdk'
+
+const scalar = new Scalar()
+
+const exchange = await scalar.auth.postv1AuthExchange({
+ personalToken: process.env.SCALAR_API_KEY!,
+})
+
+const accessToken = exchange.accessToken
+```
+
+### Use the access token
+
+Construct a second client with bearer auth. Use this authenticated client for API calls.
+
+```ts
+import { Scalar } from '@scalar/sdk'
+
+const scalar = new Scalar()
+
+const exchange = await scalar.auth.postv1AuthExchange({
+ personalToken: process.env.SCALAR_API_KEY!,
+})
+
+const authedScalar = new Scalar({
+ bearerAuth: exchange.accessToken,
+})
+```
+
+### Notes
+
+- The exchange request itself can be made from a client constructed with no arguments (`new Scalar()`).
+- The exchanged access token is valid for 12 hours.
+- Timestamps are Unix seconds.
+
+### Read more
+
+- [@scalar/sdk on npm](https://www.npmjs.com/package/@scalar/sdk)
+
+
+
+## Contents
+
+- [Installation](#installation)
+- [Usage](#usage)
+- [API Reference](./api.md)
+- [Async](#async)
+- [Authentication](#authentication)
+- [Errors](#errors)
+- [Client Options](#client-options)
+- [Retries and Timeouts](#retries-and-timeouts)
+- [Helpers](#helpers)
+- [Logging](#logging)
+- [Requirements](#requirements)
+
+
+
+## Installation
+
+```sh
+pip install scalarApi
+```
+
+
+
+## Usage
+
+```python
+import os
+
+from scalar_api import ScalarApi
+
+client = ScalarApi(
+ bearer_auth=os.environ.get("BEARER_AUTH"),
+)
+
+registry = client.registry.list_all_api_documents()
+print(registry)
+```
+
+The examples in the following sections assume a `client` configured as shown above.
+
+See the [API reference](./api.md) for every available operation.
+
+
+
+## Async
+
+Every client has an `Async` counterpart (`AsyncScalarApi`) exposing the same resource tree with `await`.
+
+```python
+import asyncio
+
+from scalar_api import AsyncScalarApi
+
+async def main() -> None:
+ client = AsyncScalarApi()
+ registry = await client.registry.list_all_api_documents()
+
+asyncio.run(main())
+```
+
+
+
+## Authentication
+
+Pass credentials to the generated client constructor. Environment variables are read automatically when supported by the target runtime.
+
+| Option | Type | Default | Description |
+| --- | --- | --- | --- |
+| `bearer_auth` | `string \| provider` | - | Credential for the BearerAuth scheme. Defaults to BEARER_AUTH. |
+
+Declared schemes:
+
+- `BearerAuth` bearer token
+
+
+
+## Errors
+
+Non-success responses throw generated API errors. Error objects expose status, headers, response body, and request metadata where the target runtime supports it.
+
+```python
+from scalar_api import APIStatusError
+
+try:
+ registry = client.registry.list_all_api_documents()
+except APIStatusError as err:
+ print(err.status_code, err.message)
+ raise
+```
+
+Documented error statuses: `400`, `401`, `403`, `404`, `422`, `500`.
+
+
+
+## Client Options
+
+Configure the generated client by setting any of these options when you create it.
+
+```python
+from scalar_api import ScalarApi
+
+client = ScalarApi(
+ timeout=60.0,
+ max_retries=2,
+)
+```
+
+| Option | Type | Default | Description |
+| --- | --- | --- | --- |
+| `bearer_auth` | `str \| None` | `os.environ.get("BEARER_AUTH")` | Credential for the BearerAuth scheme. |
+| `base_url` | `str \| httpx.URL \| None` | - | Override the default API base URL. |
+| `timeout` | `float \| Timeout \| None` | `60.0` | Maximum time in seconds to wait for a response before aborting a request. |
+| `max_retries` | `int` | `2` | Number of retries for temporary failures. |
+| `default_headers` | `Mapping[str, str] \| None` | - | Headers sent with every request. |
+| `default_query` | `Mapping[str, object] \| None` | - | Query parameters sent with every request. |
+
+
+
+## Retries and Timeouts
+
+Generated clients support request timeouts and retry temporary failures such as network errors, 408, 409, 429, and 5xx responses. Retry delays honor `Retry-After` headers when present. Tune the retry and timeout client options shown above, or override them per request.
+
+
+
+## Helpers
+
+- Use `client.with_raw_response..(...)` to access the raw `httpx.Response` and parse it yourself.
+- Use `client.with_streaming_response..(...)` to stream a response body without buffering it.
+
+
+
+## Logging
+
+- Set the `SCALAR_LOG` environment variable to `info` or `debug` to enable HTTP logging.
+- Logs are emitted through the standard `logging` module under the `scalar_api` logger.
+
+
+
+## Requirements
+
+- Python 3.8 or newer
+
+Powered by Scalar.
+
+
+## Contributions
+
+This SDK is generated programmatically. Manual edits to generated files will be
+overwritten on the next build.
+
+### SDK created by [Scalar](https://www.scalar.com/?utm_source=scalar-typescript-sdk-python&utm_campaign=sdk)
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..22d4cea
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,3 @@
+# Security Policy
+
+Please report any vulnerabilities through the standard issue tracker.
diff --git a/api.md b/api.md
new file mode 100644
index 0000000..397a3cc
--- /dev/null
+++ b/api.md
@@ -0,0 +1,837 @@
+# Scalar Python API
+
+Complete reference of every operation, grouped by resource. See [the README](./README.md) for usage and configuration.
+
+## Contents
+
+- [`Registry`](#registry)
+ - [List all API Documents](#list-all-api-documents)
+ - [List API Documents in a namespace](#list-api-documents-in-a-namespace)
+ - [Create API Document](#create-api-document)
+ - [Update API Document metadata](#update-api-document-metadata)
+ - [Delete API Document](#delete-api-document)
+ - [Get API Document](#get-api-document)
+ - [Update API Document version](#update-api-document-version)
+ - [Delete API Document version](#delete-api-document-version)
+ - [Get API Document version metadata](#get-api-document-version-metadata)
+ - [Create API Document version](#create-api-document-version)
+ - [Add access group](#add-access-group)
+ - [Remove access group](#remove-access-group)
+- [`Schemas`](#schemas)
+ - [List all shared components](#list-all-shared-components)
+ - [Create a shared component](#create-a-shared-component)
+ - [Update shared component metadata](#update-shared-component-metadata)
+ - [Delete a shared component](#delete-a-shared-component)
+ - [`Schemas Version`](#schemas-version)
+ - [Get a shared component document](#get-a-shared-component-document)
+ - [Delete a shared component version](#delete-a-shared-component-version)
+ - [Create a shared component version](#create-a-shared-component-version)
+ - [`Schemas AccessGroup`](#schemas-accessgroup)
+ - [Add shared component access group](#add-shared-component-access-group)
+ - [Remove shared component access group](#remove-shared-component-access-group)
+- [`LoginPortals`](#loginportals)
+ - [Get a login portal](#get-a-login-portal)
+ - [Update portal metadata](#update-portal-metadata)
+ - [Delete a login portal](#delete-a-login-portal)
+ - [Create a portal](#create-a-portal)
+ - [List all portals](#list-all-portals)
+- [`Rules`](#rules)
+ - [List all rules](#list-all-rules)
+ - [Create a rule](#create-a-rule)
+ - [Update rule metadata](#update-rule-metadata)
+ - [Delete a rule](#delete-a-rule)
+ - [Get a rule](#get-a-rule)
+ - [Add rule access group](#add-rule-access-group)
+ - [Remove rule access group](#remove-rule-access-group)
+- [`Themes`](#themes)
+ - [List all themes](#list-all-themes)
+ - [Create a theme](#create-a-theme)
+ - [Update theme metadata](#update-theme-metadata)
+ - [Update theme document](#update-theme-document)
+ - [Delete a theme](#delete-a-theme)
+ - [Get a theme](#get-a-theme)
+- [`Teams`](#teams)
+ - [List teams](#list-teams)
+- [`ScalarDocs`](#scalardocs)
+ - [List all projects](#list-all-projects)
+ - [Create a project](#create-a-project)
+ - [Publish a project](#publish-a-project)
+- [`Namespaces`](#namespaces)
+ - [List namespaces](#list-namespaces)
+- [`Authentication`](#authentication)
+ - [Exchange token](#exchange-token)
+ - [Get current user](#get-current-user)
+
+## Setup
+
+```python
+import os
+
+from scalar_api import ScalarApi
+
+client = ScalarApi(
+ bearer_auth=os.environ.get("BEARER_AUTH"),
+)
+```
+
+## `Registry`
+
+### List all API Documents
+
+List all API documents across every namespace the caller can access.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RegistryListAllApiDocumentsResponse`](./src/types/registry_list_all_api_documents_response.py) |
+
+```python
+registry = client.registry.list_all_api_documents()
+```
+
+### List API Documents in a namespace
+
+List API documents in a namespace.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RegistryListApiDocumentsResponse`](./src/types/registry_list_api_documents_response.py) |
+
+```python
+registry = client.registry.list_api_documents(
+ namespace="namespace",
+)
+```
+
+### Create API Document
+
+Create an API document.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RegistryCreateApiDocumentParams`](./src/types/registry_create_api_document_params.py) |
+| Response | [`RegistryCreateApiDocumentResponse`](./src/types/registry_create_api_document_response.py) |
+
+```python
+registry = client.registry.create_api_document(
+ namespace="namespace",
+ title="",
+ version="",
+ slug="",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Update API Document metadata
+
+Update metadata for an API document.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RegistryUpdateApiDocumentParams`](./src/types/registry_update_api_document_params.py) |
+| Response | [`RegistryUpdateApiDocumentResponse`](./src/types/registry_update_api_document_response.py) |
+
+```python
+registry = client.registry.update_api_document(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Delete API Document
+
+Delete an API document and all versions.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RegistryDeleteApiDocumentResponse`](./src/types/registry_delete_api_document_response.py) |
+
+```python
+registry = client.registry.delete_api_document(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Get API Document
+
+Get a specific API document version.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RegistryRetrieveApiDocumentVersionResponse`](./src/types/registry_retrieve_api_document_version_response.py) |
+
+```python
+registry = client.registry.retrieve_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+)
+```
+
+### Update API Document version
+
+Update the registry file content for an API document version.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RegistryUpdateApiDocumentVersionParams`](./src/types/registry_update_api_document_version_params.py) |
+| Response | [`RegistryUpdateApiDocumentVersionResponse`](./src/types/registry_update_api_document_version_response.py) |
+
+```python
+registry = client.registry.update_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Delete API Document version
+
+Delete a specific API document version.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RegistryDeleteApiDocumentVersionResponse`](./src/types/registry_delete_api_document_version_response.py) |
+
+```python
+registry = client.registry.delete_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ idempotency_key="",
+)
+```
+
+### Get API Document version metadata
+
+Get metadata (uid, content shas, version sha, tags) for a specific API document version.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RegistryListApiDocumentVersionMetadataResponse`](./src/types/registry_list_api_document_version_metadata_response.py) |
+
+```python
+registry = client.registry.list_api_document_version_metadata(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+)
+```
+
+### Create API Document version
+
+Create a new API document version.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RegistryCreateApiDocumentVersionParams`](./src/types/registry_create_api_document_version_params.py) |
+| Response | [`RegistryCreateApiDocumentVersionResponse`](./src/types/registry_create_api_document_version_response.py) |
+
+```python
+registry = client.registry.create_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ version="",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Add access group
+
+Add an access group to an API document.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RegistryCreateApiDocumentAccessGroupParams`](./src/types/registry_create_api_document_access_group_params.py) |
+| Response | [`RegistryCreateApiDocumentAccessGroupResponse`](./src/types/registry_create_api_document_access_group_response.py) |
+
+```python
+registry = client.registry.create_api_document_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+)
+```
+
+### Remove access group
+
+Remove an access group from an API document.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RegistryDeleteApiDocumentAccessGroupParams`](./src/types/registry_delete_api_document_access_group_params.py) |
+| Response | [`RegistryDeleteApiDocumentAccessGroupResponse`](./src/types/registry_delete_api_document_access_group_response.py) |
+
+```python
+registry = client.registry.delete_api_document_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+)
+```
+
+## `Schemas`
+
+### List all shared components
+
+List schemas in a namespace.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`SchemaListResponse`](./src/types/schema_list_response.py) |
+
+```python
+schema = client.schemas.list(
+ namespace="namespace",
+)
+```
+
+### Create a shared component
+
+Create a schema in a namespace.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`SchemaCreateParams`](./src/types/schema_create_params.py) |
+| Response | [`SchemaCreateResponse`](./src/types/schema_create_response.py) |
+
+```python
+schema = client.schemas.create(
+ namespace="namespace",
+ title="",
+ version="",
+ slug="",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Update shared component metadata
+
+Update schema metadata.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`SchemaUpdateParams`](./src/types/schema_update_params.py) |
+| Response | [`SchemaUpdateResponse`](./src/types/schema_update_response.py) |
+
+```python
+schema = client.schemas.update(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Delete a shared component
+
+Delete a schema and all related versions.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`SchemaDeleteResponse`](./src/types/schema_delete_response.py) |
+
+```python
+schema = client.schemas.delete(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### `Schemas Version`
+
+#### Get a shared component document
+
+Get a specific schema version document.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`VersionRetrieveSchemaResponse`](./src/types/schemas/version_retrieve_schema_response.py) |
+
+```python
+version = client.schemas.version.retrieve_schema(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+)
+```
+
+#### Delete a shared component version
+
+Delete a schema version.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`VersionDeleteSchemaResponse`](./src/types/schemas/version_delete_schema_response.py) |
+
+```python
+version = client.schemas.version.delete_schema(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ idempotency_key="",
+)
+```
+
+#### Create a shared component version
+
+Create a schema version.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`VersionCreateSchemaParams`](./src/types/schemas/version_create_schema_params.py) |
+| Response | [`VersionCreateSchemaResponse`](./src/types/schemas/version_create_schema_response.py) |
+
+```python
+version = client.schemas.version.create_schema(
+ namespace="namespace",
+ slug="slug",
+ version="",
+ document="",
+ idempotency_key="",
+)
+```
+
+### `Schemas AccessGroup`
+
+#### Add shared component access group
+
+Add an access group to a schema.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`AccessGroupCreateSchemaParams`](./src/types/schemas/access_group_create_schema_params.py) |
+| Response | [`AccessGroupCreateSchemaResponse`](./src/types/schemas/access_group_create_schema_response.py) |
+
+```python
+access_group = client.schemas.access_group.create_schema(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+)
+```
+
+#### Remove shared component access group
+
+Remove an access group from a schema.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`AccessGroupDeleteSchemaParams`](./src/types/schemas/access_group_delete_schema_params.py) |
+| Response | [`AccessGroupDeleteSchemaResponse`](./src/types/schemas/access_group_delete_schema_response.py) |
+
+```python
+access_group = client.schemas.access_group.delete_schema(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+)
+```
+
+## `LoginPortals`
+
+### Get a login portal
+
+Get a login portal by slug.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`LoginPortalRetrieveResponse`](./src/types/login_portal_retrieve_response.py) |
+
+```python
+login_portal = client.login_portals.retrieve(
+ slug="slug",
+)
+```
+
+### Update portal metadata
+
+Update metadata for a login portal.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`LoginPortalUpdateParams`](./src/types/login_portal_update_params.py) |
+| Response | [`LoginPortalUpdateResponse`](./src/types/login_portal_update_response.py) |
+
+```python
+login_portal = client.login_portals.update(
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Delete a login portal
+
+Delete a login portal.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`LoginPortalDeleteResponse`](./src/types/login_portal_delete_response.py) |
+
+```python
+login_portal = client.login_portals.delete(
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Create a portal
+
+Create a login portal for the current team.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`LoginPortalCreateParams`](./src/types/login_portal_create_params.py) |
+| Response | [`LoginPortalCreateResponse`](./src/types/login_portal_create_response.py) |
+
+```python
+login_portal = client.login_portals.create(
+ title="",
+ slug="",
+ email={"logo": "", "logo_size": "100", "button_text": "Login", "message": "Click to access private documentation hosted by scalar.com", "title": "Private Docs", "main_color": "#2a2f45", "main_background": "#f6f6f6", "card_color": "2a2f45", "card_background": "#fff", "button_color": "#fff", "button_background": "#0f0f0f"},
+ page={"title": "Scalar Private Docs", "description": "Login to access your documentation", "head": "", "script": "", "theme": "", "company_name": "", "logo": "", "logo_url": "", "favicon": "", "terms_link": "", "privacy_link": "", "form_title": "Scalar Private Docs", "form_description": "Login to access your documentation", "form_image": ""},
+ idempotency_key="",
+)
+```
+
+### List all portals
+
+List all login portals for the current team.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`LoginPortalListResponse`](./src/types/login_portal_list_response.py) |
+
+```python
+login_portal = client.login_portals.list()
+```
+
+## `Rules`
+
+### List all rules
+
+List all rulesets in a namespace.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RuleListRulesetsResponse`](./src/types/rule_list_rulesets_response.py) |
+
+```python
+rule = client.rules.list_rulesets(
+ namespace="namespace",
+)
+```
+
+### Create a rule
+
+Create a rule in a namespace.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RuleCreateRulesetParams`](./src/types/rule_create_ruleset_params.py) |
+| Response | [`RuleCreateRulesetResponse`](./src/types/rule_create_ruleset_response.py) |
+
+```python
+rule = client.rules.create_ruleset(
+ namespace="namespace",
+ title="",
+ slug="",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Update rule metadata
+
+Update rule metadata by slug.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RuleUpdateRulesetParams`](./src/types/rule_update_ruleset_params.py) |
+| Response | [`RuleUpdateRulesetResponse`](./src/types/rule_update_ruleset_response.py) |
+
+```python
+rule = client.rules.update_ruleset(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Delete a rule
+
+Delete a rule by slug.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RuleDeleteRulesetResponse`](./src/types/rule_delete_ruleset_response.py) |
+
+```python
+rule = client.rules.delete_ruleset(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Get a rule
+
+Get a rule document by slug.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`RuleRetrieveRulesetDocumentResponse`](./src/types/rule_retrieve_ruleset_document_response.py) |
+
+```python
+rule = client.rules.retrieve_ruleset_document(
+ namespace="namespace",
+ slug="slug",
+)
+```
+
+### Add rule access group
+
+Grant an access group to a rule.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RuleCreateRulesetAccessGroupParams`](./src/types/rule_create_ruleset_access_group_params.py) |
+| Response | [`RuleCreateRulesetAccessGroupResponse`](./src/types/rule_create_ruleset_access_group_response.py) |
+
+```python
+rule = client.rules.create_ruleset_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+)
+```
+
+### Remove rule access group
+
+Remove an access group from a rule.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`RuleDeleteRulesetAccessGroupParams`](./src/types/rule_delete_ruleset_access_group_params.py) |
+| Response | [`RuleDeleteRulesetAccessGroupResponse`](./src/types/rule_delete_ruleset_access_group_response.py) |
+
+```python
+rule = client.rules.delete_ruleset_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+)
+```
+
+## `Themes`
+
+### List all themes
+
+List all team themes.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`ThemeListResponse`](./src/types/theme_list_response.py) |
+
+```python
+theme = client.themes.list()
+```
+
+### Create a theme
+
+Create a team theme.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`ThemeCreateParams`](./src/types/theme_create_params.py) |
+| Response | [`ThemeCreateResponse`](./src/types/theme_create_response.py) |
+
+```python
+theme = client.themes.create(
+ name="",
+ slug="",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Update theme metadata
+
+Update theme metadata.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`ThemeUpdateParams`](./src/types/theme_update_params.py) |
+| Response | [`ThemeUpdateResponse`](./src/types/theme_update_response.py) |
+
+```python
+theme = client.themes.update(
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Update theme document
+
+Replace the theme document.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`ThemeReplaceDocumentParams`](./src/types/theme_replace_document_params.py) |
+| Response | [`ThemeReplaceDocumentResponse`](./src/types/theme_replace_document_response.py) |
+
+```python
+theme = client.themes.replace_document(
+ slug="slug",
+ document="",
+ idempotency_key="",
+)
+```
+
+### Delete a theme
+
+Delete a theme by slug.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`ThemeDeleteResponse`](./src/types/theme_delete_response.py) |
+
+```python
+theme = client.themes.delete(
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+### Get a theme
+
+Get the theme document by slug.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`ThemeRetrieveResponse`](./src/types/theme_retrieve_response.py) |
+
+```python
+theme = client.themes.retrieve(
+ slug="slug",
+)
+```
+
+## `Teams`
+
+### List teams
+
+List all available teams
+
+| Direction | Type |
+| --- | --- |
+| Response | [`TeamListResponse`](./src/types/team_list_response.py) |
+
+```python
+team = client.teams.list()
+```
+
+## `ScalarDocs`
+
+### List all projects
+
+List all guide projects.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`ScalarDocListGuidesResponse`](./src/types/scalar_doc_list_guides_response.py) |
+
+```python
+scalar_doc = client.scalar_docs.list_guides()
+```
+
+### Create a project
+
+Create a guide project.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`ScalarDocCreateGuideParams`](./src/types/scalar_doc_create_guide_params.py) |
+| Response | [`ScalarDocCreateGuideResponse`](./src/types/scalar_doc_create_guide_response.py) |
+
+```python
+scalar_doc = client.scalar_docs.create_guide(
+ name="",
+ is_private=False,
+ allowed_users=[],
+ allowed_domains=[],
+ idempotency_key="",
+)
+```
+
+### Publish a project
+
+Start a new publish process.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`ScalarDocPublishGuideResponse`](./src/types/scalar_doc_publish_guide_response.py) |
+
+```python
+scalar_doc = client.scalar_docs.publish_guide(
+ slug="slug",
+ idempotency_key="",
+)
+```
+
+## `Namespaces`
+
+### List namespaces
+
+Get all namespaces for the current team
+
+| Direction | Type |
+| --- | --- |
+| Response | [`NamespaceListResponse`](./src/types/namespace_list_response.py) |
+
+```python
+namespace = client.namespaces.list()
+```
+
+## `Authentication`
+
+### Exchange token
+
+Exchange an API key for an access token.
+
+| Direction | Type |
+| --- | --- |
+| Request | [`AuthenticationExchangePersonalTokenParams`](./src/types/authentication_exchange_personal_token_params.py) |
+| Response | [`AuthenticationExchangePersonalTokenResponse`](./src/types/authentication_exchange_personal_token_response.py) |
+
+```python
+authentication = client.authentication.exchange_personal_token(
+ personal_token="",
+ idempotency_key="",
+)
+```
+
+### Get current user
+
+Get the authenticated user, including their available teams and theme.
+
+| Direction | Type |
+| --- | --- |
+| Response | [`AuthenticationListCurrentUserResponse`](./src/types/authentication_list_current_user_response.py) |
+
+```python
+authentication = client.authentication.list_current_user()
+```
diff --git a/openapi.augmented.json b/openapi.augmented.json
new file mode 100644
index 0000000..2a73adf
--- /dev/null
+++ b/openapi.augmented.json
@@ -0,0 +1,7841 @@
+{
+ "openapi": "3.1.1",
+ "info": {
+ "title": "Scalar API",
+ "description": "API for managing Scalar platform resources.\n\n## TypeScript SDK\n\nFor TypeScript, we provide a SDK that makes using our API even easier.\n\n### Install\n\n```bash\nnpm add @scalar/sdk\n```\n\n### Get a Scalar API key\n\nCreate an API key in your Scalar account:\n\n- Dashboard: https://dashboard.scalar.com/account\n- Store it in `.env`, for example:\n\n```bash\nSCALAR_API_KEY=your_personal_token\n```\n\n### Exchange your API key for an access token\n\nThe personal token is not an access token. Exchange it first with `postv1AuthExchange`.\n\nIf you use the personal token directly for authenticated API calls, the API returns `401 Invalid authentication token`.\n\n```ts\nimport { Scalar } from '@scalar/sdk'\n\nconst scalar = new Scalar()\n\nconst exchange = await scalar.auth.postv1AuthExchange({\n personalToken: process.env.SCALAR_API_KEY!,\n})\n\nconst accessToken = exchange.accessToken\n```\n\n### Use the access token\n\nConstruct a second client with bearer auth. Use this authenticated client for API calls.\n\n```ts\nimport { Scalar } from '@scalar/sdk'\n\nconst scalar = new Scalar()\n\nconst exchange = await scalar.auth.postv1AuthExchange({\n personalToken: process.env.SCALAR_API_KEY!,\n})\n\nconst authedScalar = new Scalar({\n bearerAuth: exchange.accessToken,\n})\n```\n\n### Notes\n\n- The exchange request itself can be made from a client constructed with no arguments (`new Scalar()`).\n- The exchanged access token is valid for 12 hours.\n- Timestamps are Unix seconds.\n\n### Read more\n\n- [@scalar/sdk on npm](https://www.npmjs.com/package/@scalar/sdk)",
+ "version": "0.1.5",
+ "contact": {
+ "name": "Marc from Scalar",
+ "url": "https://scalar.com",
+ "email": "support@scalar.com"
+ },
+ "x-scalar-sdk-installation": [
+ {
+ "lang": "TypeScript",
+ "description": "```sh\nnpm install @scalar/sdk\n```"
+ },
+ {
+ "lang": "Python",
+ "description": "```sh\npip install scalarApi\n```"
+ },
+ {
+ "lang": "Go",
+ "description": "```sh\ngo get scalar-api\n```"
+ }
+ ]
+ },
+ "servers": [
+ {
+ "url": "https://access.scalar.com"
+ }
+ ],
+ "tags": [
+ {
+ "name": "Registry",
+ "description": "Registry"
+ },
+ {
+ "name": "Schemas",
+ "description": "Schemas"
+ },
+ {
+ "name": "Login Portals",
+ "description": "Login Portals"
+ },
+ {
+ "name": "Rules",
+ "description": "Rules"
+ },
+ {
+ "name": "Themes",
+ "description": "Themes"
+ },
+ {
+ "name": "Teams",
+ "description": "Teams"
+ },
+ {
+ "name": "Scalar Docs",
+ "description": "Scalar Docs"
+ },
+ {
+ "name": "Namespaces",
+ "description": "Namespaces"
+ },
+ {
+ "name": "Authentication",
+ "description": "Authentication"
+ }
+ ],
+ "components": {
+ "securitySchemes": {
+ "BearerAuth": {
+ "type": "http",
+ "scheme": "bearer",
+ "bearerFormat": "JWT"
+ }
+ },
+ "schemas": {
+ "400": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "401": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "403": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "404": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "422": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "500": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "api-document": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "default": "nanoid()",
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "version": {
+ "$ref": "#/components/schemas/version"
+ },
+ "title": {
+ "default": "",
+ "type": "string",
+ "maxLength": 100
+ },
+ "slug": {
+ "default": "randomManagedDocSlug()",
+ "$ref": "#/components/schemas/slug"
+ },
+ "description": {
+ "default": "",
+ "type": "string"
+ },
+ "namespace": {
+ "$ref": "#/components/schemas/namespace"
+ },
+ "isPrivate": {
+ "default": false,
+ "type": "boolean"
+ },
+ "tags": {
+ "default": []
+ },
+ "versions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/managed-doc-version"
+ }
+ }
+ },
+ "required": [
+ "uid",
+ "version",
+ "title",
+ "slug",
+ "description",
+ "namespace",
+ "isPrivate",
+ "tags",
+ "versions"
+ ],
+ "additionalProperties": false
+ },
+ "nanoid": {
+ "type": "string",
+ "minLength": 5
+ },
+ "version": {
+ "type": "string",
+ "minLength": 1
+ },
+ "slug": {
+ "type": "string",
+ "minLength": 3,
+ "maxLength": 60,
+ "pattern": "^[a-z](?:[a-z0-9-]*[a-z0-9])?$"
+ },
+ "namespace": {
+ "type": "string",
+ "minLength": 3,
+ "maxLength": 50,
+ "pattern": "^[a-zA-Z0-9-_]+$"
+ },
+ "managed-doc-version": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "createdAt": {
+ "type": "number"
+ },
+ "version": {
+ "$ref": "#/components/schemas/version"
+ },
+ "upgraded": {
+ "default": false,
+ "type": "boolean"
+ },
+ "embedStatus": {
+ "default": null,
+ "anyOf": [
+ {
+ "type": "string",
+ "enum": [
+ "complete",
+ "failed"
+ ]
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "tags": {
+ "default": [],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "method": {
+ "$ref": "#/components/schemas/method"
+ },
+ "enabledTools": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "execute-request",
+ "get-mini-openapi-spec"
+ ]
+ }
+ }
+ },
+ "required": [
+ "path",
+ "method",
+ "enabledTools"
+ ],
+ "additionalProperties": false
+ }
+ },
+ "yamlSha": {
+ "type": "string"
+ },
+ "jsonSha": {
+ "type": "string"
+ },
+ "versionSha": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "uid",
+ "createdAt",
+ "version",
+ "upgraded",
+ "embedStatus",
+ "tags"
+ ],
+ "additionalProperties": false
+ },
+ "method": {
+ "type": "string",
+ "enum": [
+ "delete",
+ "get",
+ "head",
+ "options",
+ "patch",
+ "post",
+ "put",
+ "trace"
+ ]
+ },
+ "access-group": {
+ "type": "object",
+ "properties": {
+ "accessGroupSlug": {
+ "$ref": "#/components/schemas/slug"
+ }
+ },
+ "required": [
+ "accessGroupSlug"
+ ],
+ "additionalProperties": false
+ },
+ "schema": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "default": "nanoid()",
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "title": {
+ "default": "",
+ "type": "string",
+ "maxLength": 100
+ },
+ "description": {
+ "default": "",
+ "type": "string"
+ },
+ "slug": {
+ "default": "randomManagedDocSlug()",
+ "$ref": "#/components/schemas/slug"
+ },
+ "namespace": {
+ "$ref": "#/components/schemas/namespace"
+ },
+ "isPrivate": {
+ "default": false,
+ "type": "boolean"
+ },
+ "versions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/managed-schema-version"
+ }
+ }
+ },
+ "required": [
+ "uid",
+ "title",
+ "description",
+ "slug",
+ "namespace",
+ "isPrivate",
+ "versions"
+ ],
+ "additionalProperties": false
+ },
+ "managed-schema-version": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "default": "nanoid()",
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "createdAt": {
+ "default": "unixTimestamp()",
+ "$ref": "#/components/schemas/timestamp"
+ },
+ "updatedAt": {
+ "default": "unixTimestamp()",
+ "$ref": "#/components/schemas/timestamp"
+ },
+ "version": {
+ "default": "0.0.1",
+ "$ref": "#/components/schemas/version"
+ }
+ },
+ "required": [
+ "uid",
+ "createdAt",
+ "updatedAt",
+ "version"
+ ],
+ "additionalProperties": false
+ },
+ "timestamp": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9007199254740991
+ },
+ "uid": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "$ref": "#/components/schemas/nanoid"
+ }
+ },
+ "required": [
+ "uid"
+ ],
+ "additionalProperties": false
+ },
+ "login-portal-email": {
+ "type": "object",
+ "properties": {
+ "logo": {
+ "default": "",
+ "type": "string"
+ },
+ "logoSize": {
+ "default": "100",
+ "type": "string"
+ },
+ "buttonText": {
+ "default": "Login",
+ "type": "string",
+ "maxLength": 50
+ },
+ "message": {
+ "default": "Click to access private documentation hosted by scalar.com",
+ "type": "string",
+ "maxLength": 1000
+ },
+ "title": {
+ "default": "Private Docs",
+ "type": "string",
+ "maxLength": 100
+ },
+ "mainColor": {
+ "default": "#2a2f45",
+ "type": "string",
+ "maxLength": 100
+ },
+ "mainBackground": {
+ "default": "#f6f6f6",
+ "type": "string",
+ "maxLength": 100
+ },
+ "cardColor": {
+ "default": "2a2f45",
+ "type": "string",
+ "maxLength": 100
+ },
+ "cardBackground": {
+ "default": "#fff",
+ "type": "string",
+ "maxLength": 100
+ },
+ "buttonColor": {
+ "default": "#fff",
+ "type": "string",
+ "maxLength": 100
+ },
+ "buttonBackground": {
+ "default": "#0f0f0f",
+ "type": "string",
+ "maxLength": 100
+ }
+ },
+ "required": [
+ "logo",
+ "logoSize",
+ "buttonText",
+ "message",
+ "title",
+ "mainColor",
+ "mainBackground",
+ "cardColor",
+ "cardBackground",
+ "buttonColor",
+ "buttonBackground"
+ ],
+ "additionalProperties": false
+ },
+ "login-portal-page": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "default": "Scalar Private Docs",
+ "type": "string",
+ "maxLength": 100
+ },
+ "description": {
+ "default": "Login to access your documentation",
+ "type": "string",
+ "maxLength": 500
+ },
+ "head": {
+ "default": "",
+ "type": "string"
+ },
+ "script": {
+ "default": "",
+ "type": "string"
+ },
+ "theme": {
+ "default": "",
+ "type": "string"
+ },
+ "companyName": {
+ "default": "",
+ "type": "string",
+ "maxLength": 100
+ },
+ "logo": {
+ "default": "",
+ "type": "string"
+ },
+ "logoURL": {
+ "default": "",
+ "type": "string"
+ },
+ "favicon": {
+ "default": "",
+ "type": "string"
+ },
+ "termsLink": {
+ "default": "",
+ "type": "string"
+ },
+ "privacyLink": {
+ "default": "",
+ "type": "string"
+ },
+ "formTitle": {
+ "default": "Scalar Private Docs",
+ "type": "string",
+ "maxLength": 100
+ },
+ "formDescription": {
+ "default": "Login to access your documentation",
+ "type": "string",
+ "maxLength": 500
+ },
+ "formImage": {
+ "default": "",
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "description",
+ "head",
+ "script",
+ "theme",
+ "companyName",
+ "logo",
+ "logoURL",
+ "favicon",
+ "termsLink",
+ "privacyLink",
+ "formTitle",
+ "formDescription",
+ "formImage"
+ ],
+ "additionalProperties": false
+ },
+ "login-portal": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "title": {
+ "type": "string",
+ "maxLength": 200
+ },
+ "slug": {
+ "$ref": "#/components/schemas/slug"
+ }
+ },
+ "required": [
+ "uid",
+ "title",
+ "slug"
+ ],
+ "additionalProperties": false
+ },
+ "rule": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "default": "nanoid()",
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "title": {
+ "default": "",
+ "type": "string",
+ "maxLength": 100
+ },
+ "description": {
+ "default": "",
+ "type": "string"
+ },
+ "slug": {
+ "default": "randomManagedDocSlug()",
+ "$ref": "#/components/schemas/slug"
+ },
+ "namespace": {
+ "$ref": "#/components/schemas/namespace"
+ },
+ "isPrivate": {
+ "default": false,
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "uid",
+ "title",
+ "description",
+ "slug",
+ "namespace",
+ "isPrivate"
+ ],
+ "additionalProperties": false
+ },
+ "theme": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "slug": {
+ "$ref": "#/components/schemas/slug"
+ }
+ },
+ "required": [
+ "uid",
+ "name",
+ "description",
+ "slug"
+ ],
+ "additionalProperties": false
+ },
+ "team": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "name": {
+ "$ref": "#/components/schemas/team-name"
+ },
+ "imageUri": {
+ "$ref": "#/components/schemas/team-image"
+ },
+ "slug": {
+ "$ref": "#/components/schemas/slug"
+ },
+ "theme": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "uid",
+ "name",
+ "slug",
+ "theme"
+ ],
+ "additionalProperties": false
+ },
+ "team-name": {
+ "type": "string"
+ },
+ "team-image": {
+ "type": "string"
+ },
+ "github-project": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "default": "nanoid()",
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "createdAt": {
+ "default": "unixTimestamp()",
+ "$ref": "#/components/schemas/timestamp"
+ },
+ "updatedAt": {
+ "default": "unixTimestamp()",
+ "$ref": "#/components/schemas/timestamp"
+ },
+ "name": {
+ "type": "string"
+ },
+ "activeDeployment": {
+ "default": null,
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/active-deployment"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "lastPublished": {
+ "default": null,
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/timestamp"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "lastPublishedUid": {
+ "default": null,
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "loginPortalUid": {
+ "default": "",
+ "type": "string"
+ },
+ "activeThemeId": {
+ "default": "",
+ "type": "string"
+ },
+ "typesenseId": {
+ "type": "number"
+ },
+ "isPrivate": {
+ "default": false,
+ "type": "boolean"
+ },
+ "agentEnabled": {
+ "default": false,
+ "type": "boolean"
+ },
+ "accessGroups": {
+ "default": []
+ },
+ "slug": {
+ "$ref": "#/components/schemas/slug"
+ },
+ "publishStatus": {
+ "default": "",
+ "type": "string"
+ },
+ "publishMessage": {
+ "default": "",
+ "type": "string"
+ },
+ "repository": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/github-project-repository"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "uid",
+ "createdAt",
+ "updatedAt",
+ "name",
+ "activeDeployment",
+ "lastPublished",
+ "lastPublishedUid",
+ "loginPortalUid",
+ "activeThemeId",
+ "isPrivate",
+ "agentEnabled",
+ "accessGroups",
+ "slug",
+ "publishStatus",
+ "publishMessage"
+ ],
+ "additionalProperties": false
+ },
+ "active-deployment": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "type": "string"
+ },
+ "domain": {
+ "type": "string"
+ },
+ "publishedAt": {
+ "$ref": "#/components/schemas/timestamp"
+ }
+ },
+ "required": [
+ "uid",
+ "domain",
+ "publishedAt"
+ ],
+ "additionalProperties": false
+ },
+ "github-project-repository": {
+ "type": "object",
+ "properties": {
+ "linkedBy": {
+ "type": "string"
+ },
+ "id": {
+ "type": "number"
+ },
+ "name": {
+ "type": "string",
+ "minLength": 2
+ },
+ "configPath": {
+ "default": "",
+ "type": "string"
+ },
+ "branch": {
+ "default": "",
+ "type": "string"
+ },
+ "publishOnMerge": {
+ "default": false,
+ "type": "boolean"
+ },
+ "publishPreviews": {
+ "default": false,
+ "type": "boolean"
+ },
+ "prComments": {
+ "default": false,
+ "type": "boolean"
+ },
+ "expired": {
+ "default": false,
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "linkedBy",
+ "id",
+ "name",
+ "configPath",
+ "branch",
+ "publishOnMerge",
+ "publishPreviews",
+ "prComments",
+ "expired"
+ ],
+ "additionalProperties": false
+ },
+ "email": {
+ "type": "string",
+ "format": "email",
+ "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
+ },
+ "team-summary": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "name": {
+ "$ref": "#/components/schemas/team-name"
+ },
+ "imageUri": {
+ "$ref": "#/components/schemas/team-image"
+ }
+ },
+ "required": [
+ "uid",
+ "name"
+ ],
+ "additionalProperties": false
+ },
+ "user": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "default": "nanoid()",
+ "$ref": "#/components/schemas/nanoid"
+ },
+ "createdAt": {
+ "default": "unixTimestamp()",
+ "$ref": "#/components/schemas/timestamp"
+ },
+ "updatedAt": {
+ "default": "unixTimestamp()",
+ "$ref": "#/components/schemas/timestamp"
+ },
+ "email": {
+ "$ref": "#/components/schemas/email"
+ },
+ "theme": {
+ "type": "string"
+ },
+ "activeTeamId": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "hasGithub": {
+ "default": false,
+ "type": "boolean"
+ },
+ "teams": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/team-summary"
+ }
+ }
+ },
+ "required": [
+ "uid",
+ "createdAt",
+ "updatedAt",
+ "email",
+ "activeTeamId",
+ "hasGithub",
+ "teams"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "security": [
+ {
+ "BearerAuth": []
+ }
+ ],
+ "paths": {
+ "/v1/apis": {
+ "get": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "List all API documents across every namespace the caller can access.",
+ "summary": "List all API Documents",
+ "operationId": "listAllApiDocuments",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/api-document"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst listAllAPIDocuments = await client.registry.listAllAPIDocuments();\nconsole.log(listAllAPIDocuments);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry list-all-api-documents --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.list_all_api_documents()\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.ListAllAPIDocuments(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryListAllApiDocumentsParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval registry = client.registry().listAllApiDocuments(RegistryListAllApiDocumentsParams.none())\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.list_all_api_documents\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryListAllApiDocumentsParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar registry = client.registry().listAllApiDocuments();\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry list-all-api-documents --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/apis/{namespace}": {
+ "get": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "List API documents in a namespace.",
+ "summary": "List API Documents in a namespace",
+ "operationId": "listApiDocuments",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/api-document"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst listAPIDocuments = await client.registry.listAPIDocuments(\"namespace\");\nconsole.log(listAPIDocuments);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry list-api-documents 'namespace' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.list_api_documents(\n namespace=\"namespace\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.ListAPIDocuments(context.Background(), \"namespace\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryListApiDocumentsParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryListApiDocumentsParams.builder()\n .namespace(\"namespace\")\n .build()\nval registry = client.registry().listApiDocuments(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.list_api_documents(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryListApiDocumentsParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryListApiDocumentsParams params = RegistryListApiDocumentsParams.builder()\n .namespace(\"namespace\")\n .build();\nvar registry = client.registry().listApiDocuments(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry list-api-documents 'namespace' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Create an API document.",
+ "summary": "Create API Document",
+ "operationId": "createApiDocument",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "type": "string"
+ },
+ "versionUid": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "jsonSha": {
+ "type": "string"
+ },
+ "yamlSha": {
+ "type": "string"
+ },
+ "versionSha": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "uid",
+ "versionUid",
+ "title",
+ "jsonSha",
+ "yamlSha",
+ "versionSha"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "version": {
+ "$ref": "#/components/schemas/version"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "ruleset": {
+ "type": "string"
+ },
+ "isPrivate": {
+ "type": "boolean"
+ },
+ "document": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "version",
+ "slug",
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst createAPIDocument = await client.registry.createAPIDocument(\"namespace\", {\n title: \"\",\n version: \"\",\n slug: \"\",\n document: \"\",\n});\nconsole.log(createAPIDocument);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry create-api-document 'namespace' --bearer-auth \"$BEARER_AUTH\" --title 'title' --version-command 'version' --slug 'slug' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.create_api_document(\n namespace=\"namespace\",\n title=\"\",\n version=\"\",\n slug=\"\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.NewAPIDocument(context.Background(), \"namespace\", sdk.RegistryNewAPIDocumentParams{\n\t\tDocument: \"\",\n\t\tSlug: \"\",\n\t\tTitle: \"\",\n\t\tVersion: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryCreateApiDocumentParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryCreateApiDocumentParams.builder()\n .namespace(\"namespace\")\n .title(\"title\")\n .version(\"version\")\n .slug(\"slug\")\n .document(\"document\")\n .build()\nval registry = client.registry().createApiDocument(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.create_api_document(\"smoke-test\", { title: \"title\", description: \"description\", version: \"version\", slug: \"slug\", ruleset: \"ruleset\", is_private: \"is_private\", document: \"document\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryCreateApiDocumentParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryCreateApiDocumentParams params = RegistryCreateApiDocumentParams.builder()\n .namespace(\"namespace\")\n .title(\"title\")\n .version(\"version\")\n .slug(\"slug\")\n .document(\"document\")\n .build();\nvar registry = client.registry().createApiDocument(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry create-api-document 'namespace' --bearer-auth \"$BEARER_AUTH\" --title 'title' --version-command 'version' --slug 'slug' --document 'document'"
+ }
+ ]
+ }
+ },
+ "/v1/apis/{namespace}/{slug}": {
+ "patch": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Update metadata for an API document.",
+ "summary": "Update API Document metadata",
+ "operationId": "updateApiDocument",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "isPrivate": {
+ "type": "boolean"
+ },
+ "ruleset": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.registry.updateAPIDocument(\"slug\", {\n namespace: \"namespace\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry update-api-document 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.update_api_document(\n namespace=\"namespace\",\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.UpdateAPIDocument(context.Background(), \"namespace\", \"slug\", sdk.RegistryUpdateAPIDocumentParams{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryUpdateApiDocumentParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryUpdateApiDocumentParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval registry = client.registry().updateApiDocument(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.update_api_document(\"smoke-test\", { namespace: \"namespace\", title: \"title\", description: \"description\", is_private: \"is_private\", ruleset: \"ruleset\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryUpdateApiDocumentParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryUpdateApiDocumentParams params = RegistryUpdateApiDocumentParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar registry = client.registry().updateApiDocument(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry update-api-document 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Delete an API document and all versions.",
+ "summary": "Delete API Document",
+ "operationId": "deleteApiDocument",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.registry.deleteAPIDocument(\"slug\", {\n namespace: \"namespace\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry delete-api-document 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.delete_api_document(\n namespace=\"namespace\",\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.DeleteAPIDocument(context.Background(), \"namespace\", \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryDeleteApiDocumentParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryDeleteApiDocumentParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval registry = client.registry().deleteApiDocument(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.delete_api_document(\"smoke-test\", { namespace: \"namespace\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryDeleteApiDocumentParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryDeleteApiDocumentParams params = RegistryDeleteApiDocumentParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar registry = client.registry().deleteApiDocument(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry delete-api-document 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ }
+ },
+ "/v1/apis/{namespace}/{slug}/version/{semver}": {
+ "get": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Get a specific API document version.",
+ "summary": "Get API Document",
+ "operationId": "getApiDocumentVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "semver",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst string_ = await client.registry.retrieveAPIDocumentVersion(\"semver\", {\n namespace: \"namespace\",\n slug: \"slug\",\n});\nconsole.log(string_);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry retrieve-api-document-version 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.retrieve_api_document_version(\n namespace=\"namespace\",\n slug=\"slug\",\n semver=\"semver\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.GetAPIDocumentVersion(context.Background(), \"namespace\", \"slug\", \"semver\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryRetrieveApiDocumentVersionParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryRetrieveApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build()\nval registry = client.registry().retrieveApiDocumentVersion(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.retrieve_api_document_version(\"smoke-test\", { namespace: \"namespace\", slug: \"slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryRetrieveApiDocumentVersionParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryRetrieveApiDocumentVersionParams params = RegistryRetrieveApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build();\nvar registry = client.registry().retrieveApiDocumentVersion(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry retrieve-api-document-version 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ }
+ ]
+ },
+ "patch": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Update the registry file content for an API document version.",
+ "summary": "Update API Document version",
+ "operationId": "updateApiDocumentVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "jsonSha": {
+ "type": "string"
+ },
+ "yamlSha": {
+ "type": "string"
+ },
+ "versionSha": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "jsonSha",
+ "yamlSha",
+ "versionSha"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "document": {
+ "type": "string"
+ },
+ "lastKnownVersionSha": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "semver",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst updateAPIDocumentVersion = await client.registry.updateAPIDocumentVersion(\"semver\", {\n namespace: \"namespace\",\n slug: \"slug\",\n document: \"\",\n});\nconsole.log(updateAPIDocumentVersion);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry update-api-document-version 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.update_api_document_version(\n namespace=\"namespace\",\n slug=\"slug\",\n semver=\"semver\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.UpdateAPIDocumentVersion(context.Background(), \"namespace\", \"slug\", \"semver\", sdk.RegistryUpdateAPIDocumentVersionParams{\n\t\tDocument: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryUpdateApiDocumentVersionParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryUpdateApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .document(\"document\")\n .build()\nval registry = client.registry().updateApiDocumentVersion(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.update_api_document_version(\"smoke-test\", { namespace: \"namespace\", slug: \"slug\", document: \"document\", last_known_version_sha: \"last_known_version_sha\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryUpdateApiDocumentVersionParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryUpdateApiDocumentVersionParams params = RegistryUpdateApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .document(\"document\")\n .build();\nvar registry = client.registry().updateApiDocumentVersion(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry update-api-document-version 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug' --document 'document'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Delete a specific API document version.",
+ "summary": "Delete API Document version",
+ "operationId": "deleteApiDocumentVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "semver",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.registry.deleteAPIDocumentVersion(\"semver\", {\n namespace: \"namespace\",\n slug: \"slug\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry delete-api-document-version 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.delete_api_document_version(\n namespace=\"namespace\",\n slug=\"slug\",\n semver=\"semver\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.DeleteAPIDocumentVersion(context.Background(), \"namespace\", \"slug\", \"semver\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryDeleteApiDocumentVersionParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryDeleteApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build()\nval registry = client.registry().deleteApiDocumentVersion(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.delete_api_document_version(\"smoke-test\", { namespace: \"namespace\", slug: \"slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryDeleteApiDocumentVersionParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryDeleteApiDocumentVersionParams params = RegistryDeleteApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build();\nvar registry = client.registry().deleteApiDocumentVersion(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry delete-api-document-version 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ }
+ ]
+ }
+ },
+ "/v1/apis/{namespace}/{slug}/version/{semver}/metadata": {
+ "get": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Get metadata (uid, content shas, version sha, tags) for a specific API document version.",
+ "summary": "Get API Document version metadata",
+ "operationId": "getApiDocumentVersionMetadata",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/managed-doc-version"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "semver",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst managedDocVersion = await client.registry.listAPIDocumentVersionMetadata(\"semver\", {\n namespace: \"namespace\",\n slug: \"slug\",\n});\nconsole.log(managedDocVersion);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry list-api-document-version-metadata 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.list_api_document_version_metadata(\n namespace=\"namespace\",\n slug=\"slug\",\n semver=\"semver\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.ListAPIDocumentVersionMetadata(context.Background(), \"namespace\", \"slug\", \"semver\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryListApiDocumentVersionMetadataParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryListApiDocumentVersionMetadataParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build()\nval registry = client.registry().listApiDocumentVersionMetadata(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.list_api_document_version_metadata(\"smoke-test\", { namespace: \"namespace\", slug: \"slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryListApiDocumentVersionMetadataParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryListApiDocumentVersionMetadataParams params = RegistryListApiDocumentVersionMetadataParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build();\nvar registry = client.registry().listApiDocumentVersionMetadata(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry list-api-document-version-metadata 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ }
+ ]
+ }
+ },
+ "/v1/apis/{namespace}/{slug}/version": {
+ "post": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Create a new API document version.",
+ "summary": "Create API Document version",
+ "operationId": "createApiDocumentVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/managed-doc-version"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "version": {
+ "$ref": "#/components/schemas/version"
+ },
+ "document": {
+ "type": "string"
+ },
+ "force": {
+ "type": "boolean"
+ },
+ "lastKnownVersionSha": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "version",
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst managedDocVersion = await client.registry.createAPIDocumentVersion(\"slug\", {\n namespace: \"namespace\",\n version: \"\",\n document: \"\",\n});\nconsole.log(managedDocVersion);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry create-api-document-version 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --version-command 'version' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.create_api_document_version(\n namespace=\"namespace\",\n slug=\"slug\",\n version=\"\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.NewAPIDocumentVersion(context.Background(), \"namespace\", \"slug\", sdk.RegistryNewAPIDocumentVersionParams{\n\t\tDocument: \"\",\n\t\tVersion: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryCreateApiDocumentVersionParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryCreateApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .version(\"version\")\n .document(\"document\")\n .build()\nval registry = client.registry().createApiDocumentVersion(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.create_api_document_version(\"smoke-test\", { namespace: \"namespace\", version: \"version\", document: \"document\", force: \"force\", last_known_version_sha: \"last_known_version_sha\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryCreateApiDocumentVersionParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryCreateApiDocumentVersionParams params = RegistryCreateApiDocumentVersionParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .version(\"version\")\n .document(\"document\")\n .build();\nvar registry = client.registry().createApiDocumentVersion(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry create-api-document-version 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --version-command 'version' --document 'document'"
+ }
+ ]
+ }
+ },
+ "/v1/apis/{namespace}/{slug}/access-group": {
+ "post": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Add an access group to an API document.",
+ "summary": "Add access group",
+ "operationId": "addApiDocumentAccessGroup",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/access-group"
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.registry.createAPIDocumentAccessGroup(\"slug\", {\n namespace: \"namespace\",\n accessGroupSlug: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry create-api-document-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.create_api_document_access_group(\n namespace=\"namespace\",\n slug=\"slug\",\n access_group_slug=\"\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.NewAPIDocumentAccessGroup(context.Background(), \"namespace\", \"slug\", sdk.RegistryNewAPIDocumentAccessGroupParams{\n\t\tAccessGroup: sdk.AccessGroup{\n\t\tAccessGroupSlug: \"\",\n\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryCreateApiDocumentAccessGroupParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryCreateApiDocumentAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build()\nval registry = client.registry().createApiDocumentAccessGroup(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.create_api_document_access_group(\"smoke-test\", { namespace: \"namespace\", access_group_slug: \"access_group_slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryCreateApiDocumentAccessGroupParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryCreateApiDocumentAccessGroupParams params = RegistryCreateApiDocumentAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build();\nvar registry = client.registry().createApiDocumentAccessGroup(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry create-api-document-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Registry"
+ ],
+ "description": "Remove an access group from an API document.",
+ "summary": "Remove access group",
+ "operationId": "removeApiDocumentAccessGroup",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/access-group"
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.registry.deleteAPIDocumentAccessGroup(\"slug\", {\n namespace: \"namespace\",\n accessGroupSlug: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi registry delete-api-document-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nregistry = client.registry.delete_api_document_access_group(\n namespace=\"namespace\",\n slug=\"slug\",\n access_group_slug=\"\",\n idempotency_key=\"\",\n)\nprint(registry)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tregistry, err := client.Registry.DeleteAPIDocumentAccessGroup(context.Background(), \"namespace\", \"slug\", sdk.RegistryDeleteAPIDocumentAccessGroupParams{\n\t\tAccessGroup: sdk.AccessGroup{\n\t\tAccessGroupSlug: \"\",\n\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(registry)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.registry.RegistryDeleteApiDocumentAccessGroupParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RegistryDeleteApiDocumentAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build()\nval registry = client.registry().deleteApiDocumentAccessGroup(params)\nprintln(registry)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.registry.delete_api_document_access_group(\"smoke-test\", { namespace: \"namespace\", access_group_slug: \"access_group_slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.registry.RegistryDeleteApiDocumentAccessGroupParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRegistryDeleteApiDocumentAccessGroupParams params = RegistryDeleteApiDocumentAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build();\nvar registry = client.registry().deleteApiDocumentAccessGroup(params);\nSystem.out.println(registry);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi registry delete-api-document-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ }
+ ]
+ }
+ },
+ "/v1/schemas/{namespace}": {
+ "get": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "List schemas in a namespace.",
+ "summary": "List all shared components",
+ "operationId": "listSchemas",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/schema"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst list = await client.schemas.list(\"namespace\");\nconsole.log(list);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas list 'namespace' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nschema = client.schemas.list(\n namespace=\"namespace\",\n)\nprint(schema)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tschema, err := client.Schemas.List(context.Background(), \"namespace\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(schema)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.SchemaListParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = SchemaListParams.builder()\n .namespace(\"namespace\")\n .build()\nval schema = client.schemas().list(params)\nprintln(schema)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.list(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.SchemaListParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nSchemaListParams params = SchemaListParams.builder()\n .namespace(\"namespace\")\n .build();\nvar schema = client.schemas().list(params);\nSystem.out.println(schema);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas list 'namespace' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Create a schema in a namespace.",
+ "summary": "Create a shared component",
+ "operationId": "createSchema",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/uid"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "version": {
+ "$ref": "#/components/schemas/version"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "isPrivate": {
+ "type": "boolean"
+ },
+ "document": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "version",
+ "slug",
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst uID = await client.schemas.create(\"namespace\", {\n title: \"\",\n version: \"\",\n slug: \"\",\n document: \"\",\n});\nconsole.log(uID);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas create 'namespace' --bearer-auth \"$BEARER_AUTH\" --title 'title' --version-command 'version' --slug 'slug' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nschema = client.schemas.create(\n namespace=\"namespace\",\n title=\"\",\n version=\"\",\n slug=\"\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(schema)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tschema, err := client.Schemas.New(context.Background(), \"namespace\", sdk.SchemaNewParams{\n\t\tDocument: \"\",\n\t\tSlug: \"\",\n\t\tTitle: \"\",\n\t\tVersion: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(schema)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.SchemaCreateParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = SchemaCreateParams.builder()\n .namespace(\"namespace\")\n .title(\"title\")\n .version(\"version\")\n .slug(\"slug\")\n .document(\"document\")\n .build()\nval schema = client.schemas().create(params)\nprintln(schema)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.create(\"smoke-test\", { title: \"title\", description: \"description\", version: \"version\", slug: \"slug\", is_private: \"is_private\", document: \"document\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.SchemaCreateParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nSchemaCreateParams params = SchemaCreateParams.builder()\n .namespace(\"namespace\")\n .title(\"title\")\n .version(\"version\")\n .slug(\"slug\")\n .document(\"document\")\n .build();\nvar schema = client.schemas().create(params);\nSystem.out.println(schema);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas create 'namespace' --bearer-auth \"$BEARER_AUTH\" --title 'title' --version-command 'version' --slug 'slug' --document 'document'"
+ }
+ ]
+ }
+ },
+ "/v1/schemas/{namespace}/{slug}": {
+ "patch": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Update schema metadata.",
+ "summary": "Update shared component metadata",
+ "operationId": "updateSchema",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "isPrivate": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.schemas.update(\"slug\", {\n namespace: \"namespace\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas update 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nschema = client.schemas.update(\n namespace=\"namespace\",\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(schema)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tschema, err := client.Schemas.Update(context.Background(), \"namespace\", \"slug\", sdk.SchemaUpdateParams{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(schema)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.SchemaUpdateParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = SchemaUpdateParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval schema = client.schemas().update(params)\nprintln(schema)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.update(\"smoke-test\", { namespace: \"namespace\", title: \"title\", description: \"description\", is_private: \"is_private\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.SchemaUpdateParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nSchemaUpdateParams params = SchemaUpdateParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar schema = client.schemas().update(params);\nSystem.out.println(schema);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas update 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Delete a schema and all related versions.",
+ "summary": "Delete a shared component",
+ "operationId": "deleteSchema",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.schemas.delete(\"slug\", {\n namespace: \"namespace\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas delete 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nschema = client.schemas.delete(\n namespace=\"namespace\",\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(schema)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tschema, err := client.Schemas.Delete(context.Background(), \"namespace\", \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(schema)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.SchemaDeleteParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = SchemaDeleteParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval schema = client.schemas().delete(params)\nprintln(schema)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.delete(\"smoke-test\", { namespace: \"namespace\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.SchemaDeleteParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nSchemaDeleteParams params = SchemaDeleteParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar schema = client.schemas().delete(params);\nSystem.out.println(schema);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas delete 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ }
+ },
+ "/v1/schemas/{namespace}/{slug}/version/{semver}": {
+ "get": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Get a specific schema version document.",
+ "summary": "Get a shared component document",
+ "operationId": "getSchemaVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "semver",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst string_ = await client.schemas.version.retrieveSchema(\"semver\", {\n namespace: \"namespace\",\n slug: \"slug\",\n});\nconsole.log(string_);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas:version-command retrieve-schema 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nversion = client.schemas.version.retrieve_schema(\n namespace=\"namespace\",\n slug=\"slug\",\n semver=\"semver\",\n)\nprint(version)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tversion, err := client.Schemas.Version.GetSchema(context.Background(), \"namespace\", \"slug\", \"semver\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(version)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.version.VersionRetrieveSchemaParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = VersionRetrieveSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build()\nval version = client.schemas().version().retrieveSchema(params)\nprintln(version)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.version.retrieve_schema(\"smoke-test\", { namespace: \"namespace\", slug: \"slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.version.VersionRetrieveSchemaParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nVersionRetrieveSchemaParams params = VersionRetrieveSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build();\nvar version = client.schemas().version().retrieveSchema(params);\nSystem.out.println(version);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas:version-command retrieve-schema 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Delete a schema version.",
+ "summary": "Delete a shared component version",
+ "operationId": "deleteSchemaVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "semver",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.schemas.version.deleteSchema(\"semver\", {\n namespace: \"namespace\",\n slug: \"slug\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas:version-command delete-schema 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nversion = client.schemas.version.delete_schema(\n namespace=\"namespace\",\n slug=\"slug\",\n semver=\"semver\",\n idempotency_key=\"\",\n)\nprint(version)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tversion, err := client.Schemas.Version.DeleteSchema(context.Background(), \"namespace\", \"slug\", \"semver\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(version)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.version.VersionDeleteSchemaParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = VersionDeleteSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build()\nval version = client.schemas().version().deleteSchema(params)\nprintln(version)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.version.delete_schema(\"smoke-test\", { namespace: \"namespace\", slug: \"slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.version.VersionDeleteSchemaParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nVersionDeleteSchemaParams params = VersionDeleteSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .semver(\"semver\")\n .build();\nvar version = client.schemas().version().deleteSchema(params);\nSystem.out.println(version);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas:version-command delete-schema 'semver' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --slug 'slug'"
+ }
+ ]
+ }
+ },
+ "/v1/schemas/{namespace}/{slug}/version": {
+ "post": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Create a schema version.",
+ "summary": "Create a shared component version",
+ "operationId": "createSchemaVersion",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/uid"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "version": {
+ "$ref": "#/components/schemas/version"
+ },
+ "document": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "version",
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst uID = await client.schemas.version.createSchema(\"slug\", {\n namespace: \"namespace\",\n version: \"\",\n document: \"\",\n});\nconsole.log(uID);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas:version-command create-schema 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --version-command 'version' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nversion = client.schemas.version.create_schema(\n namespace=\"namespace\",\n slug=\"slug\",\n version=\"\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(version)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tversion, err := client.Schemas.Version.NewSchema(context.Background(), \"namespace\", \"slug\", sdk.SchemaVersionNewSchemaParams{\n\t\tDocument: \"\",\n\t\tVersion: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(version)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.version.VersionCreateSchemaParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = VersionCreateSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .version(\"version\")\n .document(\"document\")\n .build()\nval version = client.schemas().version().createSchema(params)\nprintln(version)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.version.create_schema(\"smoke-test\", { namespace: \"namespace\", version: \"version\", document: \"document\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.version.VersionCreateSchemaParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nVersionCreateSchemaParams params = VersionCreateSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .version(\"version\")\n .document(\"document\")\n .build();\nvar version = client.schemas().version().createSchema(params);\nSystem.out.println(version);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas:version-command create-schema 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --version-command 'version' --document 'document'"
+ }
+ ]
+ }
+ },
+ "/v1/schemas/{namespace}/{slug}/access-group": {
+ "post": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Add an access group to a schema.",
+ "summary": "Add shared component access group",
+ "operationId": "addSchemaAccessGroup",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/access-group"
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.schemas.accessGroup.createSchema(\"slug\", {\n namespace: \"namespace\",\n accessGroupSlug: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas:access-group create-schema 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\naccess_group = client.schemas.access_group.create_schema(\n namespace=\"namespace\",\n slug=\"slug\",\n access_group_slug=\"\",\n idempotency_key=\"\",\n)\nprint(access_group)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\taccessGroup, err := client.Schemas.AccessGroup.NewSchema(context.Background(), \"namespace\", \"slug\", sdk.SchemaAccessGroupNewSchemaParams{\n\t\tAccessGroup: sdk.AccessGroup{\n\t\tAccessGroupSlug: \"\",\n\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(accessGroup)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.accessgroup.AccessGroupCreateSchemaParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = AccessGroupCreateSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build()\nval accessGroup = client.schemas().accessGroup().createSchema(params)\nprintln(accessGroup)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.accessGroup.create_schema(\"smoke-test\", { namespace: \"namespace\", access_group_slug: \"access_group_slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.accessgroup.AccessGroupCreateSchemaParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nAccessGroupCreateSchemaParams params = AccessGroupCreateSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build();\nvar accessGroup = client.schemas().accessGroup().createSchema(params);\nSystem.out.println(accessGroup);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas:access-group create-schema 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Schemas"
+ ],
+ "description": "Remove an access group from a schema.",
+ "summary": "Remove shared component access group",
+ "operationId": "removeSchemaAccessGroup",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/access-group"
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.schemas.accessGroup.deleteSchema(\"slug\", {\n namespace: \"namespace\",\n accessGroupSlug: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi schemas:access-group delete-schema 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\naccess_group = client.schemas.access_group.delete_schema(\n namespace=\"namespace\",\n slug=\"slug\",\n access_group_slug=\"\",\n idempotency_key=\"\",\n)\nprint(access_group)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\taccessGroup, err := client.Schemas.AccessGroup.DeleteSchema(context.Background(), \"namespace\", \"slug\", sdk.SchemaAccessGroupDeleteSchemaParams{\n\t\tAccessGroup: sdk.AccessGroup{\n\t\tAccessGroupSlug: \"\",\n\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(accessGroup)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.schemas.accessgroup.AccessGroupDeleteSchemaParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = AccessGroupDeleteSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build()\nval accessGroup = client.schemas().accessGroup().deleteSchema(params)\nprintln(accessGroup)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.schemas.accessGroup.delete_schema(\"smoke-test\", { namespace: \"namespace\", access_group_slug: \"access_group_slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.schemas.accessgroup.AccessGroupDeleteSchemaParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nAccessGroupDeleteSchemaParams params = AccessGroupDeleteSchemaParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build();\nvar accessGroup = client.schemas().accessGroup().deleteSchema(params);\nSystem.out.println(accessGroup);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi schemas:access-group delete-schema 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ }
+ ]
+ }
+ },
+ "/v1/login-portals/{slug}": {
+ "get": {
+ "tags": [
+ "Login Portals"
+ ],
+ "description": "Get a login portal by slug.",
+ "summary": "Get a login portal",
+ "operationId": "getLoginPortal",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "email": {
+ "$ref": "#/components/schemas/login-portal-email"
+ },
+ "page": {
+ "$ref": "#/components/schemas/login-portal-page"
+ }
+ },
+ "required": [
+ "uid",
+ "title",
+ "slug",
+ "email",
+ "page"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst retrieve = await client.loginPortals.retrieve(\"slug\");\nconsole.log(retrieve);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi login-portals retrieve 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nlogin_portal = client.login_portals.retrieve(\n slug=\"slug\",\n)\nprint(login_portal)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tloginPortal, err := client.LoginPortals.Get(context.Background(), \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(loginPortal)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.loginportals.LoginPortalRetrieveParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = LoginPortalRetrieveParams.builder()\n .slug(\"slug\")\n .build()\nval loginPortal = client.loginPortals().retrieve(params)\nprintln(loginPortal)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.loginPortals.retrieve(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.loginportals.LoginPortalRetrieveParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nLoginPortalRetrieveParams params = LoginPortalRetrieveParams.builder()\n .slug(\"slug\")\n .build();\nvar loginPortal = client.loginPortals().retrieve(params);\nSystem.out.println(loginPortal);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi login-portals retrieve 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "patch": {
+ "tags": [
+ "Login Portals"
+ ],
+ "description": "Update metadata for a login portal.",
+ "summary": "Update portal metadata",
+ "operationId": "updateLoginPortal",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.loginPortals.update(\"slug\", {});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi login-portals update 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nlogin_portal = client.login_portals.update(\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(login_portal)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tloginPortal, err := client.LoginPortals.Update(context.Background(), \"slug\", sdk.LoginPortalUpdateParams{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(loginPortal)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.loginportals.LoginPortalUpdateParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = LoginPortalUpdateParams.builder()\n .slug(\"slug\")\n .build()\nval loginPortal = client.loginPortals().update(params)\nprintln(loginPortal)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.loginPortals.update(\"smoke-test\", { title: \"title\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.loginportals.LoginPortalUpdateParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nLoginPortalUpdateParams params = LoginPortalUpdateParams.builder()\n .slug(\"slug\")\n .build();\nvar loginPortal = client.loginPortals().update(params);\nSystem.out.println(loginPortal);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi login-portals update 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Login Portals"
+ ],
+ "description": "Delete a login portal.",
+ "summary": "Delete a login portal",
+ "operationId": "deleteLoginPortal",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.loginPortals.delete(\"slug\");"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi login-portals delete 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nlogin_portal = client.login_portals.delete(\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(login_portal)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tloginPortal, err := client.LoginPortals.Delete(context.Background(), \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(loginPortal)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.loginportals.LoginPortalDeleteParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = LoginPortalDeleteParams.builder()\n .slug(\"slug\")\n .build()\nval loginPortal = client.loginPortals().delete(params)\nprintln(loginPortal)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.loginPortals.delete(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.loginportals.LoginPortalDeleteParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nLoginPortalDeleteParams params = LoginPortalDeleteParams.builder()\n .slug(\"slug\")\n .build();\nvar loginPortal = client.loginPortals().delete(params);\nSystem.out.println(loginPortal);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi login-portals delete 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/login-portals": {
+ "post": {
+ "tags": [
+ "Login Portals"
+ ],
+ "description": "Create a login portal for the current team.",
+ "summary": "Create a portal",
+ "operationId": "createLoginPortal",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/uid"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "email": {
+ "$ref": "#/components/schemas/login-portal-email"
+ },
+ "page": {
+ "$ref": "#/components/schemas/login-portal-page"
+ }
+ },
+ "required": [
+ "title",
+ "slug",
+ "email",
+ "page"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst uID = await client.loginPortals.create({\n title: \"\",\n slug: \"\",\n email: {\n logo: \"\",\n logoSize: \"100\",\n buttonText: \"Login\",\n message: \"Click to access private documentation hosted by scalar.com\",\n title: \"Private Docs\",\n mainColor: \"#2a2f45\",\n mainBackground: \"#f6f6f6\",\n cardColor: \"2a2f45\",\n cardBackground: \"#fff\",\n buttonColor: \"#fff\",\n buttonBackground: \"#0f0f0f\",\n },\n page: {\n title: \"Scalar Private Docs\",\n description: \"Login to access your documentation\",\n head: \"\",\n script: \"\",\n theme: \"\",\n companyName: \"\",\n logo: \"\",\n logoUrl: \"\",\n favicon: \"\",\n termsLink: \"\",\n privacyLink: \"\",\n formTitle: \"Scalar Private Docs\",\n formDescription: \"Login to access your documentation\",\n formImage: \"\",\n },\n});\nconsole.log(uID);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi login-portals create --bearer-auth \"$BEARER_AUTH\" --title 'title' --slug 'slug' --email '{\"logo\":\"\",\"logoSize\":\"100\",\"buttonText\":\"Login\",\"message\":\"Click to access private documentation hosted by scalar.com\",\"title\":\"Private Docs\",\"mainColor\":\"#2a2f45\",\"mainBackground\":\"#f6f6f6\",\"cardColor\":\"2a2f45\",\"cardBackground\":\"#fff\",\"buttonColor\":\"#fff\",\"buttonBackground\":\"#0f0f0f\"}' --page '{\"title\":\"Scalar Private Docs\",\"description\":\"Login to access your documentation\",\"head\":\"\",\"script\":\"\",\"theme\":\"\",\"companyName\":\"\",\"logo\":\"\",\"logoURL\":\"\",\"favicon\":\"\",\"termsLink\":\"\",\"privacyLink\":\"\",\"formTitle\":\"Scalar Private Docs\",\"formDescription\":\"Login to access your documentation\",\"formImage\":\"\"}'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nlogin_portal = client.login_portals.create(\n title=\"\",\n slug=\"\",\n email={\"logo\": \"\", \"logo_size\": \"100\", \"button_text\": \"Login\", \"message\": \"Click to access private documentation hosted by scalar.com\", \"title\": \"Private Docs\", \"main_color\": \"#2a2f45\", \"main_background\": \"#f6f6f6\", \"card_color\": \"2a2f45\", \"card_background\": \"#fff\", \"button_color\": \"#fff\", \"button_background\": \"#0f0f0f\"},\n page={\"title\": \"Scalar Private Docs\", \"description\": \"Login to access your documentation\", \"head\": \"\", \"script\": \"\", \"theme\": \"\", \"company_name\": \"\", \"logo\": \"\", \"logo_url\": \"\", \"favicon\": \"\", \"terms_link\": \"\", \"privacy_link\": \"\", \"form_title\": \"Scalar Private Docs\", \"form_description\": \"Login to access your documentation\", \"form_image\": \"\"},\n idempotency_key=\"\",\n)\nprint(login_portal)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tloginPortal, err := client.LoginPortals.New(context.Background(), sdk.LoginPortalNewParams{\n\t\tEmail: sdk.LoginPortalEmail{\n\t\t\tLogo: \"\",\n\t\t\tLogoSize: \"100\",\n\t\t\tButtonText: \"Login\",\n\t\t\tMessage: \"Click to access private documentation hosted by scalar.com\",\n\t\t\tTitle: \"Private Docs\",\n\t\t\tMainColor: \"#2a2f45\",\n\t\t\tMainBackground: \"#f6f6f6\",\n\t\t\tCardColor: \"2a2f45\",\n\t\t\tCardBackground: \"#fff\",\n\t\t\tButtonColor: \"#fff\",\n\t\t\tButtonBackground: \"#0f0f0f\",\n\t\t},\n\t\tPage: sdk.LoginPortalPage{\n\t\t\tTitle: \"Scalar Private Docs\",\n\t\t\tDescription: \"Login to access your documentation\",\n\t\t\tHead: \"\",\n\t\t\tScript: \"\",\n\t\t\tTheme: \"\",\n\t\t\tCompanyName: \"\",\n\t\t\tLogo: \"\",\n\t\t\tLogoURL: \"\",\n\t\t\tFavicon: \"\",\n\t\t\tTermsLink: \"\",\n\t\t\tPrivacyLink: \"\",\n\t\t\tFormTitle: \"Scalar Private Docs\",\n\t\t\tFormDescription: \"Login to access your documentation\",\n\t\t\tFormImage: \"\",\n\t\t},\n\t\tSlug: \"\",\n\t\tTitle: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(loginPortal)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.loginportals.LoginPortalCreateParams\nimport com.scalar.api.models.loginportals.LoginPortalEmail\nimport com.scalar.api.models.loginportals.LoginPortalPage\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = LoginPortalCreateParams.builder()\n .title(\"title\")\n .slug(\"slug\")\n .email(LoginPortalEmail.builder()\n .logo(\"\")\n .logoSize(\"100\")\n .buttonText(\"Login\")\n .message(\"Click to access private documentation hosted by scalar.com\")\n .title(\"Private Docs\")\n .mainColor(\"#2a2f45\")\n .mainBackground(\"#f6f6f6\")\n .cardColor(\"2a2f45\")\n .cardBackground(\"#fff\")\n .buttonColor(\"#fff\")\n .buttonBackground(\"#0f0f0f\")\n .build())\n .page(LoginPortalPage.builder()\n .title(\"Scalar Private Docs\")\n .description(\"Login to access your documentation\")\n .head(\"\")\n .script(\"\")\n .theme(\"\")\n .companyName(\"\")\n .logo(\"\")\n .logoUrl(\"\")\n .favicon(\"\")\n .termsLink(\"\")\n .privacyLink(\"\")\n .formTitle(\"Scalar Private Docs\")\n .formDescription(\"Login to access your documentation\")\n .formImage(\"\")\n .build())\n .build()\nval loginPortal = client.loginPortals().create(params)\nprintln(loginPortal)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.loginPortals.create({ title: \"title\", slug: \"slug\", email: \"email\", page: \"page\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.loginportals.LoginPortalCreateParams;\nimport com.scalar.api.models.loginportals.LoginPortalEmail;\nimport com.scalar.api.models.loginportals.LoginPortalPage;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nLoginPortalCreateParams params = LoginPortalCreateParams.builder()\n .title(\"title\")\n .slug(\"slug\")\n .email(LoginPortalEmail.builder()\n .logo(\"\")\n .logoSize(\"100\")\n .buttonText(\"Login\")\n .message(\"Click to access private documentation hosted by scalar.com\")\n .title(\"Private Docs\")\n .mainColor(\"#2a2f45\")\n .mainBackground(\"#f6f6f6\")\n .cardColor(\"2a2f45\")\n .cardBackground(\"#fff\")\n .buttonColor(\"#fff\")\n .buttonBackground(\"#0f0f0f\")\n .build())\n .page(LoginPortalPage.builder()\n .title(\"Scalar Private Docs\")\n .description(\"Login to access your documentation\")\n .head(\"\")\n .script(\"\")\n .theme(\"\")\n .companyName(\"\")\n .logo(\"\")\n .logoUrl(\"\")\n .favicon(\"\")\n .termsLink(\"\")\n .privacyLink(\"\")\n .formTitle(\"Scalar Private Docs\")\n .formDescription(\"Login to access your documentation\")\n .formImage(\"\")\n .build())\n .build();\nvar loginPortal = client.loginPortals().create(params);\nSystem.out.println(loginPortal);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi login-portals create --bearer-auth \"$BEARER_AUTH\" --title 'title' --slug 'slug' --email '{\"logo\":\"\",\"logoSize\":\"100\",\"buttonText\":\"Login\",\"message\":\"Click to access private documentation hosted by scalar.com\",\"title\":\"Private Docs\",\"mainColor\":\"#2a2f45\",\"mainBackground\":\"#f6f6f6\",\"cardColor\":\"2a2f45\",\"cardBackground\":\"#fff\",\"buttonColor\":\"#fff\",\"buttonBackground\":\"#0f0f0f\"}' --page '{\"title\":\"Scalar Private Docs\",\"description\":\"Login to access your documentation\",\"head\":\"\",\"script\":\"\",\"theme\":\"\",\"companyName\":\"\",\"logo\":\"\",\"logoURL\":\"\",\"favicon\":\"\",\"termsLink\":\"\",\"privacyLink\":\"\",\"formTitle\":\"Scalar Private Docs\",\"formDescription\":\"Login to access your documentation\",\"formImage\":\"\"}'"
+ }
+ ]
+ },
+ "get": {
+ "tags": [
+ "Login Portals"
+ ],
+ "description": "List all login portals for the current team.",
+ "summary": "List all portals",
+ "operationId": "listLoginPortals",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/login-portal"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst list = await client.loginPortals.list();\nconsole.log(list);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi login-portals list --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nlogin_portal = client.login_portals.list()\nprint(login_portal)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tloginPortal, err := client.LoginPortals.List(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(loginPortal)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.loginportals.LoginPortalListParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval loginPortal = client.loginPortals().list(LoginPortalListParams.none())\nprintln(loginPortal)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.loginPortals.list\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.loginportals.LoginPortalListParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar loginPortal = client.loginPortals().list();\nSystem.out.println(loginPortal);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi login-portals list --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/rulesets/{namespace}": {
+ "get": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "List all rulesets in a namespace.",
+ "summary": "List all rules",
+ "operationId": "listRulesets",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/rule"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst listRulesets = await client.rules.listRulesets(\"namespace\");\nconsole.log(listRulesets);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules list-rulesets 'namespace' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.list_rulesets(\n namespace=\"namespace\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.ListRulesets(context.Background(), \"namespace\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleListRulesetsParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleListRulesetsParams.builder()\n .namespace(\"namespace\")\n .build()\nval rule = client.rules().listRulesets(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.list_rulesets(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleListRulesetsParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleListRulesetsParams params = RuleListRulesetsParams.builder()\n .namespace(\"namespace\")\n .build();\nvar rule = client.rules().listRulesets(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules list-rulesets 'namespace' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "Create a rule in a namespace.",
+ "summary": "Create a rule",
+ "operationId": "createRuleset",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/uid"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "isPrivate": {
+ "type": "boolean"
+ },
+ "document": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "title",
+ "slug",
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst uID = await client.rules.createRuleset(\"namespace\", {\n title: \"\",\n slug: \"\",\n document: \"\",\n});\nconsole.log(uID);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules create-ruleset 'namespace' --bearer-auth \"$BEARER_AUTH\" --title 'title' --slug 'slug' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.create_ruleset(\n namespace=\"namespace\",\n title=\"\",\n slug=\"\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.NewRuleset(context.Background(), \"namespace\", sdk.RuleNewRulesetParams{\n\t\tDocument: \"\",\n\t\tSlug: \"\",\n\t\tTitle: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleCreateRulesetParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleCreateRulesetParams.builder()\n .namespace(\"namespace\")\n .title(\"title\")\n .slug(\"slug\")\n .document(\"document\")\n .build()\nval rule = client.rules().createRuleset(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.create_ruleset(\"smoke-test\", { title: \"title\", description: \"description\", slug: \"slug\", is_private: \"is_private\", document: \"document\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleCreateRulesetParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleCreateRulesetParams params = RuleCreateRulesetParams.builder()\n .namespace(\"namespace\")\n .title(\"title\")\n .slug(\"slug\")\n .document(\"document\")\n .build();\nvar rule = client.rules().createRuleset(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules create-ruleset 'namespace' --bearer-auth \"$BEARER_AUTH\" --title 'title' --slug 'slug' --document 'document'"
+ }
+ ]
+ }
+ },
+ "/v1/rulesets/{namespace}/{slug}": {
+ "patch": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "Update rule metadata by slug.",
+ "summary": "Update rule metadata",
+ "operationId": "updateRuleset",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "namespace": {
+ "type": "string"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "isPrivate": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.rules.updateRuleset(\"slug\", {\n namespace: \"namespace\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules update-ruleset 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.update_ruleset(\n namespace=\"namespace\",\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.UpdateRuleset(context.Background(), \"namespace\", \"slug\", sdk.RuleUpdateRulesetParams{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleUpdateRulesetParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleUpdateRulesetParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval rule = client.rules().updateRuleset(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.update_ruleset(\"smoke-test\", { namespace: \"namespace\", namespace_2: \"namespace_2\", slug_2: \"slug_2\", title: \"title\", description: \"description\", is_private: \"is_private\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleUpdateRulesetParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleUpdateRulesetParams params = RuleUpdateRulesetParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar rule = client.rules().updateRuleset(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules update-ruleset 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "Delete a rule by slug.",
+ "summary": "Delete a rule",
+ "operationId": "deleteRuleset",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.rules.deleteRuleset(\"slug\", {\n namespace: \"namespace\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules delete-ruleset 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.delete_ruleset(\n namespace=\"namespace\",\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.DeleteRuleset(context.Background(), \"namespace\", \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleDeleteRulesetParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleDeleteRulesetParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval rule = client.rules().deleteRuleset(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.delete_ruleset(\"smoke-test\", { namespace: \"namespace\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleDeleteRulesetParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleDeleteRulesetParams params = RuleDeleteRulesetParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar rule = client.rules().deleteRuleset(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules delete-ruleset 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ },
+ "get": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "Get a rule document by slug.",
+ "summary": "Get a rule",
+ "operationId": "getRulesetDocument",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst string_ = await client.rules.retrieveRulesetDocument(\"slug\", {\n namespace: \"namespace\",\n});\nconsole.log(string_);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules retrieve-ruleset-document 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.retrieve_ruleset_document(\n namespace=\"namespace\",\n slug=\"slug\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.GetRulesetDocument(context.Background(), \"namespace\", \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleRetrieveRulesetDocumentParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleRetrieveRulesetDocumentParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build()\nval rule = client.rules().retrieveRulesetDocument(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.retrieve_ruleset_document(\"smoke-test\", { namespace: \"namespace\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleRetrieveRulesetDocumentParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleRetrieveRulesetDocumentParams params = RuleRetrieveRulesetDocumentParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .build();\nvar rule = client.rules().retrieveRulesetDocument(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules retrieve-ruleset-document 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace'"
+ }
+ ]
+ }
+ },
+ "/v1/rulesets/{namespace}/{slug}/access-group": {
+ "post": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "Grant an access group to a rule.",
+ "summary": "Add rule access group",
+ "operationId": "addRulesetAccessGroup",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/access-group"
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.rules.createRulesetAccessGroup(\"slug\", {\n namespace: \"namespace\",\n accessGroupSlug: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules create-ruleset-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.create_ruleset_access_group(\n namespace=\"namespace\",\n slug=\"slug\",\n access_group_slug=\"\",\n idempotency_key=\"\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.NewRulesetAccessGroup(context.Background(), \"namespace\", \"slug\", sdk.RuleNewRulesetAccessGroupParams{\n\t\tAccessGroup: sdk.AccessGroup{\n\t\tAccessGroupSlug: \"\",\n\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleCreateRulesetAccessGroupParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleCreateRulesetAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build()\nval rule = client.rules().createRulesetAccessGroup(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.create_ruleset_access_group(\"smoke-test\", { namespace: \"namespace\", access_group_slug: \"access_group_slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleCreateRulesetAccessGroupParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleCreateRulesetAccessGroupParams params = RuleCreateRulesetAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build();\nvar rule = client.rules().createRulesetAccessGroup(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules create-ruleset-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Rules"
+ ],
+ "description": "Remove an access group from a rule.",
+ "summary": "Remove rule access group",
+ "operationId": "removeRulesetAccessGroup",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/access-group"
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "namespace",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.rules.deleteRulesetAccessGroup(\"slug\", {\n namespace: \"namespace\",\n accessGroupSlug: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi rules delete-ruleset-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nrule = client.rules.delete_ruleset_access_group(\n namespace=\"namespace\",\n slug=\"slug\",\n access_group_slug=\"\",\n idempotency_key=\"\",\n)\nprint(rule)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\trule, err := client.Rules.DeleteRulesetAccessGroup(context.Background(), \"namespace\", \"slug\", sdk.RuleDeleteRulesetAccessGroupParams{\n\t\tAccessGroup: sdk.AccessGroup{\n\t\tAccessGroupSlug: \"\",\n\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(rule)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.rules.RuleDeleteRulesetAccessGroupParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = RuleDeleteRulesetAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build()\nval rule = client.rules().deleteRulesetAccessGroup(params)\nprintln(rule)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.rules.delete_ruleset_access_group(\"smoke-test\", { namespace: \"namespace\", access_group_slug: \"access_group_slug\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.rules.RuleDeleteRulesetAccessGroupParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nRuleDeleteRulesetAccessGroupParams params = RuleDeleteRulesetAccessGroupParams.builder()\n .namespace(\"namespace\")\n .slug(\"slug\")\n .accessGroupSlug(\"accessGroupSlug\")\n .build();\nvar rule = client.rules().deleteRulesetAccessGroup(params);\nSystem.out.println(rule);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi rules delete-ruleset-access-group 'slug' --bearer-auth \"$BEARER_AUTH\" --namespace 'namespace' --access-group-slug 'accessGroupSlug'"
+ }
+ ]
+ }
+ },
+ "/v1/themes": {
+ "get": {
+ "tags": [
+ "Themes"
+ ],
+ "description": "List all team themes.",
+ "summary": "List all themes",
+ "operationId": "listThemes",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/theme"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst list = await client.themes.list();\nconsole.log(list);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi themes list --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\ntheme = client.themes.list()\nprint(theme)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\ttheme, err := client.Themes.List(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(theme)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.themes.ThemeListParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval theme = client.themes().list(ThemeListParams.none())\nprintln(theme)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.themes.list\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.themes.ThemeListParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar theme = client.themes().list();\nSystem.out.println(theme);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi themes list --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "Themes"
+ ],
+ "description": "Create a team theme.",
+ "summary": "Create a theme",
+ "operationId": "createTheme",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/uid"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "slug": {
+ "type": "string"
+ },
+ "document": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "slug",
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst uID = await client.themes.create({\n name: \"\",\n slug: \"\",\n document: \"\",\n});\nconsole.log(uID);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi themes create --bearer-auth \"$BEARER_AUTH\" --name 'name' --slug 'slug' --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\ntheme = client.themes.create(\n name=\"\",\n slug=\"\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(theme)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\ttheme, err := client.Themes.New(context.Background(), sdk.ThemeNewParams{\n\t\tDocument: \"\",\n\t\tName: \"\",\n\t\tSlug: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(theme)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.themes.ThemeCreateParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ThemeCreateParams.builder()\n .name(\"name\")\n .slug(\"slug\")\n .document(\"document\")\n .build()\nval theme = client.themes().create(params)\nprintln(theme)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.themes.create({ name: \"name\", description: \"description\", slug: \"slug\", document: \"document\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.themes.ThemeCreateParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nThemeCreateParams params = ThemeCreateParams.builder()\n .name(\"name\")\n .slug(\"slug\")\n .document(\"document\")\n .build();\nvar theme = client.themes().create(params);\nSystem.out.println(theme);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi themes create --bearer-auth \"$BEARER_AUTH\" --name 'name' --slug 'slug' --document 'document'"
+ }
+ ]
+ }
+ },
+ "/v1/themes/{slug}": {
+ "patch": {
+ "tags": [
+ "Themes"
+ ],
+ "description": "Update theme metadata.",
+ "summary": "Update theme metadata",
+ "operationId": "updateTheme",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.themes.update(\"slug\", {});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi themes update 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\ntheme = client.themes.update(\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(theme)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\ttheme, err := client.Themes.Update(context.Background(), \"slug\", sdk.ThemeUpdateParams{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(theme)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.themes.ThemeUpdateParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ThemeUpdateParams.builder()\n .slug(\"slug\")\n .build()\nval theme = client.themes().update(params)\nprintln(theme)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.themes.update(\"smoke-test\", { name: \"name\", description: \"description\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.themes.ThemeUpdateParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nThemeUpdateParams params = ThemeUpdateParams.builder()\n .slug(\"slug\")\n .build();\nvar theme = client.themes().update(params);\nSystem.out.println(theme);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi themes update 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "put": {
+ "tags": [
+ "Themes"
+ ],
+ "description": "Replace the theme document.",
+ "summary": "Update theme document",
+ "operationId": "replaceThemeDocument",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "document": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "document"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.themes.replaceDocument(\"slug\", {\n document: \"\",\n});"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi themes replace-document 'slug' --bearer-auth \"$BEARER_AUTH\" --document 'document'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\ntheme = client.themes.replace_document(\n slug=\"slug\",\n document=\"\",\n idempotency_key=\"\",\n)\nprint(theme)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\ttheme, err := client.Themes.ReplaceDocument(context.Background(), \"slug\", sdk.ThemeReplaceDocumentParams{\n\t\tDocument: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(theme)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.themes.ThemeReplaceDocumentParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ThemeReplaceDocumentParams.builder()\n .slug(\"slug\")\n .document(\"document\")\n .build()\nval theme = client.themes().replaceDocument(params)\nprintln(theme)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.themes.replace_document(\"smoke-test\", { document: \"document\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.themes.ThemeReplaceDocumentParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nThemeReplaceDocumentParams params = ThemeReplaceDocumentParams.builder()\n .slug(\"slug\")\n .document(\"document\")\n .build();\nvar theme = client.themes().replaceDocument(params);\nSystem.out.println(theme);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi themes replace-document 'slug' --bearer-auth \"$BEARER_AUTH\" --document 'document'"
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "Themes"
+ ],
+ "description": "Delete a theme by slug.",
+ "summary": "Delete a theme",
+ "operationId": "deleteTheme",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "null"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nawait client.themes.delete(\"slug\");"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi themes delete 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\ntheme = client.themes.delete(\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(theme)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\ttheme, err := client.Themes.Delete(context.Background(), \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(theme)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.themes.ThemeDeleteParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ThemeDeleteParams.builder()\n .slug(\"slug\")\n .build()\nval theme = client.themes().delete(params)\nprintln(theme)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.themes.delete(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.themes.ThemeDeleteParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nThemeDeleteParams params = ThemeDeleteParams.builder()\n .slug(\"slug\")\n .build();\nvar theme = client.themes().delete(params);\nSystem.out.println(theme);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi themes delete 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "get": {
+ "tags": [
+ "Themes"
+ ],
+ "description": "Get the theme document by slug.",
+ "summary": "Get a theme",
+ "operationId": "getTheme",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst string_ = await client.themes.retrieve(\"slug\");\nconsole.log(string_);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi themes retrieve 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\ntheme = client.themes.retrieve(\n slug=\"slug\",\n)\nprint(theme)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\ttheme, err := client.Themes.Get(context.Background(), \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(theme)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.themes.ThemeRetrieveParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ThemeRetrieveParams.builder()\n .slug(\"slug\")\n .build()\nval theme = client.themes().retrieve(params)\nprintln(theme)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.themes.retrieve(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.themes.ThemeRetrieveParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nThemeRetrieveParams params = ThemeRetrieveParams.builder()\n .slug(\"slug\")\n .build();\nvar theme = client.themes().retrieve(params);\nSystem.out.println(theme);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi themes retrieve 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/teams": {
+ "get": {
+ "tags": [
+ "Teams"
+ ],
+ "description": "List all available teams",
+ "summary": "List teams",
+ "operationId": "listTeams",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/team"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst list = await client.teams.list();\nconsole.log(list);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi teams list --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nteam = client.teams.list()\nprint(team)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tteam, err := client.Teams.List(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(team)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.teams.TeamListParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval team = client.teams().list(TeamListParams.none())\nprintln(team)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.teams.list\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.teams.TeamListParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar team = client.teams().list();\nSystem.out.println(team);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi teams list --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/guides": {
+ "get": {
+ "tags": [
+ "Scalar Docs"
+ ],
+ "description": "List all guide projects.",
+ "summary": "List all projects",
+ "operationId": "listGuides",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/github-project"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst listGuides = await client.scalarDocs.listGuides();\nconsole.log(listGuides);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi scalar-docs list-guides --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nscalar_doc = client.scalar_docs.list_guides()\nprint(scalar_doc)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tscalarDoc, err := client.ScalarDocs.ListGuides(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(scalarDoc)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.scalardocs.ScalarDocListGuidesParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval scalarDoc = client.scalarDocs().listGuides(ScalarDocListGuidesParams.none())\nprintln(scalarDoc)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.scalarDocs.list_guides\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.scalardocs.ScalarDocListGuidesParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar scalarDoc = client.scalarDocs().listGuides();\nSystem.out.println(scalarDoc);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi scalar-docs list-guides --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "Scalar Docs"
+ ],
+ "description": "Create a guide project.",
+ "summary": "Create a project",
+ "operationId": "createGuide",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "uid": {
+ "type": "string"
+ },
+ "slug": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "uid",
+ "slug"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "slug": {
+ "$ref": "#/components/schemas/slug"
+ },
+ "isPrivate": {
+ "default": false,
+ "type": "boolean"
+ },
+ "allowedUsers": {
+ "default": [],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allowedDomains": {
+ "default": [],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [
+ "name",
+ "isPrivate",
+ "allowedUsers",
+ "allowedDomains"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst createGuide = await client.scalarDocs.createGuide({\n name: \"\",\n isPrivate: false,\n allowedUsers: [],\n allowedDomains: [],\n});\nconsole.log(createGuide);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi scalar-docs create-guide --bearer-auth \"$BEARER_AUTH\" --name 'name' --is-private"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nscalar_doc = client.scalar_docs.create_guide(\n name=\"\",\n is_private=False,\n allowed_users=[],\n allowed_domains=[],\n idempotency_key=\"\",\n)\nprint(scalar_doc)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tscalarDoc, err := client.ScalarDocs.NewGuide(context.Background(), sdk.ScalarDocNewGuideParams{\n\t\tAllowedDomains: []string{\"\"},\n\t\tAllowedUsers: []string{\"\"},\n\t\tIsPrivate: false,\n\t\tName: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(scalarDoc)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.scalardocs.ScalarDocCreateGuideParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ScalarDocCreateGuideParams.builder()\n .name(\"name\")\n .isPrivate(false)\n .allowedUsers(listOf(\"allowedUser\"))\n .allowedDomains(listOf(\"allowedDomain\"))\n .build()\nval scalarDoc = client.scalarDocs().createGuide(params)\nprintln(scalarDoc)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.scalarDocs.create_guide({ name: \"name\", slug: \"slug\", is_private: \"is_private\", allowed_users: \"allowed_users\", allowed_domains: \"allowed_domains\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.scalardocs.ScalarDocCreateGuideParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nScalarDocCreateGuideParams params = ScalarDocCreateGuideParams.builder()\n .name(\"name\")\n .isPrivate(false)\n .allowedUsers(java.util.List.of(\"allowedUser\"))\n .allowedDomains(java.util.List.of(\"allowedDomain\"))\n .build();\nvar scalarDoc = client.scalarDocs().createGuide(params);\nSystem.out.println(scalarDoc);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi scalar-docs create-guide --bearer-auth \"$BEARER_AUTH\" --name 'name' --is-private"
+ }
+ ]
+ }
+ },
+ "/v1/guides/{slug}/publish": {
+ "post": {
+ "tags": [
+ "Scalar Docs"
+ ],
+ "description": "Start a new publish process.",
+ "summary": "Publish a project",
+ "operationId": "publishGuide",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "publishUid": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "publishUid"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "in": "path",
+ "name": "slug",
+ "required": true
+ }
+ ],
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst publishGuide = await client.scalarDocs.publishGuide(\"slug\");\nconsole.log(publishGuide);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi scalar-docs publish-guide 'slug' --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nscalar_doc = client.scalar_docs.publish_guide(\n slug=\"slug\",\n idempotency_key=\"\",\n)\nprint(scalar_doc)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tscalarDoc, err := client.ScalarDocs.PublishGuide(context.Background(), \"slug\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(scalarDoc)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.scalardocs.ScalarDocPublishGuideParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = ScalarDocPublishGuideParams.builder()\n .slug(\"slug\")\n .build()\nval scalarDoc = client.scalarDocs().publishGuide(params)\nprintln(scalarDoc)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.scalarDocs.publish_guide(\"smoke-test\")\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.scalardocs.ScalarDocPublishGuideParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nScalarDocPublishGuideParams params = ScalarDocPublishGuideParams.builder()\n .slug(\"slug\")\n .build();\nvar scalarDoc = client.scalarDocs().publishGuide(params);\nSystem.out.println(scalarDoc);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi scalar-docs publish-guide 'slug' --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/namespaces": {
+ "get": {
+ "tags": [
+ "Namespaces"
+ ],
+ "description": "Get all namespaces for the current team",
+ "summary": "List namespaces",
+ "operationId": "listNamespaces",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst list = await client.namespaces.list();\nconsole.log(list);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi namespaces list --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nnamespace = client.namespaces.list()\nprint(namespace)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tnamespace, err := client.Namespaces.List(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(namespace)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.namespaces.NamespaceListParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval namespace = client.namespaces().list(NamespaceListParams.none())\nprintln(namespace)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.namespace(\"namespace\").list\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.namespaces.NamespaceListParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar namespace = client.namespaces().list();\nSystem.out.println(namespace);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi namespaces list --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ },
+ "/v1/auth/exchange": {
+ "post": {
+ "tags": [
+ "Authentication"
+ ],
+ "description": "Exchange an API key for an access token.",
+ "summary": "Exchange token",
+ "operationId": "exchangePersonalToken",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "accessToken": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "accessToken"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "security": [],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "personalToken": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "personalToken"
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "required": true
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst exchangePersonalToken = await client.authentication.exchangePersonalToken({\n personalToken: \"\",\n});\nconsole.log(exchangePersonalToken);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi authentication exchange-personal-token --bearer-auth \"$BEARER_AUTH\" --personal-token 'personalToken'"
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nauthentication = client.authentication.exchange_personal_token(\n personal_token=\"\",\n idempotency_key=\"\",\n)\nprint(authentication)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tauthentication, err := client.Authentication.ExchangePersonalToken(context.Background(), sdk.AuthenticationExchangePersonalTokenParams{\n\t\tPersonalToken: \"\",\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(authentication)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.authentication.AuthenticationExchangePersonalTokenParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval params = AuthenticationExchangePersonalTokenParams.builder()\n .personalToken(\"personalToken\")\n .build()\nval authentication = client.authentication().exchangePersonalToken(params)\nprintln(authentication)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.authentication.exchange_personal_token({ personal_token: \"personal_token\" })\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.authentication.AuthenticationExchangePersonalTokenParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nAuthenticationExchangePersonalTokenParams params = AuthenticationExchangePersonalTokenParams.builder()\n .personalToken(\"personalToken\")\n .build();\nvar authentication = client.authentication().exchangePersonalToken(params);\nSystem.out.println(authentication);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi authentication exchange-personal-token --bearer-auth \"$BEARER_AUTH\" --personal-token 'personalToken'"
+ }
+ ]
+ }
+ },
+ "/v1/auth/me": {
+ "get": {
+ "tags": [
+ "Authentication"
+ ],
+ "description": "Get the authenticated user, including their available teams and theme.",
+ "summary": "Get current user",
+ "operationId": "getCurrentUser",
+ "responses": {
+ "200": {
+ "description": "Default Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/user"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/400"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "No auth",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/401"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/403"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/404"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Invalid payload",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/422"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Uncaught error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/500"
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "label": "TypeScript",
+ "lang": "TypeScript",
+ "source": "import ScalarAPI from \"@scalar/sdk\";\n\nconst client = new ScalarAPI({\n bearerAuth: process.env[\"BEARER_AUTH\"], // defaults to the BEARER_AUTH env var\n environment: \"production\",\n});\n\nconst user = await client.authentication.listCurrentUser();\nconsole.log(user);"
+ },
+ {
+ "label": "Shell",
+ "lang": "Shell",
+ "source": "scalarapi authentication list-current-user --bearer-auth \"$BEARER_AUTH\""
+ },
+ {
+ "label": "Python",
+ "lang": "Python",
+ "source": "import os\n\nfrom scalar_api import ScalarApi\n\nclient = ScalarApi(\n bearer_auth=os.environ.get(\"BEARER_AUTH\"),\n)\n\nauthentication = client.authentication.list_current_user()\nprint(authentication)"
+ },
+ {
+ "label": "Go",
+ "lang": "Go",
+ "source": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tsdk \"scalar-api\"\n\t\"scalar-api/option\"\n)\n\nfunc main() {\n\tclient := sdk.NewClient(\n\t\toption.WithBearerAuth(os.Getenv(\"BEARER_AUTH\")),\n\t)\n\n\tauthentication, err := client.Authentication.ListCurrentUser(context.Background())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(authentication)\n}"
+ },
+ {
+ "label": "Kotlin",
+ "lang": "Kotlin",
+ "source": "import com.scalar.api.client.ScalarApiClient\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient\nimport com.scalar.api.models.authentication.AuthenticationListCurrentUserParams\n\nval client: ScalarApiClient = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build()\n\nval authentication = client.authentication().listCurrentUser(AuthenticationListCurrentUserParams.none())\nprintln(authentication)"
+ },
+ {
+ "label": "Ruby",
+ "lang": "Ruby",
+ "source": "require \"json\"\nrequire \"scalar-api\"\n\nclient = ScalarApi::Client.new(\n bearer_auth: ENV[\"BEARER_AUTH\"],\n)\n\nresponse = client.authentication.list_current_user\nputs response.inspect"
+ },
+ {
+ "label": "Java",
+ "lang": "Java",
+ "source": "import com.scalar.api.client.ScalarApiClient;\nimport com.scalar.api.client.okhttp.ScalarApiOkHttpClient;\nimport com.scalar.api.models.authentication.AuthenticationListCurrentUserParams;\n\nScalarApiClient client = ScalarApiOkHttpClient.builder()\n .bearerAuth(System.getenv(\"BEARER_AUTH\"))\n .build();\n\nvar authentication = client.authentication().listCurrentUser();\nSystem.out.println(authentication);"
+ },
+ {
+ "lang": "Shell",
+ "label": "CLI",
+ "source": "scalarapi authentication list-current-user --bearer-auth \"$BEARER_AUTH\""
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..10b2754
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,25 @@
+[project]
+name = "scalarApi"
+version = "0.1.9"
+description = "API for managing Scalar platform resources.\n\n## TypeScript SDK\n\nFor TypeScript, we provide a SDK that makes using our API even easier.\n\n### Install\n\n```bash\nnpm add @scalar/sdk\n```\n\n### Get a Scalar API key\n\nCreate an API key in your Scalar account:\n\n- Dashboard: https://dashboard.scalar.com/account\n- Store it in `.env`, for example:\n\n```bash\nSCALAR_API_KEY=your_personal_token\n```\n\n### Exchange your API key for an access token\n\nThe personal token is not an access token. Exchange it first with `postv1AuthExchange`.\n\nIf you use the personal token directly for authenticated API calls, the API returns `401 Invalid authentication token`.\n\n```ts\nimport { Scalar } from '@scalar/sdk'\n\nconst scalar = new Scalar()\n\nconst exchange = await scalar.auth.postv1AuthExchange({\n personalToken: process.env.SCALAR_API_KEY!,\n})\n\nconst accessToken = exchange.accessToken\n```\n\n### Use the access token\n\nConstruct a second client with bearer auth. Use this authenticated client for API calls.\n\n```ts\nimport { Scalar } from '@scalar/sdk'\n\nconst scalar = new Scalar()\n\nconst exchange = await scalar.auth.postv1AuthExchange({\n personalToken: process.env.SCALAR_API_KEY!,\n})\n\nconst authedScalar = new Scalar({\n bearerAuth: exchange.accessToken,\n})\n```\n\n### Notes\n\n- The exchange request itself can be made from a client constructed with no arguments (`new Scalar()`).\n- The exchanged access token is valid for 12 hours.\n- Timestamps are Unix seconds.\n\n### Read more\n\n- [@scalar/sdk on npm](https://www.npmjs.com/package/@scalar/sdk)"
+license = "MIT"
+requires-python = ">= 3.9"
+dependencies = [
+ "httpx>=0.23.0, <1",
+ "pydantic>=1.9.0, <3",
+ "typing-extensions>=4.14, <5",
+ "anyio>=3.5.0, <5",
+ "distro>=1.7.0, <2",
+ "sniffio",
+]
+
+
+[build-system]
+requires = ["hatchling>=1.18.0"]
+build-backend = "hatchling.build"
+
+[tool.hatch.build.targets.wheel]
+packages = ["src"]
+
+[tool.hatch.build.targets.wheel.sources]
+"src" = "scalar_api"
diff --git a/release-please-config.json b/release-please-config.json
new file mode 100644
index 0000000..eb6c26e
--- /dev/null
+++ b/release-please-config.json
@@ -0,0 +1,8 @@
+{
+ "packages": {
+ ".": {
+ "package-name": "scalarApi",
+ "release-type": "python"
+ }
+ }
+}
diff --git a/scalar-sdk.manifest.json b/scalar-sdk.manifest.json
new file mode 100644
index 0000000..8c10067
--- /dev/null
+++ b/scalar-sdk.manifest.json
@@ -0,0 +1,9519 @@
+{
+ "name": "ScalarApi",
+ "slug": "scalarApi",
+ "version": "0.2.0",
+ "servers": [
+ "https://access.scalar.com"
+ ],
+ "environments": {
+ "production": "https://access.scalar.com",
+ "local": "http://127.0.0.1:4010"
+ },
+ "environmentOrder": [
+ "production",
+ "local"
+ ],
+ "auth": [
+ "bearer"
+ ],
+ "authDetails": [
+ {
+ "kind": "bearer",
+ "id": "BearerAuth",
+ "bearerFormat": "JWT"
+ }
+ ],
+ "clientHeaderParams": [],
+ "schemas": [
+ {
+ "name": "_400",
+ "source": "_400",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "code",
+ "publicName": "code",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "_401",
+ "source": "_401",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "code",
+ "publicName": "code",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "_403",
+ "source": "_403",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "code",
+ "publicName": "code",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "_404",
+ "source": "_404",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "code",
+ "publicName": "code",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "_422",
+ "source": "_422",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "code",
+ "publicName": "code",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "_500",
+ "source": "_500",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "code",
+ "publicName": "code",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "ApiDocument",
+ "source": "ApiDocument",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "version",
+ "publicName": "version",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Version"
+ }
+ },
+ {
+ "name": "title",
+ "publicName": "title",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ },
+ {
+ "name": "description",
+ "publicName": "description",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "namespace",
+ "publicName": "namespace",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Namespace"
+ }
+ },
+ {
+ "name": "isPrivate",
+ "publicName": "isPrivate",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "tags",
+ "publicName": "tags",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "versions",
+ "publicName": "versions",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "array",
+ "items": {
+ "kind": "ref",
+ "name": "ManagedDocVersion"
+ }
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Nanoid",
+ "source": "Nanoid",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "minLength": 5
+ }
+ }
+ },
+ {
+ "name": "Version",
+ "source": "Version",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "minLength": 1
+ }
+ }
+ },
+ {
+ "name": "Slug",
+ "source": "Slug",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "pattern": "^[a-z](?:[a-z0-9-]*[a-z0-9])?$",
+ "minLength": 3,
+ "maxLength": 60
+ }
+ }
+ },
+ {
+ "name": "Namespace",
+ "source": "Namespace",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "pattern": "^[a-zA-Z0-9-_]+$",
+ "minLength": 3,
+ "maxLength": 50
+ }
+ }
+ },
+ {
+ "name": "ManagedDocVersion",
+ "source": "ManagedDocVersion",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "createdAt",
+ "publicName": "createdAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "number"
+ }
+ },
+ {
+ "name": "version",
+ "publicName": "version",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Version"
+ }
+ },
+ {
+ "name": "upgraded",
+ "publicName": "upgraded",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "embedStatus",
+ "publicName": "embedStatus",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "union",
+ "variants": [
+ {
+ "kind": "enum",
+ "values": [
+ "complete",
+ "failed"
+ ],
+ "names": [
+ "Complete",
+ "Failed"
+ ],
+ "deprecations": [
+ false,
+ false
+ ]
+ },
+ {
+ "kind": "null"
+ }
+ ]
+ }
+ },
+ {
+ "name": "tags",
+ "publicName": "tags",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "array",
+ "items": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ },
+ {
+ "name": "tools",
+ "publicName": "tools",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "array",
+ "items": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "path",
+ "publicName": "path",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "method",
+ "publicName": "method",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Method"
+ }
+ },
+ {
+ "name": "enabledTools",
+ "publicName": "enabledTools",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "array",
+ "items": {
+ "kind": "enum",
+ "values": [
+ "execute-request",
+ "get-mini-openapi-spec"
+ ],
+ "names": [
+ "ExecuteRequest",
+ "GetMiniOpenapiSpec"
+ ],
+ "deprecations": [
+ false,
+ false
+ ]
+ }
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ }
+ },
+ {
+ "name": "yamlSha",
+ "publicName": "yamlSha",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "jsonSha",
+ "publicName": "jsonSha",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "versionSha",
+ "publicName": "versionSha",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Method",
+ "source": "Method",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "enum",
+ "values": [
+ "delete",
+ "get",
+ "head",
+ "options",
+ "patch",
+ "post",
+ "put",
+ "trace"
+ ],
+ "names": [
+ "Delete",
+ "Get",
+ "Head",
+ "Options",
+ "Patch",
+ "Post",
+ "Put",
+ "Trace"
+ ],
+ "deprecations": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false
+ ]
+ }
+ },
+ {
+ "name": "AccessGroup",
+ "source": "AccessGroup",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "accessGroupSlug",
+ "publicName": "accessGroupSlug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Schema",
+ "source": "Schema",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "title",
+ "publicName": "title",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "description",
+ "publicName": "description",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ },
+ {
+ "name": "namespace",
+ "publicName": "namespace",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Namespace"
+ }
+ },
+ {
+ "name": "isPrivate",
+ "publicName": "isPrivate",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "versions",
+ "publicName": "versions",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "array",
+ "items": {
+ "kind": "ref",
+ "name": "ManagedSchemaVersion"
+ }
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "ManagedSchemaVersion",
+ "source": "ManagedSchemaVersion",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "createdAt",
+ "publicName": "createdAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ },
+ {
+ "name": "updatedAt",
+ "publicName": "updatedAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ },
+ {
+ "name": "version",
+ "publicName": "version",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Version"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Timestamp",
+ "source": "Timestamp",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "integer",
+ "validation": {}
+ }
+ },
+ {
+ "name": "Uid",
+ "source": "Uid",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "LoginPortalEmail",
+ "source": "LoginPortalEmail",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "logo",
+ "publicName": "logo",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "logoSize",
+ "publicName": "logoSize",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "buttonText",
+ "publicName": "buttonText",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 50
+ }
+ }
+ },
+ {
+ "name": "message",
+ "publicName": "message",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 1000
+ }
+ }
+ },
+ {
+ "name": "title",
+ "publicName": "title",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "mainColor",
+ "publicName": "mainColor",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "mainBackground",
+ "publicName": "mainBackground",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "cardColor",
+ "publicName": "cardColor",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "cardBackground",
+ "publicName": "cardBackground",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "buttonColor",
+ "publicName": "buttonColor",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "buttonBackground",
+ "publicName": "buttonBackground",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "LoginPortalPage",
+ "source": "LoginPortalPage",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "title",
+ "publicName": "title",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "description",
+ "publicName": "description",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 500
+ }
+ }
+ },
+ {
+ "name": "head",
+ "publicName": "head",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "script",
+ "publicName": "script",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "theme",
+ "publicName": "theme",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "companyName",
+ "publicName": "companyName",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "logo",
+ "publicName": "logo",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "logoURL",
+ "publicName": "logoURL",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "favicon",
+ "publicName": "favicon",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "termsLink",
+ "publicName": "termsLink",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "privacyLink",
+ "publicName": "privacyLink",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "formTitle",
+ "publicName": "formTitle",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "formDescription",
+ "publicName": "formDescription",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 500
+ }
+ }
+ },
+ {
+ "name": "formImage",
+ "publicName": "formImage",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "LoginPortal",
+ "source": "LoginPortal",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "title",
+ "publicName": "title",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 200
+ }
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Rule",
+ "source": "Rule",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "title",
+ "publicName": "title",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "maxLength": 100
+ }
+ }
+ },
+ {
+ "name": "description",
+ "publicName": "description",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ },
+ {
+ "name": "namespace",
+ "publicName": "namespace",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Namespace"
+ }
+ },
+ {
+ "name": "isPrivate",
+ "publicName": "isPrivate",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Theme",
+ "source": "Theme",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "name",
+ "publicName": "name",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "description",
+ "publicName": "description",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Team",
+ "source": "Team",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "name",
+ "publicName": "name",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "TeamName"
+ }
+ },
+ {
+ "name": "imageUri",
+ "publicName": "imageUri",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "TeamImage"
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ },
+ {
+ "name": "theme",
+ "publicName": "theme",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "TeamName",
+ "source": "TeamName",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "TeamImage",
+ "source": "TeamImage",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "GithubProject",
+ "source": "GithubProject",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "createdAt",
+ "publicName": "createdAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ },
+ {
+ "name": "updatedAt",
+ "publicName": "updatedAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ },
+ {
+ "name": "name",
+ "publicName": "name",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "activeDeployment",
+ "publicName": "activeDeployment",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "union",
+ "variants": [
+ {
+ "kind": "ref",
+ "name": "ActiveDeployment"
+ },
+ {
+ "kind": "null"
+ }
+ ]
+ }
+ },
+ {
+ "name": "lastPublished",
+ "publicName": "lastPublished",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "union",
+ "variants": [
+ {
+ "kind": "ref",
+ "name": "Timestamp"
+ },
+ {
+ "kind": "null"
+ }
+ ]
+ }
+ },
+ {
+ "name": "lastPublishedUid",
+ "publicName": "lastPublishedUid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "union",
+ "variants": [
+ {
+ "kind": "primitive",
+ "type": "string"
+ },
+ {
+ "kind": "null"
+ }
+ ]
+ }
+ },
+ {
+ "name": "loginPortalUid",
+ "publicName": "loginPortalUid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "activeThemeId",
+ "publicName": "activeThemeId",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "typesenseId",
+ "publicName": "typesenseId",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "number"
+ }
+ },
+ {
+ "name": "isPrivate",
+ "publicName": "isPrivate",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "agentEnabled",
+ "publicName": "agentEnabled",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "accessGroups",
+ "publicName": "accessGroups",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "slug",
+ "publicName": "slug",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Slug"
+ }
+ },
+ {
+ "name": "publishStatus",
+ "publicName": "publishStatus",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "publishMessage",
+ "publicName": "publishMessage",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "repository",
+ "publicName": "repository",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "union",
+ "variants": [
+ {
+ "kind": "ref",
+ "name": "GithubProjectRepository"
+ },
+ {
+ "kind": "null"
+ }
+ ]
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "ActiveDeployment",
+ "source": "ActiveDeployment",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "domain",
+ "publicName": "domain",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "publishedAt",
+ "publicName": "publishedAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "GithubProjectRepository",
+ "source": "GithubProjectRepository",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "linkedBy",
+ "publicName": "linkedBy",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "id",
+ "publicName": "id",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "number"
+ }
+ },
+ {
+ "name": "name",
+ "publicName": "name",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "validation": {
+ "minLength": 2
+ }
+ }
+ },
+ {
+ "name": "configPath",
+ "publicName": "configPath",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "branch",
+ "publicName": "branch",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "publishOnMerge",
+ "publicName": "publishOnMerge",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "publishPreviews",
+ "publicName": "publishPreviews",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "prComments",
+ "publicName": "prComments",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "expired",
+ "publicName": "expired",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "Email",
+ "source": "Email",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string",
+ "format": "email",
+ "validation": {
+ "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
+ }
+ }
+ },
+ {
+ "name": "TeamSummary",
+ "source": "TeamSummary",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "name",
+ "publicName": "name",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "TeamName"
+ }
+ },
+ {
+ "name": "imageUri",
+ "publicName": "imageUri",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "TeamImage"
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ },
+ {
+ "name": "User",
+ "source": "User",
+ "publicAliases": [],
+ "deprecated": false,
+ "type": {
+ "kind": "object",
+ "properties": [
+ {
+ "name": "uid",
+ "publicName": "uid",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Nanoid"
+ }
+ },
+ {
+ "name": "createdAt",
+ "publicName": "createdAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ },
+ {
+ "name": "updatedAt",
+ "publicName": "updatedAt",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Timestamp"
+ }
+ },
+ {
+ "name": "email",
+ "publicName": "email",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "ref",
+ "name": "Email"
+ }
+ },
+ {
+ "name": "theme",
+ "publicName": "theme",
+ "required": false,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "string"
+ }
+ },
+ {
+ "name": "activeTeamId",
+ "publicName": "activeTeamId",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "union",
+ "variants": [
+ {
+ "kind": "primitive",
+ "type": "string"
+ },
+ {
+ "kind": "null"
+ }
+ ]
+ }
+ },
+ {
+ "name": "hasGithub",
+ "publicName": "hasGithub",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "primitive",
+ "type": "boolean"
+ }
+ },
+ {
+ "name": "teams",
+ "publicName": "teams",
+ "required": true,
+ "deprecated": false,
+ "type": {
+ "kind": "array",
+ "items": {
+ "kind": "ref",
+ "name": "TeamSummary"
+ }
+ }
+ }
+ ],
+ "additionalProperties": false
+ }
+ }
+ ],
+ "resources": [
+ "registry",
+ "schemas",
+ "schemas.version",
+ "schemas.accessGroup",
+ "loginPortals",
+ "rules",
+ "themes",
+ "teams",
+ "scalarDocs",
+ "namespaces",
+ "authentication"
+ ],
+ "publicResources": [
+ "registry",
+ "schemas",
+ "schemas.version",
+ "schemas.accessGroup",
+ "loginPortals",
+ "rules",
+ "themes",
+ "teams",
+ "scalarDocs",
+ "namespaces",
+ "authentication"
+ ],
+ "operations": [
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "listAllApiDocuments",
+ "publicOperation": "listAllApiDocuments",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/apis",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "listApiDocuments",
+ "publicOperation": "listApiDocuments",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/apis/{namespace}",
+ "pathParams": [
+ "namespace"
+ ],
+ "publicPathParams": [
+ "namespace"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryListApiDocumentsParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "createApiDocument",
+ "publicOperation": "createApiDocument",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/apis/{namespace}",
+ "pathParams": [
+ "namespace"
+ ],
+ "publicPathParams": [
+ "namespace"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title",
+ "description",
+ "version",
+ "slug",
+ "ruleset",
+ "isPrivate",
+ "document"
+ ],
+ "publicBodyParams": [
+ "title",
+ "description",
+ "version",
+ "slug",
+ "ruleset",
+ "isPrivate",
+ "document"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryCreateApiDocumentParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "updateApiDocument",
+ "publicOperation": "updateApiDocument",
+ "deprecated": false,
+ "method": "PATCH",
+ "path": "/v1/apis/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title",
+ "description",
+ "isPrivate",
+ "ruleset"
+ ],
+ "publicBodyParams": [
+ "title",
+ "description",
+ "isPrivate",
+ "ruleset"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryUpdateApiDocumentParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "deleteApiDocument",
+ "publicOperation": "deleteApiDocument",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/apis/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryDeleteApiDocumentParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "retrieveApiDocumentVersion",
+ "publicOperation": "retrieveApiDocumentVersion",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}",
+ "pathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "semver",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryRetrieveApiDocumentVersionParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "text/plain",
+ "encoding": "text",
+ "contents": [
+ {
+ "contentType": "text/plain",
+ "encoding": "text"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "updateApiDocumentVersion",
+ "publicOperation": "updateApiDocumentVersion",
+ "deprecated": false,
+ "method": "PATCH",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}",
+ "pathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "document",
+ "lastKnownVersionSha"
+ ],
+ "publicBodyParams": [
+ "document",
+ "lastKnownVersionSha"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "semver",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryUpdateApiDocumentVersionParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "deleteApiDocumentVersion",
+ "publicOperation": "deleteApiDocumentVersion",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}",
+ "pathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "semver",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryDeleteApiDocumentVersionParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "listApiDocumentVersionMetadata",
+ "publicOperation": "listApiDocumentVersionMetadata",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}/metadata",
+ "pathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "semver",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryListApiDocumentVersionMetadataParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "ManagedDocVersion",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "createApiDocumentVersion",
+ "publicOperation": "createApiDocumentVersion",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/apis/{namespace}/{slug}/version",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "version",
+ "document",
+ "force",
+ "lastKnownVersionSha"
+ ],
+ "publicBodyParams": [
+ "version",
+ "document",
+ "force",
+ "lastKnownVersionSha"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryCreateApiDocumentVersionParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "ManagedDocVersion",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "createApiDocumentAccessGroup",
+ "publicOperation": "createApiDocumentAccessGroup",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/apis/{namespace}/{slug}/access-group",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "accessGroupSlug"
+ ],
+ "publicBodyParams": [
+ "accessGroupSlug"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryCreateApiDocumentAccessGroupParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "registry",
+ "publicResource": "registry",
+ "operation": "deleteApiDocumentAccessGroup",
+ "publicOperation": "deleteApiDocumentAccessGroup",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/apis/{namespace}/{slug}/access-group",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "accessGroupSlug"
+ ],
+ "publicBodyParams": [
+ "accessGroupSlug"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RegistryDeleteApiDocumentAccessGroupParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas",
+ "publicResource": "schemas",
+ "operation": "list",
+ "publicOperation": "list",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/schemas/{namespace}",
+ "pathParams": [
+ "namespace"
+ ],
+ "publicPathParams": [
+ "namespace"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "SchemaListParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas",
+ "publicResource": "schemas",
+ "operation": "create",
+ "publicOperation": "create",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/schemas/{namespace}",
+ "pathParams": [
+ "namespace"
+ ],
+ "publicPathParams": [
+ "namespace"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title",
+ "description",
+ "version",
+ "slug",
+ "isPrivate",
+ "document"
+ ],
+ "publicBodyParams": [
+ "title",
+ "description",
+ "version",
+ "slug",
+ "isPrivate",
+ "document"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "SchemaCreateParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "Uid",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas",
+ "publicResource": "schemas",
+ "operation": "update",
+ "publicOperation": "update",
+ "deprecated": false,
+ "method": "PATCH",
+ "path": "/v1/schemas/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title",
+ "description",
+ "isPrivate"
+ ],
+ "publicBodyParams": [
+ "title",
+ "description",
+ "isPrivate"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "SchemaUpdateParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas",
+ "publicResource": "schemas",
+ "operation": "delete",
+ "publicOperation": "delete",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/schemas/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "SchemaDeleteParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas.version",
+ "publicResource": "schemas.version",
+ "operation": "retrieveSchema",
+ "publicOperation": "retrieveSchema",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/schemas/{namespace}/{slug}/version/{semver}",
+ "pathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "semver",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "VersionRetrieveSchemaParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "text/plain",
+ "encoding": "text",
+ "contents": [
+ {
+ "contentType": "text/plain",
+ "encoding": "text"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas.version",
+ "publicResource": "schemas.version",
+ "operation": "deleteSchema",
+ "publicOperation": "deleteSchema",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/schemas/{namespace}/{slug}/version/{semver}",
+ "pathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug",
+ "semver"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "semver",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "VersionDeleteSchemaParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas.version",
+ "publicResource": "schemas.version",
+ "operation": "createSchema",
+ "publicOperation": "createSchema",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/schemas/{namespace}/{slug}/version",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "version",
+ "document"
+ ],
+ "publicBodyParams": [
+ "version",
+ "document"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "VersionCreateSchemaParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "Uid",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas.accessGroup",
+ "publicResource": "schemas.accessGroup",
+ "operation": "createSchema",
+ "publicOperation": "createSchema",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/schemas/{namespace}/{slug}/access-group",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "accessGroupSlug"
+ ],
+ "publicBodyParams": [
+ "accessGroupSlug"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "AccessGroupCreateSchemaParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "schemas.accessGroup",
+ "publicResource": "schemas.accessGroup",
+ "operation": "deleteSchema",
+ "publicOperation": "deleteSchema",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/schemas/{namespace}/{slug}/access-group",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "accessGroupSlug"
+ ],
+ "publicBodyParams": [
+ "accessGroupSlug"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "AccessGroupDeleteSchemaParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "loginPortals",
+ "publicResource": "loginPortals",
+ "operation": "retrieve",
+ "publicOperation": "retrieve",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/login-portals/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "LoginPortalRetrieveParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "loginPortals",
+ "publicResource": "loginPortals",
+ "operation": "update",
+ "publicOperation": "update",
+ "deprecated": false,
+ "method": "PATCH",
+ "path": "/v1/login-portals/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title"
+ ],
+ "publicBodyParams": [
+ "title"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "LoginPortalUpdateParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "loginPortals",
+ "publicResource": "loginPortals",
+ "operation": "delete",
+ "publicOperation": "delete",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/login-portals/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "LoginPortalDeleteParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "loginPortals",
+ "publicResource": "loginPortals",
+ "operation": "create",
+ "publicOperation": "create",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/login-portals",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title",
+ "slug",
+ "email",
+ "page"
+ ],
+ "publicBodyParams": [
+ "title",
+ "slug",
+ "email",
+ "page"
+ ],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "LoginPortalCreateParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "Uid",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "loginPortals",
+ "publicResource": "loginPortals",
+ "operation": "list",
+ "publicOperation": "list",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/login-portals",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "listRulesets",
+ "publicOperation": "listRulesets",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/rulesets/{namespace}",
+ "pathParams": [
+ "namespace"
+ ],
+ "publicPathParams": [
+ "namespace"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleListRulesetsParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "createRuleset",
+ "publicOperation": "createRuleset",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/rulesets/{namespace}",
+ "pathParams": [
+ "namespace"
+ ],
+ "publicPathParams": [
+ "namespace"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "title",
+ "description",
+ "slug",
+ "isPrivate",
+ "document"
+ ],
+ "publicBodyParams": [
+ "title",
+ "description",
+ "slug",
+ "isPrivate",
+ "document"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleCreateRulesetParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "Uid",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "updateRuleset",
+ "publicOperation": "updateRuleset",
+ "deprecated": false,
+ "method": "PATCH",
+ "path": "/v1/rulesets/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "namespace",
+ "slug",
+ "title",
+ "description",
+ "isPrivate"
+ ],
+ "publicBodyParams": [
+ "namespace",
+ "slug",
+ "title",
+ "description",
+ "isPrivate"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleUpdateRulesetParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "deleteRuleset",
+ "publicOperation": "deleteRuleset",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/rulesets/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleDeleteRulesetParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "retrieveRulesetDocument",
+ "publicOperation": "retrieveRulesetDocument",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/rulesets/{namespace}/{slug}",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleRetrieveRulesetDocumentParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "text/plain",
+ "encoding": "text",
+ "contents": [
+ {
+ "contentType": "text/plain",
+ "encoding": "text"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "createRulesetAccessGroup",
+ "publicOperation": "createRulesetAccessGroup",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/rulesets/{namespace}/{slug}/access-group",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "accessGroupSlug"
+ ],
+ "publicBodyParams": [
+ "accessGroupSlug"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleCreateRulesetAccessGroupParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "rules",
+ "publicResource": "rules",
+ "operation": "deleteRulesetAccessGroup",
+ "publicOperation": "deleteRulesetAccessGroup",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/rulesets/{namespace}/{slug}/access-group",
+ "pathParams": [
+ "namespace",
+ "slug"
+ ],
+ "publicPathParams": [
+ "namespace",
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "accessGroupSlug"
+ ],
+ "publicBodyParams": [
+ "accessGroupSlug"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "namespace",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ },
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "RuleDeleteRulesetAccessGroupParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "themes",
+ "publicResource": "themes",
+ "operation": "list",
+ "publicOperation": "list",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/themes",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "themes",
+ "publicResource": "themes",
+ "operation": "create",
+ "publicOperation": "create",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/themes",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "name",
+ "description",
+ "slug",
+ "document"
+ ],
+ "publicBodyParams": [
+ "name",
+ "description",
+ "slug",
+ "document"
+ ],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ThemeCreateParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "Uid",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "themes",
+ "publicResource": "themes",
+ "operation": "update",
+ "publicOperation": "update",
+ "deprecated": false,
+ "method": "PATCH",
+ "path": "/v1/themes/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "name",
+ "description"
+ ],
+ "publicBodyParams": [
+ "name",
+ "description"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ThemeUpdateParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "themes",
+ "publicResource": "themes",
+ "operation": "replaceDocument",
+ "publicOperation": "replaceDocument",
+ "deprecated": false,
+ "method": "PUT",
+ "path": "/v1/themes/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "document"
+ ],
+ "publicBodyParams": [
+ "document"
+ ],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ThemeReplaceDocumentParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "themes",
+ "publicResource": "themes",
+ "operation": "delete",
+ "publicOperation": "delete",
+ "deprecated": false,
+ "method": "DELETE",
+ "path": "/v1/themes/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ThemeDeleteParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "themes",
+ "publicResource": "themes",
+ "operation": "retrieve",
+ "publicOperation": "retrieve",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/themes/{slug}",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ThemeRetrieveParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "text/plain",
+ "encoding": "text",
+ "contents": [
+ {
+ "contentType": "text/plain",
+ "encoding": "text"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "teams",
+ "publicResource": "teams",
+ "operation": "list",
+ "publicOperation": "list",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/teams",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "scalarDocs",
+ "publicResource": "scalarDocs",
+ "operation": "listGuides",
+ "publicOperation": "listGuides",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/guides",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "scalarDocs",
+ "publicResource": "scalarDocs",
+ "operation": "createGuide",
+ "publicOperation": "createGuide",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/guides",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "name",
+ "slug",
+ "isPrivate",
+ "allowedUsers",
+ "allowedDomains"
+ ],
+ "publicBodyParams": [
+ "name",
+ "slug",
+ "isPrivate",
+ "allowedUsers",
+ "allowedDomains"
+ ],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ScalarDocCreateGuideParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "scalarDocs",
+ "publicResource": "scalarDocs",
+ "operation": "publishGuide",
+ "publicOperation": "publishGuide",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/guides/{slug}/publish",
+ "pathParams": [
+ "slug"
+ ],
+ "publicPathParams": [
+ "slug"
+ ],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [
+ {
+ "name": "slug",
+ "required": true,
+ "style": "simple",
+ "explode": false
+ }
+ ],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "ScalarDocPublishGuideParams"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "namespaces",
+ "publicResource": "namespaces",
+ "operation": "list",
+ "publicOperation": "list",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/namespaces",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "authentication",
+ "publicResource": "authentication",
+ "operation": "exchangePersonalToken",
+ "publicOperation": "exchangePersonalToken",
+ "deprecated": false,
+ "method": "POST",
+ "path": "/v1/auth/exchange",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [
+ "personalToken"
+ ],
+ "publicBodyParams": [
+ "personalToken"
+ ],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "paramsModel": {
+ "publicName": "AuthenticationExchangePersonalTokenParams"
+ },
+ "requestBody": {
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "required": true,
+ "publicName": "body",
+ "publicIdentifier": "body"
+ },
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ },
+ {
+ "resource": "authentication",
+ "publicResource": "authentication",
+ "operation": "listCurrentUser",
+ "publicOperation": "listCurrentUser",
+ "deprecated": false,
+ "method": "GET",
+ "path": "/v1/auth/me",
+ "pathParams": [],
+ "publicPathParams": [],
+ "queryParams": [],
+ "publicQueryParams": [],
+ "headerParams": [],
+ "publicHeaderParams": [],
+ "bodyParams": [],
+ "publicBodyParams": [],
+ "pathParamDetails": [],
+ "queryParamDetails": [],
+ "headerParamDetails": [],
+ "cookieParams": [],
+ "publicCookieParams": [],
+ "cookieParamDetails": [],
+ "response": {
+ "status": "200",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ]
+ },
+ "responseModel": {
+ "name": "User",
+ "publicAliases": []
+ },
+ "result": {
+ "successStatus": "200",
+ "errorStatuses": [
+ "400",
+ "401",
+ "403",
+ "404",
+ "422",
+ "500"
+ ]
+ },
+ "errorResponses": [
+ {
+ "status": "400",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_400",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "401",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_401",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "403",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_403",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "404",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_404",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "422",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_422",
+ "publicAliases": []
+ }
+ },
+ {
+ "status": "500",
+ "contentType": "application/json",
+ "encoding": "json",
+ "contents": [
+ {
+ "contentType": "application/json",
+ "encoding": "json"
+ }
+ ],
+ "model": {
+ "name": "_500",
+ "publicAliases": []
+ }
+ }
+ ],
+ "responseLinks": [],
+ "transport": "http"
+ }
+ ],
+ "webhooks": []
+}
diff --git a/src/__init__.py b/src/__init__.py
new file mode 100644
index 0000000..42c7450
--- /dev/null
+++ b/src/__init__.py
@@ -0,0 +1,86 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+import typing as _t
+
+from . import types
+from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes, omit, not_given
+from ._utils import file_from_path
+from ._client import Client, Stream, ScalarApi, Timeout, AsyncClient, AsyncStream, AsyncScalarApi, RequestOptions, ENVIRONMENTS
+from ._models import BaseModel
+from ._version import __title__, __version__
+from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse
+from ._constants import DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_CONNECTION_LIMITS
+from ._exceptions import (
+ APIError,
+ ScalarApiError,
+ ConflictError,
+ NotFoundError,
+ APIStatusError,
+ RateLimitError,
+ APITimeoutError,
+ BadRequestError,
+ APIConnectionError,
+ AuthenticationError,
+ InternalServerError,
+ PermissionDeniedError,
+ UnprocessableEntityError,
+ APIResponseValidationError,
+)
+from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
+from ._utils._logs import setup_logging as _setup_logging
+
+__all__ = [
+ "ENVIRONMENTS",
+ "types",
+ "__version__",
+ "__title__",
+ "NoneType",
+ "Transport",
+ "ProxiesTypes",
+ "NotGiven",
+ "NOT_GIVEN",
+ "not_given",
+ "Omit",
+ "omit",
+ "ScalarApiError",
+ "APIError",
+ "APIStatusError",
+ "APITimeoutError",
+ "APIConnectionError",
+ "APIResponseValidationError",
+ "BadRequestError",
+ "AuthenticationError",
+ "PermissionDeniedError",
+ "NotFoundError",
+ "ConflictError",
+ "UnprocessableEntityError",
+ "RateLimitError",
+ "InternalServerError",
+ "Timeout",
+ "RequestOptions",
+ "Client",
+ "AsyncClient",
+ "Stream",
+ "AsyncStream",
+ "ScalarApi",
+ "AsyncScalarApi",
+ "file_from_path",
+ "BaseModel",
+ "DEFAULT_TIMEOUT",
+ "DEFAULT_MAX_RETRIES",
+ "DEFAULT_CONNECTION_LIMITS",
+ "DefaultHttpxClient",
+ "DefaultAsyncHttpxClient",
+ "DefaultAioHttpClient",
+]
+
+_setup_logging()
+
+__locals = locals()
+__module_name = __name__
+for __export_name in __all__:
+ if not __export_name.startswith("__"):
+ try:
+ __locals[__export_name].__module__ = __module_name
+ except (TypeError, AttributeError):
+ pass
diff --git a/src/_base_client.py b/src/_base_client.py
new file mode 100644
index 0000000..f99d69d
--- /dev/null
+++ b/src/_base_client.py
@@ -0,0 +1,2229 @@
+from __future__ import annotations
+
+import sys
+import json
+import time
+import uuid
+import email
+import asyncio
+import inspect
+import logging
+import platform
+import warnings
+import email.utils
+from types import TracebackType
+from random import random
+from dataclasses import field, dataclass
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Dict,
+ Type,
+ Union,
+ Generic,
+ Mapping,
+ TypeVar,
+ Iterable,
+ Iterator,
+ Optional,
+ Generator,
+ AsyncIterator,
+ cast,
+ overload,
+)
+from typing_extensions import Literal, override, get_origin
+
+import anyio
+import httpx
+import distro
+import pydantic
+from httpx import URL
+from pydantic import PrivateAttr
+
+from . import _exceptions
+from ._qs import Querystring
+from ._files import to_httpx_files, async_to_httpx_files
+from ._types import (
+ Body,
+ Omit,
+ Query,
+ Headers,
+ Timeout,
+ NotGiven,
+ ResponseT,
+ AnyMapping,
+ PostParser,
+ BinaryTypes,
+ RequestFiles,
+ HttpxSendArgs,
+ RequestOptions,
+ AsyncBinaryTypes,
+ HttpxRequestFiles,
+ ModelBuilderProtocol,
+ not_given,
+)
+from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping
+from ._compat import PYDANTIC_V1, model_copy, model_dump
+from ._models import GenericModel, SecurityOptions, FinalRequestOptions, validate_type, construct_type
+from ._response import (
+ APIResponse,
+ BaseAPIResponse,
+ AsyncAPIResponse,
+ extract_response_type,
+)
+from ._constants import (
+ DEFAULT_TIMEOUT,
+ MAX_RETRY_DELAY,
+ DEFAULT_MAX_RETRIES,
+ INITIAL_RETRY_DELAY,
+ RAW_RESPONSE_HEADER,
+ OVERRIDE_CAST_TO_HEADER,
+ DEFAULT_CONNECTION_LIMITS,
+)
+from ._streaming import Stream, SSEDecoder, AsyncStream, SSEBytesDecoder
+from ._exceptions import (
+ APIStatusError,
+ APITimeoutError,
+ APIConnectionError,
+ APIResponseValidationError,
+)
+from ._utils._json import openapi_dumps
+
+log: logging.Logger = logging.getLogger(__name__)
+
+# TODO: make base page type vars covariant
+SyncPageT = TypeVar("SyncPageT", bound="BaseSyncPage[Any]")
+AsyncPageT = TypeVar("AsyncPageT", bound="BaseAsyncPage[Any]")
+
+
+_T = TypeVar("_T")
+_T_co = TypeVar("_T_co", covariant=True)
+
+_StreamT = TypeVar("_StreamT", bound=Stream[Any])
+_AsyncStreamT = TypeVar("_AsyncStreamT", bound=AsyncStream[Any])
+
+if TYPE_CHECKING:
+ from httpx._config import (
+ DEFAULT_TIMEOUT_CONFIG, # pyright: ignore[reportPrivateImportUsage]
+ )
+
+ HTTPX_DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_CONFIG
+else:
+ try:
+ from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT
+ except ImportError:
+ # taken from https://github.com/encode/httpx/blob/3ba5fe0d7ac70222590e759c31442b1cab263791/httpx/_config.py#L366
+ HTTPX_DEFAULT_TIMEOUT = Timeout(5.0)
+
+
+@dataclass
+class CursorPageConfig:
+ """Per-operation cursor pagination descriptor baked into a page by the generated list method.
+
+ The Python view of the shared, language-neutral descriptor: where the items array lives, how to
+ read the next cursor, which request param carries it, and on which carrier (query vs body).
+ Driving extraction from this config — rather than typed `items`/`next_cursor` model fields — lets
+ one page class serve every cursor scheme, including `cursor_id` (cursor read from the last item)
+ and body-carried cursors.
+ """
+
+ # Body path to the items array (e.g. ["items"], ["data"]).
+ items_path: List[str] = field(default_factory=list)
+ # "field" (a top-level response field) or "item" (a field on the last item — `cursor_id`).
+ cursor_kind: str = "field"
+ # Path to the cursor value: from the body root when cursor_kind is "field", or from the last item.
+ cursor_path: List[str] = field(default_factory=list)
+ # Request param wire name that carries the cursor.
+ cursor_param: str = "cursor"
+ # "query" or "body": the carrier the cursor param rides on the next request.
+ cursor_location: str = "query"
+ # Keep paginating across an empty page when set.
+ continue_on_empty_items: bool = False
+ # Body path to the scheme's `has_more` boolean. Only an explicit False stops pagination;
+ # a missing or non-boolean value falls back to cursor-presence semantics.
+ has_more_path: List[str] = field(default_factory=list)
+
+
+class PageInfo:
+ """Stores the necessary information to build the request to retrieve the next page.
+
+ Exactly one of `url`, `params` (query carrier), or `json` (body carrier) must be set.
+ """
+
+ url: URL | NotGiven
+ params: Query | NotGiven
+ json: Body | NotGiven
+
+ @overload
+ def __init__(
+ self,
+ *,
+ url: URL,
+ ) -> None: ...
+
+ @overload
+ def __init__(
+ self,
+ *,
+ params: Query,
+ ) -> None: ...
+
+ @overload
+ def __init__(
+ self,
+ *,
+ json: Body,
+ ) -> None: ...
+
+ def __init__(
+ self,
+ *,
+ url: URL | NotGiven = not_given,
+ json: Body | NotGiven = not_given,
+ params: Query | NotGiven = not_given,
+ ) -> None:
+ self.url = url
+ self.json = json
+ self.params = params
+
+ @override
+ def __repr__(self) -> str:
+ if self.url:
+ return f"{self.__class__.__name__}(url={self.url})"
+ if self.json:
+ return f"{self.__class__.__name__}(json={self.json})"
+ return f"{self.__class__.__name__}(params={self.params})"
+
+
+class BasePage(GenericModel, Generic[_T]):
+ """
+ Defines the core interface for pagination.
+
+ Type Args:
+ ModelT: The pydantic model that represents an item in the response.
+
+ Methods:
+ has_next_page(): Check if there is another page available
+ next_page_info(): Get the necessary information to make a request for the next page
+ """
+
+ _options: FinalRequestOptions = PrivateAttr()
+ _model: Type[_T] = PrivateAttr()
+ # Per-operation cursor descriptor; set by the paginated method via _set_private_attributes and
+ # carried forward across pages so every page extracts items/cursor identically. None for pages
+ # that predate metadata-driven pagination.
+ _cursor_config: Optional[CursorPageConfig] = PrivateAttr(None)
+
+ def has_next_page(self) -> bool:
+ items = self._get_page_items()
+ if not items:
+ return False
+ return self.next_page_info() is not None
+
+ def next_page_info(self) -> Optional[PageInfo]: ...
+
+ def _get_page_items(self) -> Iterable[_T]: # type: ignore[empty-body]
+ ...
+
+ def _params_from_url(self, url: URL) -> httpx.QueryParams:
+ # TODO: do we have to preprocess params here?
+ return httpx.QueryParams(cast(Any, self._options.params)).merge(url.params)
+
+ def _info_to_options(self, info: PageInfo) -> FinalRequestOptions:
+ options = model_copy(self._options)
+ options._strip_raw_response_header()
+
+ if not isinstance(info.params, NotGiven):
+ options.params = {**options.params, **info.params}
+ return options
+
+ if not isinstance(info.url, NotGiven):
+ params = self._params_from_url(info.url)
+ url = info.url.copy_with(params=params)
+ options.params = dict(url.params)
+ options.url = str(url)
+ return options
+
+ if not isinstance(info.json, NotGiven):
+ if not is_mapping(info.json):
+ raise TypeError("Pagination is only supported with mappings")
+
+ if not options.json_data:
+ options.json_data = {**info.json}
+ else:
+ if not is_mapping(options.json_data):
+ raise TypeError("Pagination is only supported with mappings")
+
+ options.json_data = {**options.json_data, **info.json}
+ return options
+
+ raise ValueError("Unexpected PageInfo state")
+
+
+class BaseSyncPage(BasePage[_T], Generic[_T]):
+ _client: SyncAPIClient = pydantic.PrivateAttr()
+
+ def _set_private_attributes(
+ self,
+ client: SyncAPIClient,
+ model: Type[_T],
+ options: FinalRequestOptions,
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> None:
+ if (not PYDANTIC_V1) and getattr(self, "__pydantic_private__", None) is None:
+ self.__pydantic_private__ = {}
+
+ self._model = model
+ self._client = client
+ self._options = options
+ self._cursor_config = cursor_config
+
+ # Pydantic uses a custom `__iter__` method to support casting BaseModels
+ # to dictionaries. e.g. dict(model).
+ # As we want to support `for item in page`, this is inherently incompatible
+ # with the default pydantic behaviour. It is not possible to support both
+ # use cases at once. Fortunately, this is not a big deal as all other pydantic
+ # methods should continue to work as expected as there is an alternative method
+ # to cast a model to a dictionary, model.dict(), which is used internally
+ # by pydantic.
+ def __iter__(self) -> Iterator[_T]: # type: ignore
+ for page in self.iter_pages():
+ for item in page._get_page_items():
+ yield item
+
+ def iter_pages(self: SyncPageT) -> Iterator[SyncPageT]:
+ page = self
+ while True:
+ yield page
+ if page.has_next_page():
+ page = page.get_next_page()
+ else:
+ return
+
+ def get_next_page(self: SyncPageT) -> SyncPageT:
+ info = self.next_page_info()
+ if not info:
+ raise RuntimeError(
+ "No next page expected; please check `.has_next_page()` before calling `.get_next_page()`."
+ )
+
+ options = self._info_to_options(info)
+ # Carry the cursor descriptor forward so the next page extracts items/cursor identically.
+ return self._client._request_api_list(
+ self._model, page=self.__class__, options=options, cursor_config=self._cursor_config
+ )
+
+
+class AsyncPaginator(Generic[_T, AsyncPageT]):
+ def __init__(
+ self,
+ client: AsyncAPIClient,
+ options: FinalRequestOptions,
+ page_cls: Type[AsyncPageT],
+ model: Type[_T],
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> None:
+ self._model = model
+ self._client = client
+ self._options = options
+ self._page_cls = page_cls
+ self._cursor_config = cursor_config
+
+ def __await__(self) -> Generator[Any, None, AsyncPageT]:
+ return self._get_page().__await__()
+
+ async def _get_page(self) -> AsyncPageT:
+ def _parser(resp: AsyncPageT) -> AsyncPageT:
+ resp._set_private_attributes(
+ model=self._model,
+ options=self._options,
+ client=self._client,
+ cursor_config=self._cursor_config,
+ )
+ return resp
+
+ self._options.post_parser = _parser
+
+ return await self._client.request(self._page_cls, self._options)
+
+ async def __aiter__(self) -> AsyncIterator[_T]:
+ # https://github.com/microsoft/pyright/issues/3464
+ page = cast(
+ AsyncPageT,
+ await self, # type: ignore
+ )
+ async for item in page:
+ yield item
+
+
+class BaseAsyncPage(BasePage[_T], Generic[_T]):
+ _client: AsyncAPIClient = pydantic.PrivateAttr()
+
+ def _set_private_attributes(
+ self,
+ model: Type[_T],
+ client: AsyncAPIClient,
+ options: FinalRequestOptions,
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> None:
+ if (not PYDANTIC_V1) and getattr(self, "__pydantic_private__", None) is None:
+ self.__pydantic_private__ = {}
+
+ self._model = model
+ self._client = client
+ self._options = options
+ self._cursor_config = cursor_config
+
+ async def __aiter__(self) -> AsyncIterator[_T]:
+ async for page in self.iter_pages():
+ for item in page._get_page_items():
+ yield item
+
+ async def iter_pages(self: AsyncPageT) -> AsyncIterator[AsyncPageT]:
+ page = self
+ while True:
+ yield page
+ if page.has_next_page():
+ page = await page.get_next_page()
+ else:
+ return
+
+ async def get_next_page(self: AsyncPageT) -> AsyncPageT:
+ info = self.next_page_info()
+ if not info:
+ raise RuntimeError(
+ "No next page expected; please check `.has_next_page()` before calling `.get_next_page()`."
+ )
+
+ options = self._info_to_options(info)
+ # Carry the cursor descriptor forward so the next page extracts items/cursor identically.
+ return await self._client._request_api_list(
+ self._model, page=self.__class__, options=options, cursor_config=self._cursor_config
+ )
+
+
+_HttpxClientT = TypeVar("_HttpxClientT", bound=Union[httpx.Client, httpx.AsyncClient])
+_DefaultStreamT = TypeVar("_DefaultStreamT", bound=Union[Stream[Any], AsyncStream[Any]])
+
+
+class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
+ _client: _HttpxClientT
+ _version: str
+ _base_url: URL
+ max_retries: int
+ timeout: Union[float, Timeout, None]
+ _strict_response_validation: bool
+ _idempotency_header: str | None
+ _default_stream_cls: type[_DefaultStreamT] | None = None
+
+ def __init__(
+ self,
+ *,
+ version: str,
+ base_url: str | URL,
+ _strict_response_validation: bool,
+ max_retries: int = DEFAULT_MAX_RETRIES,
+ timeout: float | Timeout | None = DEFAULT_TIMEOUT,
+ custom_headers: Mapping[str, str] | None = None,
+ custom_query: Mapping[str, object] | None = None,
+ ) -> None:
+ self._version = version
+ self._base_url = self._enforce_trailing_slash(URL(base_url))
+ self.max_retries = max_retries
+ self.timeout = timeout
+ self._custom_headers = custom_headers or {}
+ self._custom_query = custom_query or {}
+ self._strict_response_validation = _strict_response_validation
+ self._idempotency_header = None
+ self._platform: Platform | None = None
+
+ if max_retries is None: # pyright: ignore[reportUnnecessaryComparison]
+ raise TypeError(
+ "max_retries cannot be None. If you want to disable retries, pass `0`; if you want unlimited retries, pass `math.inf` or a very high number; if you want the default behavior, pass `scalar_api.DEFAULT_MAX_RETRIES`"
+ )
+
+ def _enforce_trailing_slash(self, url: URL) -> URL:
+ if url.raw_path.endswith(b"/"):
+ return url
+ return url.copy_with(raw_path=url.raw_path + b"/")
+
+ def _make_status_error_from_response(
+ self,
+ response: httpx.Response,
+ ) -> APIStatusError:
+ if response.is_closed and not response.is_stream_consumed:
+ # We can't read the response body as it has been closed
+ # before it was read. This can happen if an event hook
+ # raises a status error.
+ body = None
+ err_msg = f"Error code: {response.status_code}"
+ else:
+ err_text = response.text.strip()
+ body = err_text
+
+ try:
+ body = json.loads(err_text)
+ err_msg = f"Error code: {response.status_code} - {body}"
+ except Exception:
+ err_msg = err_text or f"Error code: {response.status_code}"
+
+ return self._make_status_error(err_msg, body=body, response=response)
+
+ def _make_status_error(
+ self,
+ err_msg: str,
+ *,
+ body: object,
+ response: httpx.Response,
+ ) -> _exceptions.APIStatusError:
+ raise NotImplementedError()
+
+ def _auth_headers(
+ self,
+ security: SecurityOptions, # noqa: ARG002
+ ) -> dict[str, str]:
+ return {}
+
+ def _auth_query(
+ self,
+ security: SecurityOptions, # noqa: ARG002
+ ) -> dict[str, str]:
+ return {}
+
+ def _auth_cookies(
+ self,
+ security: SecurityOptions, # noqa: ARG002
+ ) -> dict[str, str]:
+ return {}
+
+ def _custom_auth(
+ self,
+ security: SecurityOptions, # noqa: ARG002
+ ) -> httpx.Auth | None:
+ return None
+
+ def _build_headers(
+ self,
+ options: FinalRequestOptions,
+ *,
+ params: Query,
+ cookies: Mapping[str, str],
+ retries_taken: int = 0,
+ ) -> httpx.Headers:
+ custom_headers = options.headers or {}
+ headers_dict = _merge_mappings({**self._auth_headers(options.security), **self.default_headers}, custom_headers)
+ self._validate_headers(headers_dict, custom_headers, params, cookies)
+
+ # headers are case-insensitive while dictionaries are not.
+ headers = httpx.Headers(headers_dict)
+
+ idempotency_header = self._idempotency_header
+ if idempotency_header and options.idempotency_key and idempotency_header not in headers:
+ headers[idempotency_header] = options.idempotency_key
+
+ # Don't set these headers if they were already set or removed by the caller. We check
+ # `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
+ lower_custom_headers = [header.lower() for header in custom_headers]
+ if "x-scalar-retry-count" not in lower_custom_headers:
+ headers["x-scalar-retry-count"] = str(retries_taken)
+ if "x-scalar-read-timeout" not in lower_custom_headers:
+ timeout = self.timeout if isinstance(options.timeout, NotGiven) else options.timeout
+ if isinstance(timeout, Timeout):
+ timeout = timeout.read
+ if timeout is not None:
+ headers["x-scalar-read-timeout"] = str(timeout)
+
+ return headers
+
+ def _prepare_url(self, url: str) -> URL:
+ """
+ Merge a URL argument together with any 'base_url' on the client,
+ to create the URL used for the outgoing request.
+ """
+ # Copied from httpx's `_merge_url` method.
+ merge_url = URL(url)
+ if merge_url.is_relative_url:
+ merge_raw_path = self.base_url.raw_path + merge_url.raw_path.lstrip(b"/")
+ return self.base_url.copy_with(raw_path=merge_raw_path)
+
+ return merge_url
+
+ def _make_sse_decoder(self) -> SSEDecoder | SSEBytesDecoder:
+ return SSEDecoder()
+
+ def _build_request(
+ self,
+ options: FinalRequestOptions,
+ *,
+ retries_taken: int = 0,
+ ) -> httpx.Request:
+ if log.isEnabledFor(logging.DEBUG):
+ log.debug(
+ "Request options: %s",
+ model_dump(
+ options,
+ exclude_unset=True,
+ # Pydantic v1 can't dump every type we support in content, so we exclude it for now.
+ exclude={
+ "content",
+ }
+ if PYDANTIC_V1
+ else {},
+ ),
+ )
+ kwargs: dict[str, Any] = {}
+
+ json_data = options.json_data
+ if options.extra_json is not None:
+ if json_data is None:
+ json_data = cast(Body, options.extra_json)
+ elif is_mapping(json_data):
+ json_data = _merge_mappings(json_data, options.extra_json)
+ else:
+ raise RuntimeError(f"Unexpected JSON data type, {type(json_data)}, cannot merge with `extra_body`")
+
+ params = _merge_mappings({**self._auth_query(options.security), **self.default_query}, options.params)
+ cookies = self._auth_cookies(options.security)
+ headers = self._build_headers(options, retries_taken=retries_taken, params=params, cookies=cookies)
+ content_type = headers.get("Content-Type")
+ files = options.files
+
+ # If the given Content-Type header is multipart/form-data then it
+ # has to be removed so that httpx can generate the header with
+ # additional information for us as it has to be in this form
+ # for the server to be able to correctly parse the request:
+ # multipart/form-data; boundary=---abc--
+ if content_type is not None and content_type.startswith("multipart/form-data"):
+ if "boundary" not in content_type:
+ # only remove the header if the boundary hasn't been explicitly set
+ # as the caller doesn't want httpx to come up with their own boundary
+ headers.pop("Content-Type")
+
+ # As we are now sending multipart/form-data instead of application/json
+ # we need to tell httpx to use it, https://www.python-httpx.org/advanced/clients/#multipart-file-encoding
+ if json_data:
+ if not is_dict(json_data):
+ raise TypeError(
+ f"Expected query input to be a dictionary for multipart requests but got {type(json_data)} instead."
+ )
+ kwargs["data"] = self._serialize_multipartform(json_data)
+
+ # httpx determines whether or not to send a "multipart/form-data"
+ # request based on the truthiness of the "files" argument.
+ # This gets around that issue by generating a dict value that
+ # evaluates to true.
+ #
+ # https://github.com/encode/httpx/discussions/2399#discussioncomment-3814186
+ if not files:
+ files = cast(HttpxRequestFiles, ForceMultipartDict())
+
+ prepared_url = self._prepare_url(options.url)
+ # preserve hard-coded query params from the url
+ if params and prepared_url.query:
+ params = {**dict(prepared_url.params.items()), **params}
+ prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0])
+ if "_" in prepared_url.host:
+ # work around https://github.com/encode/httpx/discussions/2880
+ kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")}
+
+ is_body_allowed = options.method.lower() != "get"
+
+ if is_body_allowed:
+ if options.content is not None and json_data is not None:
+ raise TypeError("Passing both `content` and `json_data` is not supported")
+ if options.content is not None and files is not None:
+ raise TypeError("Passing both `content` and `files` is not supported")
+ if options.content is not None:
+ kwargs["content"] = options.content
+ elif isinstance(json_data, bytes):
+ kwargs["content"] = json_data
+ elif not files:
+ # Don't set content when JSON is sent as multipart/form-data,
+ # since httpx's content param overrides other body arguments
+ kwargs["content"] = openapi_dumps(json_data) if is_given(json_data) and json_data is not None else None
+ kwargs["files"] = files
+ else:
+ headers.pop("Content-Type", None)
+ kwargs.pop("data", None)
+
+ # TODO: report this error to httpx
+ return self._client.build_request( # pyright: ignore[reportUnknownMemberType]
+ headers=headers,
+ timeout=self.timeout if isinstance(options.timeout, NotGiven) else options.timeout,
+ method=options.method,
+ url=prepared_url,
+ # the `Query` type that we use is incompatible with qs'
+ # `Params` type as it needs to be typed as `Mapping[str, object]`
+ # so that passing a `TypedDict` doesn't cause an error.
+ # https://github.com/microsoft/pyright/issues/3526#event-6715453066
+ params=self.qs.stringify(cast(Mapping[str, Any], params)) if params else None,
+ cookies=cookies or None,
+ **kwargs,
+ )
+
+ def _serialize_multipartform(self, data: Mapping[object, object]) -> dict[str, object]:
+ items = self.qs.stringify_items(
+ # TODO: type ignore is required as stringify_items is well typed but we can't be
+ # well typed without heavy validation.
+ data, # type: ignore
+ array_format="brackets",
+ )
+ serialized: dict[str, object] = {}
+ for key, value in items:
+ existing = serialized.get(key)
+
+ if not existing:
+ serialized[key] = value
+ continue
+
+ # If a value has already been set for this key then that
+ # means we're sending data like `array[]=[1, 2, 3]` and we
+ # need to tell httpx that we want to send multiple values with
+ # the same key which is done by using a list or a tuple.
+ #
+ # Note: 2d arrays should never result in the same key at both
+ # levels so it's safe to assume that if the value is a list,
+ # it was because we changed it to be a list.
+ if is_list(existing):
+ existing.append(value)
+ else:
+ serialized[key] = [existing, value]
+
+ return serialized
+
+ def _maybe_override_cast_to(self, cast_to: type[ResponseT], options: FinalRequestOptions) -> type[ResponseT]:
+ if not is_given(options.headers):
+ return cast_to
+
+ # make a copy of the headers so we don't mutate user-input
+ headers = dict(options.headers)
+
+ # we internally support defining a temporary header to override the
+ # default `cast_to` type for use with `.with_raw_response` and `.with_streaming_response`
+ # see _response.py for implementation details
+ override_cast_to = headers.pop(OVERRIDE_CAST_TO_HEADER, not_given)
+ if is_given(override_cast_to):
+ options.headers = headers
+ return cast(Type[ResponseT], override_cast_to)
+
+ return cast_to
+
+ def _should_stream_response_body(self, request: httpx.Request) -> bool:
+ return request.headers.get(RAW_RESPONSE_HEADER) == "stream" # type: ignore[no-any-return]
+
+ def _process_response_data(
+ self,
+ *,
+ data: object,
+ cast_to: type[ResponseT],
+ response: httpx.Response,
+ ) -> ResponseT:
+ if data is None:
+ return cast(ResponseT, None)
+
+ if cast_to is object:
+ return cast(ResponseT, data)
+
+ try:
+ if inspect.isclass(cast_to) and issubclass(cast_to, ModelBuilderProtocol):
+ return cast(ResponseT, cast_to.build(response=response, data=data))
+
+ if self._strict_response_validation:
+ return cast(ResponseT, validate_type(type_=cast_to, value=data))
+
+ return cast(ResponseT, construct_type(type_=cast_to, value=data))
+ except pydantic.ValidationError as err:
+ raise APIResponseValidationError(response=response, body=data) from err
+
+ @property
+ def qs(self) -> Querystring:
+ return Querystring()
+
+ @property
+ def custom_auth(self) -> httpx.Auth | None:
+ return None
+
+ @property
+ def auth_headers(self) -> dict[str, str]:
+ return {}
+
+ @property
+ def default_headers(self) -> dict[str, str | Omit]:
+ return {
+ "Accept": "application/json",
+ "Content-Type": "application/json",
+ "User-Agent": self.user_agent,
+ **self.platform_headers(),
+ **self._custom_headers,
+ }
+
+ @property
+ def default_query(self) -> dict[str, object]:
+ return {
+ **self._custom_query,
+ }
+
+ def _validate_headers(
+ self,
+ headers: Headers, # noqa: ARG002
+ custom_headers: Headers, # noqa: ARG002
+ params: Query, # noqa: ARG002
+ cookies: Mapping[str, str], # noqa: ARG002
+ ) -> None:
+ """Validate merged auth-bearing headers, query params, and cookies.
+
+ Does nothing by default.
+ """
+ return
+
+ @property
+ def user_agent(self) -> str:
+ return f"{self.__class__.__name__}/Python {self._version}"
+
+ @property
+ def base_url(self) -> URL:
+ return self._base_url
+
+ @base_url.setter
+ def base_url(self, url: URL | str) -> None:
+ self._base_url = self._enforce_trailing_slash(url if isinstance(url, URL) else URL(url))
+
+ def platform_headers(self) -> Dict[str, str]:
+ # the actual implementation is in a separate `lru_cache` decorated
+ # function because adding `lru_cache` to methods will leak memory
+ # https://github.com/python/cpython/issues/88476
+ return platform_headers(self._version, platform=self._platform)
+
+ def _parse_retry_after_header(self, response_headers: Optional[httpx.Headers] = None) -> float | None:
+ """Returns a float of the number of seconds (not milliseconds) to wait after retrying, or None if unspecified.
+
+ About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
+ See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#syntax
+ """
+ if response_headers is None:
+ return None
+
+ # First, try the non-standard `retry-after-ms` header for milliseconds,
+ # which is more precise than integer-seconds `retry-after`
+ try:
+ retry_ms_header = response_headers.get("retry-after-ms", None)
+ return float(retry_ms_header) / 1000
+ except (TypeError, ValueError):
+ pass
+
+ # Next, try parsing `retry-after` header as seconds (allowing nonstandard floats).
+ retry_header = response_headers.get("retry-after")
+ try:
+ # note: the spec indicates that this should only ever be an integer
+ # but if someone sends a float there's no reason for us to not respect it
+ return float(retry_header)
+ except (TypeError, ValueError):
+ pass
+
+ # Last, try parsing `retry-after` as a date.
+ retry_date_tuple = email.utils.parsedate_tz(retry_header)
+ if retry_date_tuple is None:
+ return None
+
+ retry_date = email.utils.mktime_tz(retry_date_tuple)
+ return float(retry_date - time.time())
+
+ def _calculate_retry_timeout(
+ self,
+ remaining_retries: int,
+ options: FinalRequestOptions,
+ response_headers: Optional[httpx.Headers] = None,
+ ) -> float:
+ max_retries = options.get_max_retries(self.max_retries)
+
+ # If the API asks us to wait a certain amount of time (and it's a reasonable amount), just do what it says.
+ retry_after = self._parse_retry_after_header(response_headers)
+ if retry_after is not None and 0 < retry_after <= 60:
+ return retry_after
+
+ # Also cap retry count to 1000 to avoid any potential overflows with `pow`
+ nb_retries = min(max_retries - remaining_retries, 1000)
+
+ # Apply exponential backoff, but not more than the max.
+ sleep_seconds = min(INITIAL_RETRY_DELAY * pow(2.0, nb_retries), MAX_RETRY_DELAY)
+
+ # Apply some jitter, plus-or-minus half a second.
+ jitter = 1 - 0.25 * random()
+ timeout = sleep_seconds * jitter
+ return timeout if timeout >= 0 else 0
+
+ def _should_retry(self, response: httpx.Response) -> bool:
+ # Note: this is not a standard header
+ should_retry_header = response.headers.get("x-should-retry")
+
+ # If the server explicitly says whether or not to retry, obey.
+ if should_retry_header == "true":
+ log.debug("Retrying as header `x-should-retry` is set to `true`")
+ return True
+ if should_retry_header == "false":
+ log.debug("Not retrying as header `x-should-retry` is set to `false`")
+ return False
+
+ # Retry on request timeouts.
+ if response.status_code == 408:
+ log.debug("Retrying due to status code %i", response.status_code)
+ return True
+
+ # Retry on lock timeouts.
+ if response.status_code == 409:
+ log.debug("Retrying due to status code %i", response.status_code)
+ return True
+
+ # Retry on rate limits.
+ if response.status_code == 429:
+ log.debug("Retrying due to status code %i", response.status_code)
+ return True
+
+ # Retry internal errors.
+ if response.status_code >= 500:
+ log.debug("Retrying due to status code %i", response.status_code)
+ return True
+
+ log.debug("Not retrying")
+ return False
+
+ def _idempotency_key(self) -> str:
+ return f"scalar-python-retry-{uuid.uuid4()}"
+
+
+class _DefaultHttpxClient(httpx.Client):
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
+ kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
+ kwargs.setdefault("follow_redirects", True)
+ super().__init__(**kwargs)
+
+
+if TYPE_CHECKING:
+ DefaultHttpxClient = httpx.Client
+ """An alias to `httpx.Client` that provides the same defaults that this SDK
+ uses internally.
+
+ This is useful because overriding the `http_client` with your own instance of
+ `httpx.Client` will result in httpx's defaults being used, not ours.
+ """
+else:
+ DefaultHttpxClient = _DefaultHttpxClient
+
+
+class SyncHttpxClientWrapper(DefaultHttpxClient):
+ def __del__(self) -> None:
+ if self.is_closed:
+ return
+
+ try:
+ self.close()
+ except Exception:
+ pass
+
+
+class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
+ _client: httpx.Client
+ _default_stream_cls: type[Stream[Any]] | None = None
+
+ def __init__(
+ self,
+ *,
+ version: str,
+ base_url: str | URL,
+ max_retries: int = DEFAULT_MAX_RETRIES,
+ timeout: float | Timeout | None | NotGiven = not_given,
+ http_client: httpx.Client | None = None,
+ custom_headers: Mapping[str, str] | None = None,
+ custom_query: Mapping[str, object] | None = None,
+ _strict_response_validation: bool,
+ **kwargs: Any,
+ ) -> None:
+ if not is_given(timeout):
+ # if the user passed in a custom http client with a non-default
+ # timeout set then we use that timeout.
+ #
+ # note: there is an edge case here where the user passes in a client
+ # where they've explicitly set the timeout to match the default timeout
+ # as this check is structural, meaning that we'll think they didn't
+ # pass in a timeout and will ignore it
+ if http_client and http_client.timeout != HTTPX_DEFAULT_TIMEOUT:
+ timeout = http_client.timeout
+ else:
+ timeout = DEFAULT_TIMEOUT
+
+ if http_client is not None and not isinstance(http_client, httpx.Client): # pyright: ignore[reportUnnecessaryIsInstance]
+ raise TypeError(
+ f"Invalid `http_client` argument; Expected an instance of `httpx.Client` but got {type(http_client)}"
+ )
+
+ super().__init__(
+ version=version,
+ # cast to a valid type because mypy doesn't understand our type narrowing
+ timeout=cast(Timeout, timeout),
+ base_url=base_url,
+ max_retries=max_retries,
+ custom_query=custom_query,
+ custom_headers=custom_headers,
+ _strict_response_validation=_strict_response_validation,
+ )
+ self._client = http_client or SyncHttpxClientWrapper(
+ base_url=base_url,
+ # cast to a valid type because mypy doesn't understand our type narrowing
+ timeout=cast(Timeout, timeout),
+ # Used by generated `with_options(_extra_kwargs=...)` for HTTPX client configuration.
+ **kwargs,
+ )
+
+ def is_closed(self) -> bool:
+ return self._client.is_closed
+
+ def close(self) -> None:
+ """Close the underlying HTTPX client.
+
+ The client will *not* be usable after this.
+ """
+ # If an error is thrown while constructing a client, self._client
+ # may not be present
+ if hasattr(self, "_client"):
+ self._client.close()
+
+ def __enter__(self: _T) -> _T:
+ return self
+
+ def __exit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc: BaseException | None,
+ exc_tb: TracebackType | None,
+ ) -> None:
+ self.close()
+
+ def _prepare_options(
+ self,
+ options: FinalRequestOptions, # noqa: ARG002
+ ) -> FinalRequestOptions:
+ """Hook for mutating the given options"""
+ return options
+
+ def _prepare_request(
+ self,
+ request: httpx.Request, # noqa: ARG002
+ ) -> None:
+ """This method is used as a callback for mutating the `Request` object
+ after it has been constructed.
+ This is useful for cases where you want to add certain headers based off of
+ the request properties, e.g. `url`, `method` etc.
+ """
+ return None
+
+ @overload
+ def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: Literal[True],
+ stream_cls: Type[_StreamT],
+ ) -> _StreamT: ...
+
+ @overload
+ def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: Literal[False] = False,
+ ) -> ResponseT: ...
+
+ @overload
+ def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: bool = False,
+ stream_cls: Type[_StreamT] | None = None,
+ ) -> ResponseT | _StreamT: ...
+
+ def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: bool = False,
+ stream_cls: type[_StreamT] | None = None,
+ ) -> ResponseT | _StreamT:
+ cast_to = self._maybe_override_cast_to(cast_to, options)
+
+ # create a copy of the options we were given so that if the
+ # options are mutated later & we then retry, the retries are
+ # given the original options
+ input_options = model_copy(options)
+ if input_options.idempotency_key is None and input_options.method.lower() != "get":
+ # ensure the idempotency key is reused between requests
+ input_options.idempotency_key = self._idempotency_key()
+
+ response: httpx.Response | None = None
+ max_retries = input_options.get_max_retries(self.max_retries)
+
+ retries_taken = 0
+ for retries_taken in range(max_retries + 1):
+ options = model_copy(input_options)
+ options = self._prepare_options(options)
+
+ remaining_retries = max_retries - retries_taken
+ request = self._build_request(options, retries_taken=retries_taken)
+ self._prepare_request(request)
+
+ kwargs: HttpxSendArgs = {}
+ custom_auth = self._custom_auth(options.security)
+ if custom_auth is not None:
+ kwargs["auth"] = custom_auth
+
+ if options.follow_redirects is not None:
+ kwargs["follow_redirects"] = options.follow_redirects
+
+ log.debug("Sending HTTP Request: %s %s", request.method, request.url)
+
+ response = None
+ try:
+ response = self._client.send(
+ request,
+ stream=stream or self._should_stream_response_body(request=request),
+ **kwargs,
+ )
+ except httpx.TimeoutException as err:
+ log.debug("Encountered httpx.TimeoutException", exc_info=True)
+
+ if remaining_retries > 0:
+ self._sleep_for_retry(
+ retries_taken=retries_taken,
+ max_retries=max_retries,
+ options=input_options,
+ response=None,
+ )
+ continue
+
+ log.debug("Raising timeout error")
+ raise APITimeoutError(request=request) from err
+ except Exception as err:
+ log.debug("Encountered Exception", exc_info=True)
+
+ if remaining_retries > 0:
+ self._sleep_for_retry(
+ retries_taken=retries_taken,
+ max_retries=max_retries,
+ options=input_options,
+ response=None,
+ )
+ continue
+
+ log.debug("Raising connection error")
+ raise APIConnectionError(request=request) from err
+
+ log.debug(
+ 'HTTP Response: %s %s "%i %s" %s',
+ request.method,
+ request.url,
+ response.status_code,
+ response.reason_phrase,
+ response.headers,
+ )
+
+ try:
+ response.raise_for_status()
+ except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
+ log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
+
+ if remaining_retries > 0 and self._should_retry(err.response):
+ err.response.close()
+ self._sleep_for_retry(
+ retries_taken=retries_taken,
+ max_retries=max_retries,
+ options=input_options,
+ response=response,
+ )
+ continue
+
+ # If the response is streamed then we need to explicitly read the response
+ # to completion before attempting to access the response text.
+ if not err.response.is_closed:
+ err.response.read()
+
+ log.debug("Re-raising status error")
+ raise self._make_status_error_from_response(err.response) from None
+
+ break
+
+ assert response is not None, "could not resolve response (should never happen)"
+ return self._process_response(
+ cast_to=cast_to,
+ options=options,
+ response=response,
+ stream=stream,
+ stream_cls=stream_cls,
+ retries_taken=retries_taken,
+ )
+
+ def _sleep_for_retry(
+ self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None
+ ) -> None:
+ remaining_retries = max_retries - retries_taken
+ if remaining_retries == 1:
+ log.debug("1 retry left")
+ else:
+ log.debug("%i retries left", remaining_retries)
+
+ timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None)
+ log.info("Retrying request to %s in %f seconds", options.url, timeout)
+
+ time.sleep(timeout)
+
+ def _process_response(
+ self,
+ *,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ response: httpx.Response,
+ stream: bool,
+ stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
+ retries_taken: int = 0,
+ ) -> ResponseT:
+ origin = get_origin(cast_to) or cast_to
+
+ if (
+ inspect.isclass(origin)
+ and issubclass(origin, BaseAPIResponse)
+ # we only want to actually return the custom BaseAPIResponse class if we're
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
+ ):
+ if not issubclass(origin, APIResponse):
+ raise TypeError(f"API Response types must subclass {APIResponse}; Received {origin}")
+
+ response_cls = cast("type[BaseAPIResponse[Any]]", cast_to)
+ return cast(
+ ResponseT,
+ response_cls(
+ raw=response,
+ client=self,
+ cast_to=extract_response_type(response_cls),
+ stream=stream,
+ stream_cls=stream_cls,
+ options=options,
+ retries_taken=retries_taken,
+ ),
+ )
+
+ if cast_to == httpx.Response:
+ return cast(ResponseT, response)
+
+ api_response = APIResponse(
+ raw=response,
+ client=self,
+ cast_to=cast("type[ResponseT]", cast_to), # pyright: ignore[reportUnnecessaryCast]
+ stream=stream,
+ stream_cls=stream_cls,
+ options=options,
+ retries_taken=retries_taken,
+ )
+ if bool(response.request.headers.get(RAW_RESPONSE_HEADER)):
+ return cast(ResponseT, api_response)
+
+ return api_response.parse()
+
+ def _request_api_list(
+ self,
+ model: Type[object],
+ page: Type[SyncPageT],
+ options: FinalRequestOptions,
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> SyncPageT:
+ def _parser(resp: SyncPageT) -> SyncPageT:
+ resp._set_private_attributes(
+ client=self,
+ model=model,
+ options=options,
+ cursor_config=cursor_config,
+ )
+ return resp
+
+ options.post_parser = _parser
+
+ return self.request(page, options, stream=False)
+
+ @overload
+ def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: Literal[False] = False,
+ ) -> ResponseT: ...
+
+ @overload
+ def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: Literal[True],
+ stream_cls: type[_StreamT],
+ ) -> _StreamT: ...
+
+ @overload
+ def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: bool,
+ stream_cls: type[_StreamT] | None = None,
+ ) -> ResponseT | _StreamT: ...
+
+ def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: bool = False,
+ stream_cls: type[_StreamT] | None = None,
+ ) -> ResponseT | _StreamT:
+ opts = FinalRequestOptions.construct(method="get", url=path, **options)
+ # cast is required because mypy complains about returning Any even though
+ # it understands the type variables
+ return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
+
+ @overload
+ def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ options: RequestOptions = {},
+ files: RequestFiles | None = None,
+ stream: Literal[False] = False,
+ ) -> ResponseT: ...
+
+ @overload
+ def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ options: RequestOptions = {},
+ files: RequestFiles | None = None,
+ stream: Literal[True],
+ stream_cls: type[_StreamT],
+ ) -> _StreamT: ...
+
+ @overload
+ def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ options: RequestOptions = {},
+ files: RequestFiles | None = None,
+ stream: bool,
+ stream_cls: type[_StreamT] | None = None,
+ ) -> ResponseT | _StreamT: ...
+
+ def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ options: RequestOptions = {},
+ files: RequestFiles | None = None,
+ stream: bool = False,
+ stream_cls: type[_StreamT] | None = None,
+ ) -> ResponseT | _StreamT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(
+ method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
+ )
+ return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
+
+ def patch(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ ) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(
+ method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
+ )
+ return self.request(cast_to, opts)
+
+ def put(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ ) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(
+ method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
+ )
+ return self.request(cast_to, opts)
+
+ def delete(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: BinaryTypes | None = None,
+ options: RequestOptions = {},
+ ) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
+ return self.request(cast_to, opts)
+
+ def get_api_list(
+ self,
+ path: str,
+ *,
+ model: Type[object],
+ page: Type[SyncPageT],
+ body: Body | None = None,
+ options: RequestOptions = {},
+ method: str = "get",
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> SyncPageT:
+ opts = FinalRequestOptions.construct(method=method, url=path, json_data=body, **options)
+ return self._request_api_list(model, page, opts, cursor_config=cursor_config)
+
+
+class _DefaultAsyncHttpxClient(httpx.AsyncClient):
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
+ kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
+ kwargs.setdefault("follow_redirects", True)
+ super().__init__(**kwargs)
+
+
+try:
+ import httpx_aiohttp
+except ImportError:
+
+ class _DefaultAioHttpClient(httpx.AsyncClient):
+ def __init__(self, **_kwargs: Any) -> None:
+ raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra")
+else:
+
+ class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
+ def __init__(self, **kwargs: Any) -> None:
+ kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
+ kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
+ kwargs.setdefault("follow_redirects", True)
+
+ super().__init__(**kwargs)
+
+
+if TYPE_CHECKING:
+ DefaultAsyncHttpxClient = httpx.AsyncClient
+ """An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
+ uses internally.
+
+ This is useful because overriding the `http_client` with your own instance of
+ `httpx.AsyncClient` will result in httpx's defaults being used, not ours.
+ """
+
+ DefaultAioHttpClient = httpx.AsyncClient
+ """An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`."""
+else:
+ DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
+ DefaultAioHttpClient = _DefaultAioHttpClient
+
+
+class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
+ def __del__(self) -> None:
+ if self.is_closed:
+ return
+
+ try:
+ # TODO(someday): support non asyncio runtimes here
+ asyncio.get_running_loop().create_task(self.aclose())
+ except Exception:
+ pass
+
+
+class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
+ _client: httpx.AsyncClient
+ _default_stream_cls: type[AsyncStream[Any]] | None = None
+
+ def __init__(
+ self,
+ *,
+ version: str,
+ base_url: str | URL,
+ _strict_response_validation: bool,
+ max_retries: int = DEFAULT_MAX_RETRIES,
+ timeout: float | Timeout | None | NotGiven = not_given,
+ http_client: httpx.AsyncClient | None = None,
+ custom_headers: Mapping[str, str] | None = None,
+ custom_query: Mapping[str, object] | None = None,
+ **kwargs: Any,
+ ) -> None:
+ if not is_given(timeout):
+ # if the user passed in a custom http client with a non-default
+ # timeout set then we use that timeout.
+ #
+ # note: there is an edge case here where the user passes in a client
+ # where they've explicitly set the timeout to match the default timeout
+ # as this check is structural, meaning that we'll think they didn't
+ # pass in a timeout and will ignore it
+ if http_client and http_client.timeout != HTTPX_DEFAULT_TIMEOUT:
+ timeout = http_client.timeout
+ else:
+ timeout = DEFAULT_TIMEOUT
+
+ if http_client is not None and not isinstance(http_client, httpx.AsyncClient): # pyright: ignore[reportUnnecessaryIsInstance]
+ raise TypeError(
+ f"Invalid `http_client` argument; Expected an instance of `httpx.AsyncClient` but got {type(http_client)}"
+ )
+
+ super().__init__(
+ version=version,
+ base_url=base_url,
+ # cast to a valid type because mypy doesn't understand our type narrowing
+ timeout=cast(Timeout, timeout),
+ max_retries=max_retries,
+ custom_query=custom_query,
+ custom_headers=custom_headers,
+ _strict_response_validation=_strict_response_validation,
+ )
+ self._client = http_client or AsyncHttpxClientWrapper(
+ base_url=base_url,
+ # cast to a valid type because mypy doesn't understand our type narrowing
+ timeout=cast(Timeout, timeout),
+ # Used by generated `with_options(_extra_kwargs=...)` for HTTPX client configuration.
+ **kwargs,
+ )
+
+ def is_closed(self) -> bool:
+ return self._client.is_closed
+
+ async def close(self) -> None:
+ """Close the underlying HTTPX client.
+
+ The client will *not* be usable after this.
+ """
+ await self._client.aclose()
+
+ async def __aenter__(self: _T) -> _T:
+ return self
+
+ async def __aexit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc: BaseException | None,
+ exc_tb: TracebackType | None,
+ ) -> None:
+ await self.close()
+
+ async def _prepare_options(
+ self,
+ options: FinalRequestOptions, # noqa: ARG002
+ ) -> FinalRequestOptions:
+ """Hook for mutating the given options"""
+ return options
+
+ async def _prepare_request(
+ self,
+ request: httpx.Request, # noqa: ARG002
+ ) -> None:
+ """This method is used as a callback for mutating the `Request` object
+ after it has been constructed.
+ This is useful for cases where you want to add certain headers based off of
+ the request properties, e.g. `url`, `method` etc.
+ """
+ return None
+
+ @overload
+ async def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: Literal[False] = False,
+ ) -> ResponseT: ...
+
+ @overload
+ async def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: Literal[True],
+ stream_cls: type[_AsyncStreamT],
+ ) -> _AsyncStreamT: ...
+
+ @overload
+ async def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: bool,
+ stream_cls: type[_AsyncStreamT] | None = None,
+ ) -> ResponseT | _AsyncStreamT: ...
+
+ async def request(
+ self,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ *,
+ stream: bool = False,
+ stream_cls: type[_AsyncStreamT] | None = None,
+ ) -> ResponseT | _AsyncStreamT:
+ if self._platform is None:
+ # `get_platform` can make blocking IO calls so we
+ # execute it earlier while we are in an async context
+ self._platform = await asyncify(get_platform)()
+
+ cast_to = self._maybe_override_cast_to(cast_to, options)
+
+ # create a copy of the options we were given so that if the
+ # options are mutated later & we then retry, the retries are
+ # given the original options
+ input_options = model_copy(options)
+ if input_options.idempotency_key is None and input_options.method.lower() != "get":
+ # ensure the idempotency key is reused between requests
+ input_options.idempotency_key = self._idempotency_key()
+
+ response: httpx.Response | None = None
+ max_retries = input_options.get_max_retries(self.max_retries)
+
+ retries_taken = 0
+ for retries_taken in range(max_retries + 1):
+ options = model_copy(input_options)
+ options = await self._prepare_options(options)
+
+ remaining_retries = max_retries - retries_taken
+ request = self._build_request(options, retries_taken=retries_taken)
+ await self._prepare_request(request)
+
+ kwargs: HttpxSendArgs = {}
+ if self.custom_auth is not None:
+ kwargs["auth"] = self.custom_auth
+
+ if options.follow_redirects is not None:
+ kwargs["follow_redirects"] = options.follow_redirects
+
+ log.debug("Sending HTTP Request: %s %s", request.method, request.url)
+
+ response = None
+ try:
+ response = await self._client.send(
+ request,
+ stream=stream or self._should_stream_response_body(request=request),
+ **kwargs,
+ )
+ except httpx.TimeoutException as err:
+ log.debug("Encountered httpx.TimeoutException", exc_info=True)
+
+ if remaining_retries > 0:
+ await self._sleep_for_retry(
+ retries_taken=retries_taken,
+ max_retries=max_retries,
+ options=input_options,
+ response=None,
+ )
+ continue
+
+ log.debug("Raising timeout error")
+ raise APITimeoutError(request=request) from err
+ except Exception as err:
+ log.debug("Encountered Exception", exc_info=True)
+
+ if remaining_retries > 0:
+ await self._sleep_for_retry(
+ retries_taken=retries_taken,
+ max_retries=max_retries,
+ options=input_options,
+ response=None,
+ )
+ continue
+
+ log.debug("Raising connection error")
+ raise APIConnectionError(request=request) from err
+
+ log.debug(
+ 'HTTP Response: %s %s "%i %s" %s',
+ request.method,
+ request.url,
+ response.status_code,
+ response.reason_phrase,
+ response.headers,
+ )
+
+ try:
+ response.raise_for_status()
+ except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
+ log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
+
+ if remaining_retries > 0 and self._should_retry(err.response):
+ await err.response.aclose()
+ await self._sleep_for_retry(
+ retries_taken=retries_taken,
+ max_retries=max_retries,
+ options=input_options,
+ response=response,
+ )
+ continue
+
+ # If the response is streamed then we need to explicitly read the response
+ # to completion before attempting to access the response text.
+ if not err.response.is_closed:
+ await err.response.aread()
+
+ log.debug("Re-raising status error")
+ raise self._make_status_error_from_response(err.response) from None
+
+ break
+
+ assert response is not None, "could not resolve response (should never happen)"
+ return await self._process_response(
+ cast_to=cast_to,
+ options=options,
+ response=response,
+ stream=stream,
+ stream_cls=stream_cls,
+ retries_taken=retries_taken,
+ )
+
+ async def _sleep_for_retry(
+ self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None
+ ) -> None:
+ remaining_retries = max_retries - retries_taken
+ if remaining_retries == 1:
+ log.debug("1 retry left")
+ else:
+ log.debug("%i retries left", remaining_retries)
+
+ timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None)
+ log.info("Retrying request to %s in %f seconds", options.url, timeout)
+
+ await anyio.sleep(timeout)
+
+ async def _process_response(
+ self,
+ *,
+ cast_to: Type[ResponseT],
+ options: FinalRequestOptions,
+ response: httpx.Response,
+ stream: bool,
+ stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
+ retries_taken: int = 0,
+ ) -> ResponseT:
+ origin = get_origin(cast_to) or cast_to
+
+ if (
+ inspect.isclass(origin)
+ and issubclass(origin, BaseAPIResponse)
+ # we only want to actually return the custom BaseAPIResponse class if we're
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
+ ):
+ if not issubclass(origin, AsyncAPIResponse):
+ raise TypeError(f"API Response types must subclass {AsyncAPIResponse}; Received {origin}")
+
+ response_cls = cast("type[BaseAPIResponse[Any]]", cast_to)
+ return cast(
+ "ResponseT",
+ response_cls(
+ raw=response,
+ client=self,
+ cast_to=extract_response_type(response_cls),
+ stream=stream,
+ stream_cls=stream_cls,
+ options=options,
+ retries_taken=retries_taken,
+ ),
+ )
+
+ if cast_to == httpx.Response:
+ return cast(ResponseT, response)
+
+ api_response = AsyncAPIResponse(
+ raw=response,
+ client=self,
+ cast_to=cast("type[ResponseT]", cast_to), # pyright: ignore[reportUnnecessaryCast]
+ stream=stream,
+ stream_cls=stream_cls,
+ options=options,
+ retries_taken=retries_taken,
+ )
+ if bool(response.request.headers.get(RAW_RESPONSE_HEADER)):
+ return cast(ResponseT, api_response)
+
+ return await api_response.parse()
+
+ def _request_api_list(
+ self,
+ model: Type[_T],
+ page: Type[AsyncPageT],
+ options: FinalRequestOptions,
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> AsyncPaginator[_T, AsyncPageT]:
+ return AsyncPaginator(
+ client=self, options=options, page_cls=page, model=model, cursor_config=cursor_config
+ )
+
+ @overload
+ async def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: Literal[False] = False,
+ ) -> ResponseT: ...
+
+ @overload
+ async def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: Literal[True],
+ stream_cls: type[_AsyncStreamT],
+ ) -> _AsyncStreamT: ...
+
+ @overload
+ async def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: bool,
+ stream_cls: type[_AsyncStreamT] | None = None,
+ ) -> ResponseT | _AsyncStreamT: ...
+
+ async def get(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ options: RequestOptions = {},
+ stream: bool = False,
+ stream_cls: type[_AsyncStreamT] | None = None,
+ ) -> ResponseT | _AsyncStreamT:
+ opts = FinalRequestOptions.construct(method="get", url=path, **options)
+ return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
+
+ @overload
+ async def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ stream: Literal[False] = False,
+ ) -> ResponseT: ...
+
+ @overload
+ async def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ stream: Literal[True],
+ stream_cls: type[_AsyncStreamT],
+ ) -> _AsyncStreamT: ...
+
+ @overload
+ async def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ stream: bool,
+ stream_cls: type[_AsyncStreamT] | None = None,
+ ) -> ResponseT | _AsyncStreamT: ...
+
+ async def post(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ stream: bool = False,
+ stream_cls: type[_AsyncStreamT] | None = None,
+ ) -> ResponseT | _AsyncStreamT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(
+ method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
+ )
+ return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
+
+ async def patch(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ ) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(
+ method="patch",
+ url=path,
+ json_data=body,
+ content=content,
+ files=await async_to_httpx_files(files),
+ **options,
+ )
+ return await self.request(cast_to, opts)
+
+ async def put(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ files: RequestFiles | None = None,
+ options: RequestOptions = {},
+ ) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if files is not None and content is not None:
+ raise TypeError("Passing both `files` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(
+ method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
+ )
+ return await self.request(cast_to, opts)
+
+ async def delete(
+ self,
+ path: str,
+ *,
+ cast_to: Type[ResponseT],
+ body: Body | None = None,
+ content: AsyncBinaryTypes | None = None,
+ options: RequestOptions = {},
+ ) -> ResponseT:
+ if body is not None and content is not None:
+ raise TypeError("Passing both `body` and `content` is not supported")
+ if isinstance(body, bytes):
+ warnings.warn(
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
+ "Please pass raw bytes via the `content` parameter instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
+ return await self.request(cast_to, opts)
+
+ def get_api_list(
+ self,
+ path: str,
+ *,
+ model: Type[_T],
+ page: Type[AsyncPageT],
+ body: Body | None = None,
+ options: RequestOptions = {},
+ method: str = "get",
+ cursor_config: Optional[CursorPageConfig] = None,
+ ) -> AsyncPaginator[_T, AsyncPageT]:
+ opts = FinalRequestOptions.construct(method=method, url=path, json_data=body, **options)
+ return self._request_api_list(model, page, opts, cursor_config=cursor_config)
+
+
+def make_request_options(
+ *,
+ query: Query | None = None,
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ idempotency_key: str | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ post_parser: PostParser | NotGiven = not_given,
+ security: SecurityOptions | None = None,
+) -> RequestOptions:
+ """Create a dict of type RequestOptions without keys of NotGiven values."""
+ options: RequestOptions = {}
+ if extra_headers is not None:
+ options["headers"] = extra_headers
+
+ if extra_body is not None:
+ options["extra_json"] = cast(AnyMapping, extra_body)
+
+ if query is not None:
+ options["params"] = query
+
+ if extra_query is not None:
+ options["params"] = {**options.get("params", {}), **extra_query}
+
+ if not isinstance(timeout, NotGiven):
+ options["timeout"] = timeout
+
+ if idempotency_key is not None:
+ options["idempotency_key"] = idempotency_key
+
+ if is_given(post_parser):
+ # internal
+ options["post_parser"] = post_parser # type: ignore
+
+ if security is not None:
+ options["security"] = security
+
+ return options
+
+
+class ForceMultipartDict(Dict[str, None]):
+ def __bool__(self) -> bool:
+ return True
+
+
+class OtherPlatform:
+ def __init__(self, name: str) -> None:
+ self.name = name
+
+ @override
+ def __str__(self) -> str:
+ return f"Other:{self.name}"
+
+
+Platform = Union[
+ OtherPlatform,
+ Literal[
+ "MacOS",
+ "Linux",
+ "Windows",
+ "FreeBSD",
+ "OpenBSD",
+ "iOS",
+ "Android",
+ "Unknown",
+ ],
+]
+
+
+def get_platform() -> Platform:
+ try:
+ system = platform.system().lower()
+ platform_name = platform.platform().lower()
+ except Exception:
+ return "Unknown"
+
+ if "iphone" in platform_name or "ipad" in platform_name:
+ # Tested using Python3IDE on an iPhone 11 and Pythonista on an iPad 7
+ # system is Darwin and platform_name is a string like:
+ # - Darwin-21.6.0-iPhone12,1-64bit
+ # - Darwin-21.6.0-iPad7,11-64bit
+ return "iOS"
+
+ if system == "darwin":
+ return "MacOS"
+
+ if system == "windows":
+ return "Windows"
+
+ if "android" in platform_name:
+ # Tested using Pydroid 3
+ # system is Linux and platform_name is a string like 'Linux-5.10.81-android12-9-00001-geba40aecb3b7-ab8534902-aarch64-with-libc'
+ return "Android"
+
+ if system == "linux":
+ # https://distro.readthedocs.io/en/latest/#distro.id
+ distro_id = distro.id()
+ if distro_id == "freebsd":
+ return "FreeBSD"
+
+ if distro_id == "openbsd":
+ return "OpenBSD"
+
+ return "Linux"
+
+ if platform_name:
+ return OtherPlatform(platform_name)
+
+ return "Unknown"
+
+
+@lru_cache(maxsize=None)
+def platform_headers(version: str, *, platform: Platform | None) -> Dict[str, str]:
+ return {
+ "X-Scalar-Lang": "python",
+ "X-Scalar-Package-Version": version,
+ "X-Scalar-OS": str(platform or get_platform()),
+ "X-Scalar-Arch": str(get_architecture()),
+ "X-Scalar-Runtime": get_python_runtime(),
+ "X-Scalar-Runtime-Version": get_python_version(),
+ }
+
+
+class OtherArch:
+ def __init__(self, name: str) -> None:
+ self.name = name
+
+ @override
+ def __str__(self) -> str:
+ return f"other:{self.name}"
+
+
+Arch = Union[OtherArch, Literal["x32", "x64", "arm", "arm64", "unknown"]]
+
+
+def get_python_runtime() -> str:
+ try:
+ return platform.python_implementation()
+ except Exception:
+ return "unknown"
+
+
+def get_python_version() -> str:
+ try:
+ return platform.python_version()
+ except Exception:
+ return "unknown"
+
+
+def get_architecture() -> Arch:
+ try:
+ machine = platform.machine().lower()
+ except Exception:
+ return "unknown"
+
+ if machine in ("arm64", "aarch64"):
+ return "arm64"
+
+ # TODO: untested
+ if machine == "arm":
+ return "arm"
+
+ if machine == "x86_64":
+ return "x64"
+
+ # TODO: untested
+ if sys.maxsize <= 2**32:
+ return "x32"
+
+ if machine:
+ return OtherArch(machine)
+
+ return "unknown"
+
+
+def _merge_mappings(
+ obj1: Mapping[_T_co, Union[_T, Omit]],
+ obj2: Mapping[_T_co, Union[_T, Omit]],
+) -> Dict[_T_co, _T]:
+ """Merge two mappings of the same type, removing any values that are instances of `Omit`.
+
+ In cases with duplicate keys the second mapping takes precedence.
+ """
+ merged = {**obj1, **obj2}
+ return {key: value for key, value in merged.items() if not isinstance(value, Omit)}
diff --git a/src/_client.py b/src/_client.py
new file mode 100644
index 0000000..7097de1
--- /dev/null
+++ b/src/_client.py
@@ -0,0 +1,794 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import os
+import threading
+from typing import TYPE_CHECKING, Any, Mapping
+from typing_extensions import Literal, Self, override
+
+import httpx
+
+from . import _exceptions
+from ._qs import Querystring
+from ._types import (
+ Omit,
+ Headers,
+ Timeout,
+ NotGiven,
+ Transport,
+ ProxiesTypes,
+ RequestOptions,
+ not_given,
+)
+from ._utils import is_given, is_mapping_t, get_async_library
+from ._compat import cached_property
+from ._exceptions import APIStatusError
+from ._base_client import (
+ DEFAULT_MAX_RETRIES,
+ SyncAPIClient,
+ AsyncAPIClient,
+)
+from ._streaming import Stream as Stream, AsyncStream as AsyncStream
+from ._version import __version__
+
+if TYPE_CHECKING:
+ from .resources.registry import RegistryResource, AsyncRegistryResource
+ from .resources.schemas import SchemasResource, AsyncSchemasResource
+ from .resources.login_portals import LoginPortalsResource, AsyncLoginPortalsResource
+ from .resources.rules import RulesResource, AsyncRulesResource
+ from .resources.themes import ThemesResource, AsyncThemesResource
+ from .resources.teams import TeamsResource, AsyncTeamsResource
+ from .resources.scalar_docs import ScalarDocsResource, AsyncScalarDocsResource
+ from .resources.namespaces import NamespacesResource, AsyncNamespacesResource
+ from .resources.authentication import AuthenticationResource, AsyncAuthenticationResource
+
+# Serializes lazy resource imports so concurrent cold access from multiple
+# threads cannot deadlock on CPython import locks (see CPython 3.14).
+_RESOURCE_IMPORT_LOCK = threading.RLock()
+
+ENVIRONMENTS: dict[str, str] = {
+ "production": "https://access.scalar.com",
+ "local": "http://127.0.0.1:4010",
+}
+
+__all__ = ["ENVIRONMENTS", "ScalarApi", "AsyncScalarApi", "Client", "AsyncClient", "Timeout", "Transport", "ProxiesTypes", "RequestOptions"]
+
+
+class ScalarApi(SyncAPIClient):
+ # client options
+ bearer_auth: str | None
+
+ def __init__(
+ self,
+ *,
+ bearer_auth: str | None = None,
+ environment: Literal["production", "local"] | NotGiven = not_given,
+ base_url: str | httpx.URL | None | NotGiven = not_given,
+ timeout: float | Timeout | None | NotGiven = not_given,
+ max_retries: int = DEFAULT_MAX_RETRIES,
+ default_headers: Mapping[str, str] | None = None,
+ default_query: Mapping[str, object] | None = None,
+ http_client: httpx.Client | None = None,
+ _strict_response_validation: bool = False,
+ **kwargs: Any,
+ ) -> None:
+ if bearer_auth is None:
+ bearer_auth = os.environ.get("BEARER_AUTH")
+ self.bearer_auth = bearer_auth
+ self._environment = environment
+ base_url_env = os.environ.get("SCALAR_BASE_URL")
+ if is_given(base_url) and base_url is not None:
+ if is_given(environment):
+ raise ValueError(
+ "Ambiguous URL; the `base_url` and `environment` arguments are both set. Pass `base_url=None` to use the environment.",
+ )
+ elif is_given(environment):
+ if base_url_env and base_url is not None:
+ raise ValueError(
+ "Ambiguous URL; the base URL environment variable and the `environment` argument are both set. Pass base_url=None to use the environment.",
+ )
+ try:
+ base_url = ENVIRONMENTS[environment]
+ except KeyError as exc:
+ raise ValueError(f"Unknown environment: {environment}") from exc
+ elif base_url_env is not None:
+ base_url = base_url_env
+ else:
+ self._environment = environment = "production"
+ try:
+ base_url = ENVIRONMENTS[environment]
+ except KeyError as exc:
+ raise ValueError(f"Unknown environment: {environment}") from exc
+ # Extra keyword args flow through `with_options(_extra_kwargs=...)` to the default HTTPX client.
+ super().__init__(
+ version=__version__,
+ base_url=base_url,
+ max_retries=max_retries,
+ timeout=timeout,
+ http_client=http_client,
+ custom_headers=default_headers,
+ custom_query=default_query,
+ _strict_response_validation=_strict_response_validation,
+ **kwargs,
+ )
+ self._idempotency_header = "Idempotency-Key"
+ self._default_stream_cls = Stream
+ self._streaming_handlers: list[dict[str, object]] = []
+
+ @cached_property
+ def registry(self) -> "RegistryResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.registry import RegistryResource
+ return RegistryResource(self)
+
+ @cached_property
+ def schemas(self) -> "SchemasResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.schemas import SchemasResource
+ return SchemasResource(self)
+
+ @cached_property
+ def login_portals(self) -> "LoginPortalsResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.login_portals import LoginPortalsResource
+ return LoginPortalsResource(self)
+
+ @cached_property
+ def rules(self) -> "RulesResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.rules import RulesResource
+ return RulesResource(self)
+
+ @cached_property
+ def themes(self) -> "ThemesResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.themes import ThemesResource
+ return ThemesResource(self)
+
+ @cached_property
+ def teams(self) -> "TeamsResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.teams import TeamsResource
+ return TeamsResource(self)
+
+ @cached_property
+ def scalar_docs(self) -> "ScalarDocsResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.scalar_docs import ScalarDocsResource
+ return ScalarDocsResource(self)
+
+ @cached_property
+ def namespaces(self) -> "NamespacesResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.namespaces import NamespacesResource
+ return NamespacesResource(self)
+
+ @cached_property
+ def authentication(self) -> "AuthenticationResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.authentication import AuthenticationResource
+ return AuthenticationResource(self)
+
+ @cached_property
+ def with_raw_response(self) -> ScalarApiWithRawResponse:
+ return ScalarApiWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ScalarApiWithStreamingResponse:
+ return ScalarApiWithStreamingResponse(self)
+
+ def copy(
+ self,
+ *,
+ bearer_auth: str | None = None,
+ environment: str | None = None,
+ base_url: str | httpx.URL | None = None,
+ timeout: float | Timeout | None | NotGiven = not_given,
+ http_client: httpx.Client | None = None,
+ max_retries: int | NotGiven = not_given,
+ default_headers: Mapping[str, str] | None = None,
+ set_default_headers: Mapping[str, str] | None = None,
+ default_query: Mapping[str, object] | None = None,
+ set_default_query: Mapping[str, object] | None = None,
+ _extra_kwargs: Mapping[str, Any] | None = None,
+ ) -> Self:
+ """Create a new client reusing this client's options with optional overrides."""
+ if default_headers is not None and set_default_headers is not None:
+ raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")
+ if default_query is not None and set_default_query is not None:
+ raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")
+ headers = self._custom_headers
+ if default_headers is not None:
+ headers = {**headers, **default_headers}
+ elif set_default_headers is not None:
+ headers = set_default_headers
+ params = self._custom_query
+ if default_query is not None:
+ params = {**params, **default_query}
+ elif set_default_query is not None:
+ params = set_default_query
+ http_client = http_client or self._client
+ copied_base_url = base_url if base_url is not None else self.base_url
+ # Environment overrides must resolve their own URL instead of reusing this client's host.
+ if environment is not None and base_url is None:
+ copied_base_url = None
+ return self.__class__(
+ bearer_auth=bearer_auth if bearer_auth is not None else self.bearer_auth,
+ environment=environment if environment is not None else self._environment,
+ base_url=copied_base_url,
+ timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
+ http_client=http_client,
+ max_retries=max_retries if is_given(max_retries) else self.max_retries,
+ default_headers=headers,
+ default_query=params,
+ _strict_response_validation=self._strict_response_validation,
+ **(_extra_kwargs or {}),
+ )
+
+ with_options = copy
+
+ @property
+ @override
+ def qs(self) -> Querystring:
+ return Querystring(array_format="repeat")
+
+ @override
+ def _auth_headers(self, security: dict[str, bool]) -> dict[str, str]:
+ _ = security
+ return {
+ **self._bearer_auth_header_auth,
+ }
+
+ @override
+ def _auth_query(self, security: dict[str, bool]) -> dict[str, str]:
+ _ = security
+ return {
+ }
+
+ @override
+ def _auth_cookies(self, security: dict[str, bool]) -> dict[str, str]:
+ _ = security
+ return {
+ }
+
+ @property
+ def _bearer_auth_header_auth(self) -> dict[str, str]:
+ value = self.bearer_auth
+ if value is None:
+ return {}
+ return {"Authorization": f"Bearer {value}"}
+
+
+ @override
+ def _validate_headers(
+ self,
+ headers: Headers,
+ custom_headers: Headers,
+ params: Mapping[str, object],
+ cookies: Mapping[str, str],
+ ) -> None:
+ if headers.get("Authorization"):
+ return
+ if isinstance(custom_headers.get("Authorization"), Omit):
+ return
+ raise TypeError("Could not resolve authentication method. Expected Authorization to be set.")
+
+ @property
+ @override
+ def default_headers(self) -> dict[str, str | Omit]:
+ return {
+ **super().default_headers,
+ "X-Scalar-Async": "false",
+ **self._custom_headers,
+ }
+
+ @override
+ def _make_status_error(self, err_msg: str, *, body: object, response: httpx.Response) -> APIStatusError:
+ if response.status_code == 400:
+ return _exceptions.BadRequestError(err_msg, response=response, body=body)
+ if response.status_code == 401:
+ return _exceptions.AuthenticationError(err_msg, response=response, body=body)
+ if response.status_code == 403:
+ return _exceptions.PermissionDeniedError(err_msg, response=response, body=body)
+ if response.status_code == 404:
+ return _exceptions.NotFoundError(err_msg, response=response, body=body)
+ if response.status_code == 409:
+ return _exceptions.ConflictError(err_msg, response=response, body=body)
+ if response.status_code == 422:
+ return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body)
+ if response.status_code == 429:
+ return _exceptions.RateLimitError(err_msg, response=response, body=body)
+ if response.status_code >= 500:
+ return _exceptions.InternalServerError(err_msg, response=response, body=body)
+ return APIStatusError(err_msg, response=response, body=body)
+
+
+class AsyncScalarApi(AsyncAPIClient):
+ # client options
+ bearer_auth: str | None
+
+ def __init__(
+ self,
+ *,
+ bearer_auth: str | None = None,
+ environment: Literal["production", "local"] | NotGiven = not_given,
+ base_url: str | httpx.URL | None | NotGiven = not_given,
+ timeout: float | Timeout | None | NotGiven = not_given,
+ max_retries: int = DEFAULT_MAX_RETRIES,
+ default_headers: Mapping[str, str] | None = None,
+ default_query: Mapping[str, object] | None = None,
+ http_client: httpx.AsyncClient | None = None,
+ _strict_response_validation: bool = False,
+ **kwargs: Any,
+ ) -> None:
+ if bearer_auth is None:
+ bearer_auth = os.environ.get("BEARER_AUTH")
+ self.bearer_auth = bearer_auth
+ self._environment = environment
+ base_url_env = os.environ.get("SCALAR_BASE_URL")
+ if is_given(base_url) and base_url is not None:
+ if is_given(environment):
+ raise ValueError(
+ "Ambiguous URL; the `base_url` and `environment` arguments are both set. Pass `base_url=None` to use the environment.",
+ )
+ elif is_given(environment):
+ if base_url_env and base_url is not None:
+ raise ValueError(
+ "Ambiguous URL; the base URL environment variable and the `environment` argument are both set. Pass base_url=None to use the environment.",
+ )
+ try:
+ base_url = ENVIRONMENTS[environment]
+ except KeyError as exc:
+ raise ValueError(f"Unknown environment: {environment}") from exc
+ elif base_url_env is not None:
+ base_url = base_url_env
+ else:
+ self._environment = environment = "production"
+ try:
+ base_url = ENVIRONMENTS[environment]
+ except KeyError as exc:
+ raise ValueError(f"Unknown environment: {environment}") from exc
+ # Extra keyword args flow through `with_options(_extra_kwargs=...)` to the default HTTPX client.
+ super().__init__(
+ version=__version__,
+ base_url=base_url,
+ max_retries=max_retries,
+ timeout=timeout,
+ http_client=http_client,
+ custom_headers=default_headers,
+ custom_query=default_query,
+ _strict_response_validation=_strict_response_validation,
+ **kwargs,
+ )
+ self._idempotency_header = "Idempotency-Key"
+ self._default_stream_cls = AsyncStream
+ self._streaming_handlers: list[dict[str, object]] = []
+
+ @cached_property
+ def registry(self) -> "AsyncRegistryResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.registry import AsyncRegistryResource
+ return AsyncRegistryResource(self)
+
+ @cached_property
+ def schemas(self) -> "AsyncSchemasResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.schemas import AsyncSchemasResource
+ return AsyncSchemasResource(self)
+
+ @cached_property
+ def login_portals(self) -> "AsyncLoginPortalsResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.login_portals import AsyncLoginPortalsResource
+ return AsyncLoginPortalsResource(self)
+
+ @cached_property
+ def rules(self) -> "AsyncRulesResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.rules import AsyncRulesResource
+ return AsyncRulesResource(self)
+
+ @cached_property
+ def themes(self) -> "AsyncThemesResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.themes import AsyncThemesResource
+ return AsyncThemesResource(self)
+
+ @cached_property
+ def teams(self) -> "AsyncTeamsResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.teams import AsyncTeamsResource
+ return AsyncTeamsResource(self)
+
+ @cached_property
+ def scalar_docs(self) -> "AsyncScalarDocsResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.scalar_docs import AsyncScalarDocsResource
+ return AsyncScalarDocsResource(self)
+
+ @cached_property
+ def namespaces(self) -> "AsyncNamespacesResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.namespaces import AsyncNamespacesResource
+ return AsyncNamespacesResource(self)
+
+ @cached_property
+ def authentication(self) -> "AsyncAuthenticationResource":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.authentication import AsyncAuthenticationResource
+ return AsyncAuthenticationResource(self)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncScalarApiWithRawResponse:
+ return AsyncScalarApiWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncScalarApiWithStreamingResponse:
+ return AsyncScalarApiWithStreamingResponse(self)
+
+ def copy(
+ self,
+ *,
+ bearer_auth: str | None = None,
+ environment: str | None = None,
+ base_url: str | httpx.URL | None = None,
+ timeout: float | Timeout | None | NotGiven = not_given,
+ http_client: httpx.AsyncClient | None = None,
+ max_retries: int | NotGiven = not_given,
+ default_headers: Mapping[str, str] | None = None,
+ set_default_headers: Mapping[str, str] | None = None,
+ default_query: Mapping[str, object] | None = None,
+ set_default_query: Mapping[str, object] | None = None,
+ _extra_kwargs: Mapping[str, Any] | None = None,
+ ) -> Self:
+ """Create a new client reusing this client's options with optional overrides."""
+ if default_headers is not None and set_default_headers is not None:
+ raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")
+ if default_query is not None and set_default_query is not None:
+ raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")
+ headers = self._custom_headers
+ if default_headers is not None:
+ headers = {**headers, **default_headers}
+ elif set_default_headers is not None:
+ headers = set_default_headers
+ params = self._custom_query
+ if default_query is not None:
+ params = {**params, **default_query}
+ elif set_default_query is not None:
+ params = set_default_query
+ http_client = http_client or self._client
+ copied_base_url = base_url if base_url is not None else self.base_url
+ # Environment overrides must resolve their own URL instead of reusing this client's host.
+ if environment is not None and base_url is None:
+ copied_base_url = None
+ return self.__class__(
+ bearer_auth=bearer_auth if bearer_auth is not None else self.bearer_auth,
+ environment=environment if environment is not None else self._environment,
+ base_url=copied_base_url,
+ timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
+ http_client=http_client,
+ max_retries=max_retries if is_given(max_retries) else self.max_retries,
+ default_headers=headers,
+ default_query=params,
+ _strict_response_validation=self._strict_response_validation,
+ **(_extra_kwargs or {}),
+ )
+
+ with_options = copy
+
+ @property
+ @override
+ def qs(self) -> Querystring:
+ return Querystring(array_format="repeat")
+
+ @override
+ def _auth_headers(self, security: dict[str, bool]) -> dict[str, str]:
+ _ = security
+ return {
+ **self._bearer_auth_header_auth,
+ }
+
+ @override
+ def _auth_query(self, security: dict[str, bool]) -> dict[str, str]:
+ _ = security
+ return {
+ }
+
+ @override
+ def _auth_cookies(self, security: dict[str, bool]) -> dict[str, str]:
+ _ = security
+ return {
+ }
+
+ @property
+ def _bearer_auth_header_auth(self) -> dict[str, str]:
+ value = self.bearer_auth
+ if value is None:
+ return {}
+ return {"Authorization": f"Bearer {value}"}
+
+
+ @override
+ def _validate_headers(
+ self,
+ headers: Headers,
+ custom_headers: Headers,
+ params: Mapping[str, object],
+ cookies: Mapping[str, str],
+ ) -> None:
+ if headers.get("Authorization"):
+ return
+ if isinstance(custom_headers.get("Authorization"), Omit):
+ return
+ raise TypeError("Could not resolve authentication method. Expected Authorization to be set.")
+
+ @property
+ @override
+ def default_headers(self) -> dict[str, str | Omit]:
+ return {
+ **super().default_headers,
+ "X-Scalar-Async": f"async:{get_async_library()}",
+ **self._custom_headers,
+ }
+
+ @override
+ def _make_status_error(self, err_msg: str, *, body: object, response: httpx.Response) -> APIStatusError:
+ if response.status_code == 400:
+ return _exceptions.BadRequestError(err_msg, response=response, body=body)
+ if response.status_code == 401:
+ return _exceptions.AuthenticationError(err_msg, response=response, body=body)
+ if response.status_code == 403:
+ return _exceptions.PermissionDeniedError(err_msg, response=response, body=body)
+ if response.status_code == 404:
+ return _exceptions.NotFoundError(err_msg, response=response, body=body)
+ if response.status_code == 409:
+ return _exceptions.ConflictError(err_msg, response=response, body=body)
+ if response.status_code == 422:
+ return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body)
+ if response.status_code == 429:
+ return _exceptions.RateLimitError(err_msg, response=response, body=body)
+ if response.status_code >= 500:
+ return _exceptions.InternalServerError(err_msg, response=response, body=body)
+ return APIStatusError(err_msg, response=response, body=body)
+
+
+class ScalarApiWithRawResponse:
+ def __init__(self, client: ScalarApi) -> None:
+ self._client = client
+
+ @cached_property
+ def registry(self) -> "RegistryResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.registry import RegistryResourceWithRawResponse
+ return RegistryResourceWithRawResponse(self._client.registry)
+
+ @cached_property
+ def schemas(self) -> "SchemasResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.schemas import SchemasResourceWithRawResponse
+ return SchemasResourceWithRawResponse(self._client.schemas)
+
+ @cached_property
+ def login_portals(self) -> "LoginPortalsResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.login_portals import LoginPortalsResourceWithRawResponse
+ return LoginPortalsResourceWithRawResponse(self._client.login_portals)
+
+ @cached_property
+ def rules(self) -> "RulesResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.rules import RulesResourceWithRawResponse
+ return RulesResourceWithRawResponse(self._client.rules)
+
+ @cached_property
+ def themes(self) -> "ThemesResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.themes import ThemesResourceWithRawResponse
+ return ThemesResourceWithRawResponse(self._client.themes)
+
+ @cached_property
+ def teams(self) -> "TeamsResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.teams import TeamsResourceWithRawResponse
+ return TeamsResourceWithRawResponse(self._client.teams)
+
+ @cached_property
+ def scalar_docs(self) -> "ScalarDocsResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.scalar_docs import ScalarDocsResourceWithRawResponse
+ return ScalarDocsResourceWithRawResponse(self._client.scalar_docs)
+
+ @cached_property
+ def namespaces(self) -> "NamespacesResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.namespaces import NamespacesResourceWithRawResponse
+ return NamespacesResourceWithRawResponse(self._client.namespaces)
+
+ @cached_property
+ def authentication(self) -> "AuthenticationResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.authentication import AuthenticationResourceWithRawResponse
+ return AuthenticationResourceWithRawResponse(self._client.authentication)
+
+
+class AsyncScalarApiWithRawResponse:
+ def __init__(self, client: AsyncScalarApi) -> None:
+ self._client = client
+
+ @cached_property
+ def registry(self) -> "AsyncRegistryResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.registry import AsyncRegistryResourceWithRawResponse
+ return AsyncRegistryResourceWithRawResponse(self._client.registry)
+
+ @cached_property
+ def schemas(self) -> "AsyncSchemasResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.schemas import AsyncSchemasResourceWithRawResponse
+ return AsyncSchemasResourceWithRawResponse(self._client.schemas)
+
+ @cached_property
+ def login_portals(self) -> "AsyncLoginPortalsResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.login_portals import AsyncLoginPortalsResourceWithRawResponse
+ return AsyncLoginPortalsResourceWithRawResponse(self._client.login_portals)
+
+ @cached_property
+ def rules(self) -> "AsyncRulesResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.rules import AsyncRulesResourceWithRawResponse
+ return AsyncRulesResourceWithRawResponse(self._client.rules)
+
+ @cached_property
+ def themes(self) -> "AsyncThemesResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.themes import AsyncThemesResourceWithRawResponse
+ return AsyncThemesResourceWithRawResponse(self._client.themes)
+
+ @cached_property
+ def teams(self) -> "AsyncTeamsResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.teams import AsyncTeamsResourceWithRawResponse
+ return AsyncTeamsResourceWithRawResponse(self._client.teams)
+
+ @cached_property
+ def scalar_docs(self) -> "AsyncScalarDocsResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.scalar_docs import AsyncScalarDocsResourceWithRawResponse
+ return AsyncScalarDocsResourceWithRawResponse(self._client.scalar_docs)
+
+ @cached_property
+ def namespaces(self) -> "AsyncNamespacesResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.namespaces import AsyncNamespacesResourceWithRawResponse
+ return AsyncNamespacesResourceWithRawResponse(self._client.namespaces)
+
+ @cached_property
+ def authentication(self) -> "AsyncAuthenticationResourceWithRawResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.authentication import AsyncAuthenticationResourceWithRawResponse
+ return AsyncAuthenticationResourceWithRawResponse(self._client.authentication)
+
+
+class ScalarApiWithStreamingResponse:
+ def __init__(self, client: ScalarApi) -> None:
+ self._client = client
+
+ @cached_property
+ def registry(self) -> "RegistryResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.registry import RegistryResourceWithStreamingResponse
+ return RegistryResourceWithStreamingResponse(self._client.registry)
+
+ @cached_property
+ def schemas(self) -> "SchemasResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.schemas import SchemasResourceWithStreamingResponse
+ return SchemasResourceWithStreamingResponse(self._client.schemas)
+
+ @cached_property
+ def login_portals(self) -> "LoginPortalsResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.login_portals import LoginPortalsResourceWithStreamingResponse
+ return LoginPortalsResourceWithStreamingResponse(self._client.login_portals)
+
+ @cached_property
+ def rules(self) -> "RulesResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.rules import RulesResourceWithStreamingResponse
+ return RulesResourceWithStreamingResponse(self._client.rules)
+
+ @cached_property
+ def themes(self) -> "ThemesResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.themes import ThemesResourceWithStreamingResponse
+ return ThemesResourceWithStreamingResponse(self._client.themes)
+
+ @cached_property
+ def teams(self) -> "TeamsResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.teams import TeamsResourceWithStreamingResponse
+ return TeamsResourceWithStreamingResponse(self._client.teams)
+
+ @cached_property
+ def scalar_docs(self) -> "ScalarDocsResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.scalar_docs import ScalarDocsResourceWithStreamingResponse
+ return ScalarDocsResourceWithStreamingResponse(self._client.scalar_docs)
+
+ @cached_property
+ def namespaces(self) -> "NamespacesResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.namespaces import NamespacesResourceWithStreamingResponse
+ return NamespacesResourceWithStreamingResponse(self._client.namespaces)
+
+ @cached_property
+ def authentication(self) -> "AuthenticationResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.authentication import AuthenticationResourceWithStreamingResponse
+ return AuthenticationResourceWithStreamingResponse(self._client.authentication)
+
+
+class AsyncScalarApiWithStreamingResponse:
+ def __init__(self, client: AsyncScalarApi) -> None:
+ self._client = client
+
+ @cached_property
+ def registry(self) -> "AsyncRegistryResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.registry import AsyncRegistryResourceWithStreamingResponse
+ return AsyncRegistryResourceWithStreamingResponse(self._client.registry)
+
+ @cached_property
+ def schemas(self) -> "AsyncSchemasResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.schemas import AsyncSchemasResourceWithStreamingResponse
+ return AsyncSchemasResourceWithStreamingResponse(self._client.schemas)
+
+ @cached_property
+ def login_portals(self) -> "AsyncLoginPortalsResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.login_portals import AsyncLoginPortalsResourceWithStreamingResponse
+ return AsyncLoginPortalsResourceWithStreamingResponse(self._client.login_portals)
+
+ @cached_property
+ def rules(self) -> "AsyncRulesResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.rules import AsyncRulesResourceWithStreamingResponse
+ return AsyncRulesResourceWithStreamingResponse(self._client.rules)
+
+ @cached_property
+ def themes(self) -> "AsyncThemesResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.themes import AsyncThemesResourceWithStreamingResponse
+ return AsyncThemesResourceWithStreamingResponse(self._client.themes)
+
+ @cached_property
+ def teams(self) -> "AsyncTeamsResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.teams import AsyncTeamsResourceWithStreamingResponse
+ return AsyncTeamsResourceWithStreamingResponse(self._client.teams)
+
+ @cached_property
+ def scalar_docs(self) -> "AsyncScalarDocsResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.scalar_docs import AsyncScalarDocsResourceWithStreamingResponse
+ return AsyncScalarDocsResourceWithStreamingResponse(self._client.scalar_docs)
+
+ @cached_property
+ def namespaces(self) -> "AsyncNamespacesResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.namespaces import AsyncNamespacesResourceWithStreamingResponse
+ return AsyncNamespacesResourceWithStreamingResponse(self._client.namespaces)
+
+ @cached_property
+ def authentication(self) -> "AsyncAuthenticationResourceWithStreamingResponse":
+ with _RESOURCE_IMPORT_LOCK:
+ from .resources.authentication import AsyncAuthenticationResourceWithStreamingResponse
+ return AsyncAuthenticationResourceWithStreamingResponse(self._client.authentication)
+
+
+# Alias names for the documented `Client` / `AsyncClient` symbols.
+Client = ScalarApi
+AsyncClient = AsyncScalarApi
diff --git a/src/_compat.py b/src/_compat.py
new file mode 100644
index 0000000..e6690a4
--- /dev/null
+++ b/src/_compat.py
@@ -0,0 +1,226 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload
+from datetime import date, datetime
+from typing_extensions import Self, Literal, TypedDict
+
+import pydantic
+from pydantic.fields import FieldInfo
+
+from ._types import IncEx, StrBytesIntFloat
+
+_T = TypeVar("_T")
+_ModelT = TypeVar("_ModelT", bound=pydantic.BaseModel)
+
+# --------------- Pydantic v2, v3 compatibility ---------------
+
+# Pyright incorrectly reports some of our functions as overriding a method when they don't
+# pyright: reportIncompatibleMethodOverride=false
+
+PYDANTIC_V1 = pydantic.VERSION.startswith("1.")
+
+if TYPE_CHECKING:
+
+ def parse_date(value: date | StrBytesIntFloat) -> date: # noqa: ARG001
+ ...
+
+ def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime: # noqa: ARG001
+ ...
+
+ def get_args(t: type[Any]) -> tuple[Any, ...]: # noqa: ARG001
+ ...
+
+ def is_union(tp: type[Any] | None) -> bool: # noqa: ARG001
+ ...
+
+ def get_origin(t: type[Any]) -> type[Any] | None: # noqa: ARG001
+ ...
+
+ def is_literal_type(type_: type[Any]) -> bool: # noqa: ARG001
+ ...
+
+ def is_typeddict(type_: type[Any]) -> bool: # noqa: ARG001
+ ...
+
+else:
+ # v1 re-exports
+ if PYDANTIC_V1:
+ from pydantic.typing import (
+ get_args as get_args,
+ is_union as is_union,
+ get_origin as get_origin,
+ is_typeddict as is_typeddict,
+ is_literal_type as is_literal_type,
+ )
+ from pydantic.datetime_parse import parse_date as parse_date, parse_datetime as parse_datetime
+ else:
+ from ._utils import (
+ get_args as get_args,
+ is_union as is_union,
+ get_origin as get_origin,
+ parse_date as parse_date,
+ is_typeddict as is_typeddict,
+ parse_datetime as parse_datetime,
+ is_literal_type as is_literal_type,
+ )
+
+
+# refactored config
+if TYPE_CHECKING:
+ from pydantic import ConfigDict as ConfigDict
+else:
+ if PYDANTIC_V1:
+ # TODO: provide an error message here?
+ ConfigDict = None
+ else:
+ from pydantic import ConfigDict as ConfigDict
+
+
+# renamed methods / properties
+def parse_obj(model: type[_ModelT], value: object) -> _ModelT:
+ if PYDANTIC_V1:
+ return cast(_ModelT, model.parse_obj(value)) # pyright: ignore[reportDeprecated, reportUnnecessaryCast]
+ else:
+ return model.model_validate(value)
+
+
+def field_is_required(field: FieldInfo) -> bool:
+ if PYDANTIC_V1:
+ return field.required # type: ignore
+ return field.is_required()
+
+
+def field_get_default(field: FieldInfo) -> Any:
+ value = field.get_default()
+ if PYDANTIC_V1:
+ return value
+ from pydantic_core import PydanticUndefined
+
+ if value == PydanticUndefined:
+ return None
+ return value
+
+
+def field_outer_type(field: FieldInfo) -> Any:
+ if PYDANTIC_V1:
+ return field.outer_type_ # type: ignore
+ return field.annotation
+
+
+def get_model_config(model: type[pydantic.BaseModel]) -> Any:
+ if PYDANTIC_V1:
+ return model.__config__ # type: ignore
+ return model.model_config
+
+
+def get_model_fields(model: type[pydantic.BaseModel]) -> dict[str, FieldInfo]:
+ if PYDANTIC_V1:
+ return model.__fields__ # type: ignore
+ return model.model_fields
+
+
+def model_copy(model: _ModelT, *, deep: bool = False) -> _ModelT:
+ if PYDANTIC_V1:
+ return model.copy(deep=deep) # type: ignore
+ return model.model_copy(deep=deep)
+
+
+def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str:
+ if PYDANTIC_V1:
+ return model.json(indent=indent) # type: ignore
+ return model.model_dump_json(indent=indent)
+
+
+class _ModelDumpKwargs(TypedDict, total=False):
+ by_alias: bool
+
+
+def model_dump(
+ model: pydantic.BaseModel,
+ *,
+ exclude: IncEx | None = None,
+ exclude_unset: bool = False,
+ exclude_defaults: bool = False,
+ warnings: bool = True,
+ mode: Literal["json", "python"] = "python",
+ by_alias: bool | None = None,
+) -> dict[str, Any]:
+ if (not PYDANTIC_V1) or hasattr(model, "model_dump"):
+ kwargs: _ModelDumpKwargs = {}
+ if by_alias is not None:
+ kwargs["by_alias"] = by_alias
+ return model.model_dump(
+ mode=mode,
+ exclude=exclude,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ # warnings are not supported in Pydantic v1
+ warnings=True if PYDANTIC_V1 else warnings,
+ **kwargs,
+ )
+ return cast(
+ "dict[str, Any]",
+ model.dict( # pyright: ignore[reportDeprecated, reportUnnecessaryCast]
+ exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, by_alias=bool(by_alias)
+ ),
+ )
+
+
+def model_parse(model: type[_ModelT], data: Any) -> _ModelT:
+ if PYDANTIC_V1:
+ return model.parse_obj(data) # pyright: ignore[reportDeprecated]
+ return model.model_validate(data)
+
+
+# generic models
+if TYPE_CHECKING:
+
+ class GenericModel(pydantic.BaseModel): ...
+
+else:
+ if PYDANTIC_V1:
+ import pydantic.generics
+
+ class GenericModel(pydantic.generics.GenericModel, pydantic.BaseModel): ...
+ else:
+ # there no longer needs to be a distinction in v2 but
+ # we still have to create our own subclass to avoid
+ # inconsistent MRO ordering errors
+ class GenericModel(pydantic.BaseModel): ...
+
+
+# cached properties
+if TYPE_CHECKING:
+ cached_property = property
+
+ # we define a separate type (copied from typeshed)
+ # that represents that `cached_property` is `set`able
+ # at runtime, which differs from `@property`.
+ #
+ # this is a separate type as editors likely special case
+ # `@property` and we don't want to cause issues just to have
+ # more helpful internal types.
+
+ class typed_cached_property(Generic[_T]):
+ func: Callable[[Any], _T]
+ attrname: str | None
+
+ def __init__(self, func: Callable[[Any], _T]) -> None: ...
+
+ @overload
+ def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ...
+
+ @overload
+ def __get__(self, instance: object, owner: type[Any] | None = None) -> _T: ...
+
+ def __get__(self, instance: object, owner: type[Any] | None = None) -> _T | Self:
+ raise NotImplementedError()
+
+ def __set_name__(self, owner: type[Any], name: str) -> None: ...
+
+ # __set__ is not defined at runtime, but @cached_property is designed to be settable
+ def __set__(self, instance: object, value: _T) -> None: ...
+else:
+ from functools import cached_property as cached_property
+
+ typed_cached_property = cached_property
diff --git a/src/_constants.py b/src/_constants.py
new file mode 100644
index 0000000..969d075
--- /dev/null
+++ b/src/_constants.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See CONTRIBUTING.md for details.
+
+import httpx
+
+RAW_RESPONSE_HEADER = "X-Scalar-Raw-Response"
+OVERRIDE_CAST_TO_HEADER = "____scalar_override_cast_to"
+
+# default timeout is 1 minute
+DEFAULT_TIMEOUT = httpx.Timeout(timeout=60, connect=5.0)
+DEFAULT_MAX_RETRIES = 2
+DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20)
+
+INITIAL_RETRY_DELAY = 0.5
+MAX_RETRY_DELAY = 8.0
diff --git a/src/_event_handler.py b/src/_event_handler.py
new file mode 100644
index 0000000..d84a24d
--- /dev/null
+++ b/src/_event_handler.py
@@ -0,0 +1,85 @@
+# File generated from our OpenAPI spec by Scalar. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import threading
+from typing import Any, Callable
+
+EventHandler = Callable[..., Any]
+
+
+class EventHandlerRegistry:
+ """Thread-safe (optional) registry of event handlers."""
+
+ def __init__(self, *, use_lock: bool = False) -> None:
+ self._handlers: dict[str, list[EventHandler]] = {}
+ self._once_ids: set[int] = set()
+ self._lock: threading.Lock | None = threading.Lock() if use_lock else None
+
+ def _acquire(self) -> None:
+ if self._lock is not None:
+ self._lock.acquire()
+
+ def _release(self) -> None:
+ if self._lock is not None:
+ self._lock.release()
+
+ def add(self, event_type: str, handler: EventHandler, *, once: bool = False) -> None:
+ self._acquire()
+ try:
+ handlers = self._handlers.setdefault(event_type, [])
+ handlers.append(handler)
+ if once:
+ self._once_ids.add(id(handler))
+ finally:
+ self._release()
+
+ def remove(self, event_type: str, handler: EventHandler) -> None:
+ self._acquire()
+ try:
+ handlers = self._handlers.get(event_type)
+ if handlers is not None:
+ try:
+ handlers.remove(handler)
+ except ValueError:
+ pass
+ self._once_ids.discard(id(handler))
+ finally:
+ self._release()
+
+ def get_handlers(self, event_type: str) -> list[EventHandler]:
+ """Return a snapshot of handlers for the given event type, removing once-handlers."""
+ self._acquire()
+ try:
+ handlers = self._handlers.get(event_type)
+ if not handlers:
+ return []
+ result = list(handlers)
+ to_remove = [h for h in result if id(h) in self._once_ids]
+ for h in to_remove:
+ handlers.remove(h)
+ self._once_ids.discard(id(h))
+ return result
+ finally:
+ self._release()
+
+ def has_handlers(self, event_type: str) -> bool:
+ self._acquire()
+ try:
+ handlers = self._handlers.get(event_type)
+ return bool(handlers)
+ finally:
+ self._release()
+
+ def merge_into(self, target: EventHandlerRegistry) -> None:
+ """Move all handlers from this registry into *target*, then clear self."""
+ self._acquire()
+ try:
+ for event_type, handlers in self._handlers.items():
+ for handler in handlers:
+ once = id(handler) in self._once_ids
+ target.add(event_type, handler, once=once)
+ self._handlers.clear()
+ self._once_ids.clear()
+ finally:
+ self._release()
diff --git a/src/_exceptions.py b/src/_exceptions.py
new file mode 100644
index 0000000..e448b86
--- /dev/null
+++ b/src/_exceptions.py
@@ -0,0 +1,126 @@
+# File generated from our OpenAPI spec by Scalar. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal
+
+import httpx
+
+__all__ = [
+ "BadRequestError",
+ "AuthenticationError",
+ "PermissionDeniedError",
+ "NotFoundError",
+ "ConflictError",
+ "UnprocessableEntityError",
+ "RateLimitError",
+ "InternalServerError",
+ "WebSocketConnectionClosedError",
+ "WebSocketQueueFullError",
+]
+
+
+class ScalarApiError(Exception):
+ pass
+
+
+class APIError(ScalarApiError):
+ message: str
+ request: httpx.Request
+
+ body: object | None
+ """The API response body.
+
+ If the API responded with a valid JSON structure then this property will be the
+ decoded result.
+
+ If it isn't a valid JSON structure then this will be the raw response.
+
+ If there was no response associated with this error then it will be `None`.
+ """
+
+ def __init__(self, message: str, request: httpx.Request, *, body: object | None) -> None: # noqa: ARG002
+ super().__init__(message)
+ self.request = request
+ self.message = message
+ self.body = body
+
+
+class APIResponseValidationError(APIError):
+ response: httpx.Response
+ status_code: int
+
+ def __init__(self, response: httpx.Response, body: object | None, *, message: str | None = None) -> None:
+ super().__init__(message or "Data returned by API invalid for expected schema.", response.request, body=body)
+ self.response = response
+ self.status_code = response.status_code
+
+
+class APIStatusError(APIError):
+ """Raised when an API response has a status code of 4xx or 5xx."""
+
+ response: httpx.Response
+ status_code: int
+
+ def __init__(self, message: str, *, response: httpx.Response, body: object | None) -> None:
+ super().__init__(message, response.request, body=body)
+ self.response = response
+ self.status_code = response.status_code
+
+
+class APIConnectionError(APIError):
+ def __init__(self, *, message: str = "Connection error.", request: httpx.Request) -> None:
+ super().__init__(message, request, body=None)
+
+
+class APITimeoutError(APIConnectionError):
+ def __init__(self, request: httpx.Request) -> None:
+ super().__init__(message="Request timed out.", request=request)
+
+
+class BadRequestError(APIStatusError):
+ status_code: Literal[400] = 400 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class AuthenticationError(APIStatusError):
+ status_code: Literal[401] = 401 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class PermissionDeniedError(APIStatusError):
+ status_code: Literal[403] = 403 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class NotFoundError(APIStatusError):
+ status_code: Literal[404] = 404 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class ConflictError(APIStatusError):
+ status_code: Literal[409] = 409 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class UnprocessableEntityError(APIStatusError):
+ status_code: Literal[422] = 422 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class RateLimitError(APIStatusError):
+ status_code: Literal[429] = 429 # pyright: ignore[reportIncompatibleVariableOverride]
+
+
+class InternalServerError(APIStatusError):
+ pass
+
+
+class WebSocketConnectionClosedError(ScalarApiError):
+ """Raised when a WebSocket connection closes with unsent messages."""
+
+ unsent_messages: list[str]
+
+ def __init__(self, message: str, *, unsent_messages: list[str]) -> None:
+ super().__init__(message)
+ self.unsent_messages = unsent_messages
+
+
+class WebSocketQueueFullError(ScalarApiError):
+ """Raised when the outgoing WebSocket message queue exceeds its byte-size limit."""
+
+ pass
diff --git a/src/_files.py b/src/_files.py
new file mode 100644
index 0000000..76da9e0
--- /dev/null
+++ b/src/_files.py
@@ -0,0 +1,173 @@
+from __future__ import annotations
+
+import io
+import os
+import pathlib
+from typing import Sequence, cast, overload
+from typing_extensions import TypeVar, TypeGuard
+
+import anyio
+
+from ._types import (
+ FileTypes,
+ FileContent,
+ RequestFiles,
+ HttpxFileTypes,
+ Base64FileInput,
+ HttpxFileContent,
+ HttpxRequestFiles,
+)
+from ._utils import is_list, is_mapping, is_tuple_t, is_mapping_t, is_sequence_t
+
+_T = TypeVar("_T")
+
+
+def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]:
+ return isinstance(obj, io.IOBase) or isinstance(obj, os.PathLike)
+
+
+def is_file_content(obj: object) -> TypeGuard[FileContent]:
+ return (
+ isinstance(obj, bytes) or isinstance(obj, tuple) or isinstance(obj, io.IOBase) or isinstance(obj, os.PathLike)
+ )
+
+
+def assert_is_file_content(obj: object, *, key: str | None = None) -> None:
+ if not is_file_content(obj):
+ prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`"
+ raise RuntimeError(
+ f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead."
+ ) from None
+
+
+@overload
+def to_httpx_files(files: None) -> None: ...
+
+
+@overload
+def to_httpx_files(files: RequestFiles) -> HttpxRequestFiles: ...
+
+
+def to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles | None:
+ if files is None:
+ return None
+
+ if is_mapping_t(files):
+ files = {key: _transform_file(file) for key, file in files.items()}
+ elif is_sequence_t(files):
+ files = [(key, _transform_file(file)) for key, file in files]
+ else:
+ raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence")
+
+ return files
+
+
+def _transform_file(file: FileTypes) -> HttpxFileTypes:
+ if is_file_content(file):
+ if isinstance(file, os.PathLike):
+ path = pathlib.Path(file)
+ return (path.name, path.read_bytes())
+
+ return file
+
+ if is_tuple_t(file):
+ return (file[0], read_file_content(file[1]), *file[2:])
+
+ raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple")
+
+
+def read_file_content(file: FileContent) -> HttpxFileContent:
+ if isinstance(file, os.PathLike):
+ return pathlib.Path(file).read_bytes()
+ return file
+
+
+@overload
+async def async_to_httpx_files(files: None) -> None: ...
+
+
+@overload
+async def async_to_httpx_files(files: RequestFiles) -> HttpxRequestFiles: ...
+
+
+async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles | None:
+ if files is None:
+ return None
+
+ if is_mapping_t(files):
+ files = {key: await _async_transform_file(file) for key, file in files.items()}
+ elif is_sequence_t(files):
+ files = [(key, await _async_transform_file(file)) for key, file in files]
+ else:
+ raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence")
+
+ return files
+
+
+async def _async_transform_file(file: FileTypes) -> HttpxFileTypes:
+ if is_file_content(file):
+ if isinstance(file, os.PathLike):
+ path = anyio.Path(file)
+ return (path.name, await path.read_bytes())
+
+ return file
+
+ if is_tuple_t(file):
+ return (file[0], await async_read_file_content(file[1]), *file[2:])
+
+ raise TypeError(f"Expected file types input to be a FileContent type or to be a tuple")
+
+
+async def async_read_file_content(file: FileContent) -> HttpxFileContent:
+ if isinstance(file, os.PathLike):
+ return await anyio.Path(file).read_bytes()
+
+ return file
+
+
+def deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]]) -> _T:
+ """Copy only the containers along the given paths.
+
+ Used to guard against mutation by extract_files without copying the entire structure.
+ Only dicts and lists that lie on a path are copied; everything else
+ is returned by reference.
+
+ For example, given paths=[["foo", "files", "file"]] and the structure:
+ {
+ "foo": {
+ "bar": {"baz": {}},
+ "files": {"file": }
+ }
+ }
+ The root dict, "foo", and "files" are copied (they lie on the path).
+ "bar" and "baz" are returned by reference (off the path).
+ """
+ return _deepcopy_with_paths(item, paths, 0)
+
+
+def _deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]], index: int) -> _T:
+ if not paths:
+ return item
+ if is_mapping(item):
+ key_to_paths: dict[str, list[Sequence[str]]] = {}
+ for path in paths:
+ if index < len(path):
+ key_to_paths.setdefault(path[index], []).append(path)
+
+ # if no path continues through this mapping, it won't be mutated and copying it is redundant
+ if not key_to_paths:
+ return item
+
+ result = dict(item)
+ for key, subpaths in key_to_paths.items():
+ if key in result:
+ result[key] = _deepcopy_with_paths(result[key], subpaths, index + 1)
+ return cast(_T, result)
+ if is_list(item):
+ array_paths = [path for path in paths if index < len(path) and path[index] == ""]
+
+ # if no path expects a list here, nothing will be mutated inside it - return by reference
+ if not array_paths:
+ return cast(_T, item)
+ return cast(_T, [_deepcopy_with_paths(entry, array_paths, index + 1) for entry in item])
+ return item
diff --git a/src/_models.py b/src/_models.py
new file mode 100644
index 0000000..ce728eb
--- /dev/null
+++ b/src/_models.py
@@ -0,0 +1,962 @@
+from __future__ import annotations
+
+import os
+import inspect
+import weakref
+from typing import (
+ IO,
+ TYPE_CHECKING,
+ Any,
+ Type,
+ Union,
+ Generic,
+ TypeVar,
+ Callable,
+ Iterable,
+ Optional,
+ AsyncIterable,
+ cast,
+)
+from datetime import date, datetime
+from typing_extensions import (
+ List,
+ Unpack,
+ Literal,
+ ClassVar,
+ Protocol,
+ Required,
+ Annotated,
+ ParamSpec,
+ TypeAlias,
+ TypedDict,
+ TypeGuard,
+ final,
+ override,
+ runtime_checkable,
+)
+
+import pydantic
+from pydantic.fields import FieldInfo
+
+from ._types import (
+ Body,
+ IncEx,
+ Query,
+ ModelT,
+ Headers,
+ Timeout,
+ NotGiven,
+ AnyMapping,
+ HttpxRequestFiles,
+)
+from ._utils import (
+ PropertyInfo,
+ is_list,
+ is_given,
+ json_safe,
+ lru_cache,
+ is_mapping,
+ parse_date,
+ coerce_boolean,
+ parse_datetime,
+ strip_not_given,
+ extract_type_arg,
+ is_annotated_type,
+ is_type_alias_type,
+ strip_annotated_type,
+)
+from ._compat import (
+ PYDANTIC_V1,
+ ConfigDict,
+ GenericModel as BaseGenericModel,
+ get_args,
+ is_union,
+ parse_obj,
+ get_origin,
+ is_literal_type,
+ get_model_config,
+ get_model_fields,
+ field_get_default,
+)
+from ._constants import RAW_RESPONSE_HEADER
+
+if TYPE_CHECKING:
+ from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler
+ from pydantic_core import CoreSchema, core_schema
+ from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema
+else:
+ try:
+ from pydantic_core import CoreSchema, core_schema
+ except ImportError:
+ CoreSchema = None
+ core_schema = None
+
+__all__ = ["BaseModel", "GenericModel"]
+
+_T = TypeVar("_T")
+_BaseModelT = TypeVar("_BaseModelT", bound="BaseModel")
+
+P = ParamSpec("P")
+
+
+@runtime_checkable
+class _ConfigProtocol(Protocol):
+ allow_population_by_field_name: bool
+
+
+class BaseModel(pydantic.BaseModel):
+ if PYDANTIC_V1:
+
+ @property
+ @override
+ def model_fields_set(self) -> set[str]:
+ # a forwards-compat shim for pydantic v2
+ return self.__fields_set__ # type: ignore
+
+ class Config(pydantic.BaseConfig): # pyright: ignore[reportDeprecated]
+ extra: Any = pydantic.Extra.allow # type: ignore
+ else:
+ model_config: ClassVar[ConfigDict] = ConfigDict(
+ extra="allow", defer_build=coerce_boolean(os.environ.get("DEFER_PYDANTIC_BUILD", "true"))
+ )
+
+ def to_dict(
+ self,
+ *,
+ mode: Literal["json", "python"] = "python",
+ use_api_names: bool = True,
+ exclude_unset: bool = True,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+ warnings: bool = True,
+ ) -> dict[str, object]:
+ """Recursively generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
+
+ By default, fields that were not set by the API will not be included,
+ and keys will match the API response, *not* the property names from the model.
+
+ For example, if the API responds with `"fooBar": true` but we've defined a `foo_bar: bool` property,
+ the output will use the `"fooBar"` key (unless `use_api_names=False` is passed).
+
+ Args:
+ mode:
+ If mode is 'json', the dictionary will only contain JSON serializable types. e.g. `datetime` will be turned into a string, `"2024-3-22T18:11:19.117000Z"`.
+ If mode is 'python', the dictionary may contain any Python objects. e.g. `datetime(2024, 3, 22)`
+
+ use_api_names: Whether to use the key that the API responded with or the property name. Defaults to `True`.
+ exclude_unset: Whether to exclude fields that have not been explicitly set.
+ exclude_defaults: Whether to exclude fields that are set to their default value from the output.
+ exclude_none: Whether to exclude fields that have a value of `None` from the output.
+ warnings: Whether to log warnings when invalid fields are encountered. This is only supported in Pydantic v2.
+ """
+ return self.model_dump(
+ mode=mode,
+ by_alias=use_api_names,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ warnings=warnings,
+ )
+
+ def to_json(
+ self,
+ *,
+ indent: int | None = 2,
+ use_api_names: bool = True,
+ exclude_unset: bool = True,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+ warnings: bool = True,
+ ) -> str:
+ """Generates a JSON string representing this model as it would be received from or sent to the API (but with indentation).
+
+ By default, fields that were not set by the API will not be included,
+ and keys will match the API response, *not* the property names from the model.
+
+ For example, if the API responds with `"fooBar": true` but we've defined a `foo_bar: bool` property,
+ the output will use the `"fooBar"` key (unless `use_api_names=False` is passed).
+
+ Args:
+ indent: Indentation to use in the JSON output. If `None` is passed, the output will be compact. Defaults to `2`
+ use_api_names: Whether to use the key that the API responded with or the property name. Defaults to `True`.
+ exclude_unset: Whether to exclude fields that have not been explicitly set.
+ exclude_defaults: Whether to exclude fields that have the default value.
+ exclude_none: Whether to exclude fields that have a value of `None`.
+ warnings: Whether to show any warnings that occurred during serialization. This is only supported in Pydantic v2.
+ """
+ return self.model_dump_json(
+ indent=indent,
+ by_alias=use_api_names,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ warnings=warnings,
+ )
+
+ @override
+ def __str__(self) -> str:
+ # mypy complains about an invalid self arg
+ return f"{self.__repr_name__()}({self.__repr_str__(', ')})" # type: ignore[misc]
+
+ # Override the 'construct' method in a way that supports recursive parsing without validation.
+ # Based on https://github.com/samuelcolvin/pydantic/issues/1168#issuecomment-817742836.
+ @classmethod
+ @override
+ def construct( # pyright: ignore[reportIncompatibleMethodOverride]
+ __cls: Type[ModelT],
+ _fields_set: set[str] | None = None,
+ **values: object,
+ ) -> ModelT:
+ m = __cls.__new__(__cls)
+ fields_values: dict[str, object] = {}
+
+ config = get_model_config(__cls)
+ populate_by_name = (
+ config.allow_population_by_field_name
+ if isinstance(config, _ConfigProtocol)
+ else config.get("populate_by_name")
+ )
+
+ if _fields_set is None:
+ _fields_set = set()
+
+ model_fields = get_model_fields(__cls)
+ for name, field in model_fields.items():
+ key = field.alias
+ if key is None or (key not in values and populate_by_name):
+ key = name
+
+ if key in values:
+ fields_values[name] = _construct_field(value=values[key], field=field, key=key)
+ _fields_set.add(name)
+ else:
+ fields_values[name] = field_get_default(field)
+
+ extra_field_type = _get_extra_fields_type(__cls)
+
+ _extra = {}
+ for key, value in values.items():
+ if key not in model_fields:
+ parsed = construct_type(value=value, type_=extra_field_type) if extra_field_type is not None else value
+
+ if PYDANTIC_V1:
+ _fields_set.add(key)
+ fields_values[key] = parsed
+ else:
+ _extra[key] = parsed
+
+ object.__setattr__(m, "__dict__", fields_values)
+
+ if PYDANTIC_V1:
+ # init_private_attributes() does not exist in v2
+ m._init_private_attributes() # type: ignore
+
+ # copied from Pydantic v1's `construct()` method
+ object.__setattr__(m, "__fields_set__", _fields_set)
+ else:
+ # these properties are copied from Pydantic's `model_construct()` method
+ object.__setattr__(m, "__pydantic_private__", None)
+ object.__setattr__(m, "__pydantic_extra__", _extra)
+ object.__setattr__(m, "__pydantic_fields_set__", _fields_set)
+
+ return m
+
+ if not TYPE_CHECKING:
+ # type checkers incorrectly complain about this assignment
+ # because the type signatures are technically different
+ # although not in practice
+ model_construct = construct
+
+ if PYDANTIC_V1:
+ # we define aliases for some of the new pydantic v2 methods so
+ # that we can just document these methods without having to specify
+ # a specific pydantic version as some users may not know which
+ # pydantic version they are currently using
+
+ @override
+ def model_dump(
+ self,
+ *,
+ mode: Literal["json", "python"] | str = "python",
+ include: IncEx | None = None,
+ exclude: IncEx | None = None,
+ context: Any | None = None,
+ by_alias: bool | None = None,
+ exclude_unset: bool = False,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+ exclude_computed_fields: bool = False,
+ round_trip: bool = False,
+ warnings: bool | Literal["none", "warn", "error"] = True,
+ fallback: Callable[[Any], Any] | None = None,
+ serialize_as_any: bool = False,
+ ) -> dict[str, Any]:
+ """Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
+
+ Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
+
+ Args:
+ mode: The mode in which `to_python` should run.
+ If mode is 'json', the output will only contain JSON serializable types.
+ If mode is 'python', the output may contain non-JSON-serializable Python objects.
+ include: A set of fields to include in the output.
+ exclude: A set of fields to exclude from the output.
+ context: Additional context to pass to the serializer.
+ by_alias: Whether to use the field's alias in the dictionary key if defined.
+ exclude_unset: Whether to exclude fields that have not been explicitly set.
+ exclude_defaults: Whether to exclude fields that are set to their default value.
+ exclude_none: Whether to exclude fields that have a value of `None`.
+ exclude_computed_fields: Whether to exclude computed fields.
+ While this can be useful for round-tripping, it is usually recommended to use the dedicated
+ `round_trip` parameter instead.
+ round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].
+ warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,
+ "error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].
+ fallback: A function to call when an unknown value is encountered. If not provided,
+ a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
+ serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
+
+ Returns:
+ A dictionary representation of the model.
+ """
+ if mode not in {"json", "python"}:
+ raise ValueError("mode must be either 'json' or 'python'")
+ if round_trip != False:
+ raise ValueError("round_trip is only supported in Pydantic v2")
+ if warnings != True:
+ raise ValueError("warnings is only supported in Pydantic v2")
+ if context is not None:
+ raise ValueError("context is only supported in Pydantic v2")
+ if serialize_as_any != False:
+ raise ValueError("serialize_as_any is only supported in Pydantic v2")
+ if fallback is not None:
+ raise ValueError("fallback is only supported in Pydantic v2")
+ if exclude_computed_fields != False:
+ raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
+ dumped = super().dict( # pyright: ignore[reportDeprecated]
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias if by_alias is not None else False,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+
+ return cast("dict[str, Any]", json_safe(dumped)) if mode == "json" else dumped
+
+ @override
+ def model_dump_json(
+ self,
+ *,
+ indent: int | None = None,
+ ensure_ascii: bool = False,
+ include: IncEx | None = None,
+ exclude: IncEx | None = None,
+ context: Any | None = None,
+ by_alias: bool | None = None,
+ exclude_unset: bool = False,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+ exclude_computed_fields: bool = False,
+ round_trip: bool = False,
+ warnings: bool | Literal["none", "warn", "error"] = True,
+ fallback: Callable[[Any], Any] | None = None,
+ serialize_as_any: bool = False,
+ ) -> str:
+ """Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump_json
+
+ Generates a JSON representation of the model using Pydantic's `to_json` method.
+
+ Args:
+ indent: Indentation to use in the JSON output. If None is passed, the output will be compact.
+ include: Field(s) to include in the JSON output. Can take either a string or set of strings.
+ exclude: Field(s) to exclude from the JSON output. Can take either a string or set of strings.
+ by_alias: Whether to serialize using field aliases.
+ exclude_unset: Whether to exclude fields that have not been explicitly set.
+ exclude_defaults: Whether to exclude fields that have the default value.
+ exclude_none: Whether to exclude fields that have a value of `None`.
+ round_trip: Whether to use serialization/deserialization between JSON and class instance.
+ warnings: Whether to show any warnings that occurred during serialization.
+
+ Returns:
+ A JSON string representation of the model.
+ """
+ if round_trip != False:
+ raise ValueError("round_trip is only supported in Pydantic v2")
+ if warnings != True:
+ raise ValueError("warnings is only supported in Pydantic v2")
+ if context is not None:
+ raise ValueError("context is only supported in Pydantic v2")
+ if serialize_as_any != False:
+ raise ValueError("serialize_as_any is only supported in Pydantic v2")
+ if fallback is not None:
+ raise ValueError("fallback is only supported in Pydantic v2")
+ if ensure_ascii != False:
+ raise ValueError("ensure_ascii is only supported in Pydantic v2")
+ if exclude_computed_fields != False:
+ raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
+ return super().json( # type: ignore[reportDeprecated]
+ indent=indent,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias if by_alias is not None else False,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+
+
+class _EagerIterable(list[_T], Generic[_T]):
+ """
+ Accepts any Iterable[T] input (including generators), consumes it
+ eagerly, and validates all items upfront.
+
+ Validation preserves the original container type where possible
+ (e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON)
+ always emits a list — round-tripping through model_dump() will not
+ restore the original container type.
+ """
+
+ @classmethod
+ def __get_pydantic_core_schema__(
+ cls,
+ source_type: Any,
+ handler: GetCoreSchemaHandler,
+ ) -> CoreSchema:
+ (item_type,) = get_args(source_type) or (Any,)
+ item_schema: CoreSchema = handler.generate_schema(item_type)
+ list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema)
+
+ return core_schema.no_info_wrap_validator_function(
+ cls._validate,
+ list_of_items_schema,
+ serialization=core_schema.plain_serializer_function_ser_schema(
+ cls._serialize,
+ info_arg=False,
+ ),
+ )
+
+ @staticmethod
+ def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any:
+ original_type: type[Any] = type(v)
+
+ # Normalize to list so list_schema can validate each item
+ if isinstance(v, list):
+ items: list[_T] = v
+ else:
+ try:
+ items = list(v)
+ except TypeError as e:
+ raise TypeError("Value is not iterable") from e
+
+ # Validate items against the inner schema
+ validated: list[_T] = handler(items)
+
+ # Reconstruct original container type
+ if original_type is list:
+ return validated
+ # str(list) produces the list's repr, not a string built from items,
+ # so skip reconstruction for str and its subclasses.
+ if issubclass(original_type, str):
+ return validated
+ try:
+ return original_type(validated)
+ except (TypeError, ValueError):
+ # If the type cannot be reconstructed, just return the validated list
+ return validated
+
+ @staticmethod
+ def _serialize(v: Iterable[_T]) -> list[_T]:
+ """Always serialize as a list so Pydantic's JSON encoder is happy."""
+ if isinstance(v, list):
+ return v
+ return list(v)
+
+
+EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable]
+
+
+def _construct_field(value: object, field: FieldInfo, key: str) -> object:
+ if value is None:
+ return field_get_default(field)
+
+ if PYDANTIC_V1:
+ type_ = cast(type, field.outer_type_) # type: ignore
+ else:
+ type_ = field.annotation # type: ignore
+
+ if type_ is None:
+ raise RuntimeError(f"Unexpected field type is None for {key}")
+
+ return construct_type(value=value, type_=type_, metadata=getattr(field, "metadata", None))
+
+
+def _get_extra_fields_type(cls: type[pydantic.BaseModel]) -> type | None:
+ if PYDANTIC_V1:
+ # TODO
+ return None
+
+ schema = cls.__pydantic_core_schema__
+ if schema["type"] == "model":
+ fields = schema["schema"]
+ if fields["type"] == "model-fields":
+ extras = fields.get("extras_schema")
+ if extras and "cls" in extras:
+ # mypy can't narrow the type
+ return extras["cls"] # type: ignore[no-any-return]
+
+ return None
+
+
+def is_basemodel(type_: type) -> bool:
+ """Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`"""
+ if is_union(type_):
+ for variant in get_args(type_):
+ if is_basemodel(variant):
+ return True
+
+ return False
+
+ return is_basemodel_type(type_)
+
+
+def is_basemodel_type(type_: type) -> TypeGuard[type[BaseModel] | type[GenericModel]]:
+ origin = get_origin(type_) or type_
+ if not inspect.isclass(origin):
+ return False
+ return issubclass(origin, BaseModel) or issubclass(origin, GenericModel)
+
+
+def build(
+ base_model_cls: Callable[P, _BaseModelT],
+ *args: P.args,
+ **kwargs: P.kwargs,
+) -> _BaseModelT:
+ """Construct a BaseModel class without validation.
+
+ This is useful for cases where you need to instantiate a `BaseModel`
+ from an API response as this provides type-safe params which isn't supported
+ by helpers like `construct_type()`.
+
+ ```py
+ build(MyModel, my_field_a="foo", my_field_b=123)
+ ```
+ """
+ if args:
+ raise TypeError(
+ "Received positional arguments which are not supported; Keyword arguments must be used instead",
+ )
+
+ return cast(_BaseModelT, construct_type(type_=base_model_cls, value=kwargs))
+
+
+def construct_type_unchecked(*, value: object, type_: type[_T]) -> _T:
+ """Loose coercion to the expected type with construction of nested values.
+
+ Note: the returned value from this function is not guaranteed to match the
+ given type.
+ """
+ return cast(_T, construct_type(value=value, type_=type_))
+
+
+def construct_type(*, value: object, type_: object, metadata: Optional[List[Any]] = None) -> object:
+ """Loose coercion to the expected type with construction of nested values.
+
+ If the given value does not match the expected type then it is returned as-is.
+ """
+
+ # store a reference to the original type we were given before we extract any inner
+ # types so that we can properly resolve forward references in `TypeAliasType` annotations
+ original_type = None
+
+ # we allow `object` as the input type because otherwise, passing things like
+ # `Literal['value']` will be reported as a type error by type checkers
+ type_ = cast("type[object]", type_)
+ if is_type_alias_type(type_):
+ original_type = type_ # type: ignore[unreachable]
+ type_ = type_.__value__ # type: ignore[unreachable]
+
+ # unwrap `Annotated[T, ...]` -> `T`
+ if metadata is not None and len(metadata) > 0:
+ meta: tuple[Any, ...] = tuple(metadata)
+ elif is_annotated_type(type_):
+ meta = get_args(type_)[1:]
+ type_ = extract_type_arg(type_, 0)
+ else:
+ meta = tuple()
+
+ # we need to use the origin class for any types that are subscripted generics
+ # e.g. Dict[str, object]
+ origin = get_origin(type_) or type_
+ args = get_args(type_)
+
+ if is_union(origin):
+ try:
+ return validate_type(type_=cast("type[object]", original_type or type_), value=value)
+ except Exception:
+ pass
+
+ # if the type is a discriminated union then we want to construct the right variant
+ # in the union, even if the data doesn't match exactly, otherwise we'd break code
+ # that relies on the constructed class types, e.g.
+ #
+ # class FooType:
+ # kind: Literal['foo']
+ # value: str
+ #
+ # class BarType:
+ # kind: Literal['bar']
+ # value: int
+ #
+ # without this block, if the data we get is something like `{'kind': 'bar', 'value': 'foo'}` then
+ # we'd end up constructing `FooType` when it should be `BarType`.
+ discriminator = _build_discriminated_union_meta(union=type_, meta_annotations=meta)
+ if discriminator and is_mapping(value):
+ variant_value = value.get(discriminator.field_alias_from or discriminator.field_name)
+ if variant_value and isinstance(variant_value, str):
+ variant_type = discriminator.mapping.get(variant_value)
+ if variant_type:
+ return construct_type(type_=variant_type, value=value)
+
+ # if the data is not valid, use the first variant that doesn't fail while deserializing
+ for variant in args:
+ try:
+ return construct_type(value=value, type_=variant)
+ except Exception:
+ continue
+
+ raise RuntimeError(f"Could not convert data into a valid instance of {type_}")
+
+ if origin == dict:
+ if not is_mapping(value):
+ return value
+
+ _, items_type = get_args(type_) # Dict[_, items_type]
+ return {key: construct_type(value=item, type_=items_type) for key, item in value.items()}
+
+ if (
+ not is_literal_type(type_)
+ and inspect.isclass(origin)
+ and (issubclass(origin, BaseModel) or issubclass(origin, GenericModel))
+ ):
+ if is_list(value):
+ return [cast(Any, type_).construct(**entry) if is_mapping(entry) else entry for entry in value]
+
+ if is_mapping(value):
+ if issubclass(type_, BaseModel):
+ return type_.construct(**value) # type: ignore[arg-type]
+
+ return cast(Any, type_).construct(**value)
+
+ if origin == list:
+ if not is_list(value):
+ return value
+
+ inner_type = args[0] # List[inner_type]
+ return [construct_type(value=entry, type_=inner_type) for entry in value]
+
+ if origin == float:
+ if isinstance(value, int):
+ coerced = float(value)
+ if coerced != value:
+ return value
+ return coerced
+
+ return value
+
+ if type_ == datetime:
+ try:
+ return parse_datetime(value) # type: ignore
+ except Exception:
+ return value
+
+ if type_ == date:
+ try:
+ return parse_date(value) # type: ignore
+ except Exception:
+ return value
+
+ return value
+
+
+@runtime_checkable
+class CachedDiscriminatorType(Protocol):
+ __discriminator__: DiscriminatorDetails
+
+
+DISCRIMINATOR_CACHE: weakref.WeakKeyDictionary[type, DiscriminatorDetails] = weakref.WeakKeyDictionary()
+
+
+class DiscriminatorDetails:
+ field_name: str
+ """The name of the discriminator field in the variant class, e.g.
+
+ ```py
+ class Foo(BaseModel):
+ type: Literal['foo']
+ ```
+
+ Will result in field_name='type'
+ """
+
+ field_alias_from: str | None
+ """The name of the discriminator field in the API response, e.g.
+
+ ```py
+ class Foo(BaseModel):
+ type: Literal['foo'] = Field(alias='type_from_api')
+ ```
+
+ Will result in field_alias_from='type_from_api'
+ """
+
+ mapping: dict[str, type]
+ """Mapping of discriminator value to variant type, e.g.
+
+ {'foo': FooVariant, 'bar': BarVariant}
+ """
+
+ def __init__(
+ self,
+ *,
+ mapping: dict[str, type],
+ discriminator_field: str,
+ discriminator_alias: str | None,
+ ) -> None:
+ self.mapping = mapping
+ self.field_name = discriminator_field
+ self.field_alias_from = discriminator_alias
+
+
+def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None:
+ cached = DISCRIMINATOR_CACHE.get(union)
+ if cached is not None:
+ return cached
+
+ discriminator_field_name: str | None = None
+
+ for annotation in meta_annotations:
+ if isinstance(annotation, PropertyInfo) and annotation.discriminator is not None:
+ discriminator_field_name = annotation.discriminator
+ break
+
+ if not discriminator_field_name:
+ return None
+
+ mapping: dict[str, type] = {}
+ discriminator_alias: str | None = None
+
+ for variant in get_args(union):
+ variant = strip_annotated_type(variant)
+ if is_basemodel_type(variant):
+ if PYDANTIC_V1:
+ field_info = cast("dict[str, FieldInfo]", variant.__fields__).get(discriminator_field_name) # pyright: ignore[reportDeprecated, reportUnnecessaryCast]
+ if not field_info:
+ continue
+
+ # Note: if one variant defines an alias then they all should
+ discriminator_alias = field_info.alias
+
+ if (annotation := getattr(field_info, "annotation", None)) and is_literal_type(annotation):
+ for entry in get_args(annotation):
+ if isinstance(entry, str):
+ mapping[entry] = variant
+ else:
+ field = _extract_field_schema_pv2(variant, discriminator_field_name)
+ if not field:
+ continue
+
+ # Note: if one variant defines an alias then they all should
+ discriminator_alias = field.get("serialization_alias")
+
+ field_schema = field["schema"]
+
+ if field_schema["type"] == "literal":
+ for entry in cast("LiteralSchema", field_schema)["expected"]:
+ if isinstance(entry, str):
+ mapping[entry] = variant
+
+ if not mapping:
+ return None
+
+ details = DiscriminatorDetails(
+ mapping=mapping,
+ discriminator_field=discriminator_field_name,
+ discriminator_alias=discriminator_alias,
+ )
+ DISCRIMINATOR_CACHE.setdefault(union, details)
+ return details
+
+
+def _extract_field_schema_pv2(model: type[BaseModel], field_name: str) -> ModelField | None:
+ schema = model.__pydantic_core_schema__
+ if schema["type"] == "definitions":
+ schema = schema["schema"]
+
+ if schema["type"] != "model":
+ return None
+
+ schema = cast("ModelSchema", schema)
+ fields_schema = schema["schema"]
+ if fields_schema["type"] != "model-fields":
+ return None
+
+ fields_schema = cast("ModelFieldsSchema", fields_schema)
+ field = fields_schema["fields"].get(field_name)
+ if not field:
+ return None
+
+ return cast("ModelField", field) # pyright: ignore[reportUnnecessaryCast]
+
+
+def validate_type(*, type_: type[_T], value: object) -> _T:
+ """Strict validation that the given value matches the expected type"""
+ if inspect.isclass(type_) and issubclass(type_, pydantic.BaseModel):
+ return cast(_T, parse_obj(type_, value))
+
+ return cast(_T, _validate_non_model_type(type_=type_, value=value))
+
+
+def set_pydantic_config(typ: Any, config: pydantic.ConfigDict) -> None:
+ """Add a pydantic config for the given type.
+
+ Note: this is a no-op on Pydantic v1.
+ """
+ setattr(typ, "__pydantic_config__", config) # noqa: B010
+
+
+# our use of subclassing here causes weirdness for type checkers,
+# so we just pretend that we don't subclass
+if TYPE_CHECKING:
+ GenericModel = BaseModel
+else:
+
+ class GenericModel(BaseGenericModel, BaseModel):
+ pass
+
+
+if not PYDANTIC_V1:
+ from pydantic import TypeAdapter as _TypeAdapter
+
+ _CachedTypeAdapter = cast("TypeAdapter[object]", lru_cache(maxsize=None)(_TypeAdapter))
+
+ if TYPE_CHECKING:
+ from pydantic import TypeAdapter
+ else:
+ TypeAdapter = _CachedTypeAdapter
+
+ def _validate_non_model_type(*, type_: type[_T], value: object) -> _T:
+ return TypeAdapter(type_).validate_python(value)
+
+elif not TYPE_CHECKING: # TODO: condition is weird
+
+ class RootModel(GenericModel, Generic[_T]):
+ """Used as a placeholder to easily convert runtime types to a Pydantic format
+ to provide validation.
+
+ For example:
+ ```py
+ validated = RootModel[int](__root__="5").__root__
+ # validated: 5
+ ```
+ """
+
+ __root__: _T
+
+ def _validate_non_model_type(*, type_: type[_T], value: object) -> _T:
+ model = _create_pydantic_model(type_).validate(value)
+ return cast(_T, model.__root__)
+
+ def _create_pydantic_model(type_: _T) -> Type[RootModel[_T]]:
+ return RootModel[type_] # type: ignore
+
+
+class SecurityOptions(TypedDict, total=False):
+ api_key_auth: bool
+ bearer_auth: bool
+
+
+class FinalRequestOptionsInput(TypedDict, total=False):
+ method: Required[str]
+ url: Required[str]
+ params: Query
+ headers: Headers
+ max_retries: int
+ timeout: float | Timeout | None
+ files: HttpxRequestFiles | None
+ idempotency_key: str
+ content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None]
+ json_data: Body
+ extra_json: AnyMapping
+ follow_redirects: bool
+ security: SecurityOptions
+
+
+@final
+class FinalRequestOptions(pydantic.BaseModel):
+ method: str
+ url: str
+ params: Query = {}
+ headers: Union[Headers, NotGiven] = NotGiven()
+ max_retries: Union[int, NotGiven] = NotGiven()
+ timeout: Union[float, Timeout, None, NotGiven] = NotGiven()
+ files: Union[HttpxRequestFiles, None] = None
+ idempotency_key: Union[str, None] = None
+ post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
+ follow_redirects: Union[bool, None] = None
+ security: SecurityOptions = {
+ "api_key_auth": True,
+ "bearer_auth": True,
+ }
+
+ content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None
+ # It should be noted that we cannot use `json` here as that would override
+ # a BaseModel method in an incompatible fashion.
+ json_data: Union[Body, None] = None
+ extra_json: Union[AnyMapping, None] = None
+
+ if PYDANTIC_V1:
+
+ class Config(pydantic.BaseConfig): # pyright: ignore[reportDeprecated]
+ arbitrary_types_allowed: bool = True
+ else:
+ model_config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True)
+
+ def get_max_retries(self, max_retries: int) -> int:
+ if isinstance(self.max_retries, NotGiven):
+ return max_retries
+ return self.max_retries
+
+ def _strip_raw_response_header(self) -> None:
+ if not is_given(self.headers):
+ return
+
+ if self.headers.get(RAW_RESPONSE_HEADER):
+ self.headers = {**self.headers}
+ self.headers.pop(RAW_RESPONSE_HEADER)
+
+ # override the `construct` method so that we can run custom transformations.
+ # this is necessary as we don't want to do any actual runtime type checking
+ # (which means we can't use validators) but we do want to ensure that `NotGiven`
+ # values are not present
+ #
+ # type ignore required because we're adding explicit types to `**values`
+ @classmethod
+ def construct( # type: ignore
+ cls,
+ _fields_set: set[str] | None = None,
+ **values: Unpack[FinalRequestOptionsInput],
+ ) -> FinalRequestOptions:
+ kwargs: dict[str, Any] = {
+ # we unconditionally call `strip_not_given` on any value
+ # as it will just ignore any non-mapping types
+ key: strip_not_given(value)
+ for key, value in values.items()
+ }
+ if PYDANTIC_V1:
+ return cast(FinalRequestOptions, super().construct(_fields_set, **kwargs)) # pyright: ignore[reportDeprecated]
+ return super().model_construct(_fields_set, **kwargs)
+
+ if not TYPE_CHECKING:
+ # type checkers incorrectly complain about this assignment
+ model_construct = construct
diff --git a/src/_qs.py b/src/_qs.py
new file mode 100644
index 0000000..4127c19
--- /dev/null
+++ b/src/_qs.py
@@ -0,0 +1,149 @@
+from __future__ import annotations
+
+from typing import Any, List, Tuple, Union, Mapping, TypeVar
+from urllib.parse import parse_qs, urlencode
+from typing_extensions import get_args
+
+from ._types import NotGiven, ArrayFormat, NestedFormat, not_given
+from ._utils import flatten
+
+_T = TypeVar("_T")
+
+PrimitiveData = Union[str, int, float, bool, None]
+# this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"]
+# https://github.com/microsoft/pyright/issues/3555
+Data = Union[PrimitiveData, List[Any], Tuple[Any], "Mapping[str, Any]"]
+Params = Mapping[str, Data]
+
+
+class Querystring:
+ array_format: ArrayFormat
+ nested_format: NestedFormat
+
+ def __init__(
+ self,
+ *,
+ array_format: ArrayFormat = "repeat",
+ nested_format: NestedFormat = "brackets",
+ ) -> None:
+ self.array_format = array_format
+ self.nested_format = nested_format
+
+ def parse(self, query: str) -> Mapping[str, object]:
+ # Note: custom format syntax is not supported yet
+ return parse_qs(query)
+
+ def stringify(
+ self,
+ params: Params,
+ *,
+ array_format: ArrayFormat | NotGiven = not_given,
+ nested_format: NestedFormat | NotGiven = not_given,
+ ) -> str:
+ return urlencode(
+ self.stringify_items(
+ params,
+ array_format=array_format,
+ nested_format=nested_format,
+ )
+ )
+
+ def stringify_items(
+ self,
+ params: Params,
+ *,
+ array_format: ArrayFormat | NotGiven = not_given,
+ nested_format: NestedFormat | NotGiven = not_given,
+ ) -> list[tuple[str, str]]:
+ opts = Options(
+ qs=self,
+ array_format=array_format,
+ nested_format=nested_format,
+ )
+ return flatten([self._stringify_item(key, value, opts) for key, value in params.items()])
+
+ def _stringify_item(
+ self,
+ key: str,
+ value: Data,
+ opts: Options,
+ ) -> list[tuple[str, str]]:
+ if isinstance(value, Mapping):
+ items: list[tuple[str, str]] = []
+ nested_format = opts.nested_format
+ for subkey, subvalue in value.items():
+ items.extend(
+ self._stringify_item(
+ # TODO: error if unknown format
+ f"{key}.{subkey}" if nested_format == "dots" else f"{key}[{subkey}]",
+ subvalue,
+ opts,
+ )
+ )
+ return items
+
+ if isinstance(value, (list, tuple)):
+ array_format = opts.array_format
+ if array_format == "comma":
+ return [
+ (
+ key,
+ ",".join(self._primitive_value_to_str(item) for item in value if item is not None),
+ ),
+ ]
+ elif array_format == "repeat":
+ items = []
+ for item in value:
+ items.extend(self._stringify_item(key, item, opts))
+ return items
+ elif array_format == "indices":
+ items = []
+ for i, item in enumerate(value):
+ items.extend(self._stringify_item(f"{key}[{i}]", item, opts))
+ return items
+ elif array_format == "brackets":
+ items = []
+ key = key + "[]"
+ for item in value:
+ items.extend(self._stringify_item(key, item, opts))
+ return items
+ else:
+ raise NotImplementedError(
+ f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}"
+ )
+
+ serialised = self._primitive_value_to_str(value)
+ if not serialised:
+ return []
+ return [(key, serialised)]
+
+ def _primitive_value_to_str(self, value: PrimitiveData) -> str:
+ # copied from httpx
+ if value is True:
+ return "true"
+ elif value is False:
+ return "false"
+ elif value is None:
+ return ""
+ return str(value)
+
+
+_qs = Querystring()
+parse = _qs.parse
+stringify = _qs.stringify
+stringify_items = _qs.stringify_items
+
+
+class Options:
+ array_format: ArrayFormat
+ nested_format: NestedFormat
+
+ def __init__(
+ self,
+ qs: Querystring = _qs,
+ *,
+ array_format: ArrayFormat | NotGiven = not_given,
+ nested_format: NestedFormat | NotGiven = not_given,
+ ) -> None:
+ self.array_format = qs.array_format if isinstance(array_format, NotGiven) else array_format
+ self.nested_format = qs.nested_format if isinstance(nested_format, NotGiven) else nested_format
diff --git a/src/_resource.py b/src/_resource.py
new file mode 100644
index 0000000..975eb18
--- /dev/null
+++ b/src/_resource.py
@@ -0,0 +1,43 @@
+# File generated from our OpenAPI spec by Scalar. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import time
+from typing import TYPE_CHECKING
+
+import anyio
+
+if TYPE_CHECKING:
+ from ._client import ScalarApi, AsyncScalarApi
+
+
+class SyncAPIResource:
+ _client: ScalarApi
+
+ def __init__(self, client: ScalarApi) -> None:
+ self._client = client
+ self._get = client.get
+ self._post = client.post
+ self._patch = client.patch
+ self._put = client.put
+ self._delete = client.delete
+ self._get_api_list = client.get_api_list
+
+ def _sleep(self, seconds: float) -> None:
+ time.sleep(seconds)
+
+
+class AsyncAPIResource:
+ _client: AsyncScalarApi
+
+ def __init__(self, client: AsyncScalarApi) -> None:
+ self._client = client
+ self._get = client.get
+ self._post = client.post
+ self._patch = client.patch
+ self._put = client.put
+ self._delete = client.delete
+ self._get_api_list = client.get_api_list
+
+ async def _sleep(self, seconds: float) -> None:
+ await anyio.sleep(seconds)
diff --git a/src/_response.py b/src/_response.py
new file mode 100644
index 0000000..480d8a9
--- /dev/null
+++ b/src/_response.py
@@ -0,0 +1,832 @@
+from __future__ import annotations
+
+import os
+import inspect
+import logging
+import datetime
+import functools
+from types import TracebackType
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Union,
+ Generic,
+ TypeVar,
+ Callable,
+ Iterator,
+ AsyncIterator,
+ cast,
+ overload,
+)
+from typing_extensions import Awaitable, ParamSpec, override, get_origin
+
+import anyio
+import httpx
+import pydantic
+
+from ._types import NoneType
+from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type, extract_type_var_from_base
+from ._models import BaseModel, is_basemodel
+from ._constants import RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER
+from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type
+from ._exceptions import ScalarApiError, APIResponseValidationError
+
+if TYPE_CHECKING:
+ from ._models import FinalRequestOptions
+ from ._base_client import BaseClient
+
+
+P = ParamSpec("P")
+R = TypeVar("R")
+_T = TypeVar("_T")
+_APIResponseT = TypeVar("_APIResponseT", bound="APIResponse[Any]")
+_AsyncAPIResponseT = TypeVar("_AsyncAPIResponseT", bound="AsyncAPIResponse[Any]")
+
+log: logging.Logger = logging.getLogger(__name__)
+
+
+class BaseAPIResponse(Generic[R]):
+ _cast_to: type[R]
+ _client: BaseClient[Any, Any]
+ _parsed_by_type: dict[type[Any], Any]
+ _is_sse_stream: bool
+ _stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None
+ _options: FinalRequestOptions
+
+ http_response: httpx.Response
+
+ retries_taken: int
+ """The number of retries made. If no retries happened this will be `0`"""
+
+ def __init__(
+ self,
+ *,
+ raw: httpx.Response,
+ cast_to: type[R],
+ client: BaseClient[Any, Any],
+ stream: bool,
+ stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
+ options: FinalRequestOptions,
+ retries_taken: int = 0,
+ ) -> None:
+ self._cast_to = cast_to
+ self._client = client
+ self._parsed_by_type = {}
+ self._is_sse_stream = stream
+ self._stream_cls = stream_cls
+ self._options = options
+ self.http_response = raw
+ self.retries_taken = retries_taken
+
+ @property
+ def headers(self) -> httpx.Headers:
+ return self.http_response.headers
+
+ @property
+ def http_request(self) -> httpx.Request:
+ """Returns the httpx Request instance associated with the current response."""
+ return self.http_response.request
+
+ @property
+ def status_code(self) -> int:
+ return self.http_response.status_code
+
+ @property
+ def url(self) -> httpx.URL:
+ """Returns the URL for which the request was made."""
+ return self.http_response.url
+
+ @property
+ def method(self) -> str:
+ return self.http_request.method
+
+ @property
+ def http_version(self) -> str:
+ return self.http_response.http_version
+
+ @property
+ def elapsed(self) -> datetime.timedelta:
+ """The time taken for the complete request/response cycle to complete."""
+ return self.http_response.elapsed
+
+ @property
+ def is_closed(self) -> bool:
+ """Whether or not the response body has been closed.
+
+ If this is False then there is response data that has not been read yet.
+ You must either fully consume the response body or call `.close()`
+ before discarding the response to prevent resource leaks.
+ """
+ return self.http_response.is_closed
+
+ @override
+ def __repr__(self) -> str:
+ return (
+ f"<{self.__class__.__name__} [{self.status_code} {self.http_response.reason_phrase}] type={self._cast_to}>"
+ )
+
+ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
+ cast_to = to if to is not None else self._cast_to
+
+ # unwrap `TypeAlias('Name', T)` -> `T`
+ if is_type_alias_type(cast_to):
+ cast_to = cast_to.__value__ # type: ignore[unreachable]
+
+ # unwrap `Annotated[T, ...]` -> `T`
+ if cast_to and is_annotated_type(cast_to):
+ cast_to = extract_type_arg(cast_to, 0)
+
+ origin = get_origin(cast_to) or cast_to
+
+ if self._is_sse_stream:
+ if to:
+ if not is_stream_class_type(to):
+ raise TypeError(f"Expected custom parse type to be a subclass of {Stream} or {AsyncStream}")
+
+ return cast(
+ _T,
+ to(
+ cast_to=extract_stream_chunk_type(
+ to,
+ failure_message="Expected custom stream type to be passed with a type argument, e.g. Stream[ChunkType]",
+ ),
+ response=self.http_response,
+ client=cast(Any, self._client),
+ options=self._options,
+ ),
+ )
+
+ if self._stream_cls:
+ return cast(
+ R,
+ self._stream_cls(
+ cast_to=extract_stream_chunk_type(self._stream_cls),
+ response=self.http_response,
+ client=cast(Any, self._client),
+ options=self._options,
+ ),
+ )
+
+ stream_cls = cast("type[Stream[Any]] | type[AsyncStream[Any]] | None", self._client._default_stream_cls)
+ if stream_cls is None:
+ raise MissingStreamClassError()
+
+ return cast(
+ R,
+ stream_cls(
+ cast_to=cast_to,
+ response=self.http_response,
+ client=cast(Any, self._client),
+ options=self._options,
+ ),
+ )
+
+ if cast_to is None or cast_to is NoneType:
+ return cast(R, None)
+
+ response = self.http_response
+ if cast_to == str:
+ return cast(R, response.text)
+
+ if cast_to == bytes:
+ return cast(R, response.content)
+
+ if cast_to == int:
+ return cast(R, int(response.text))
+
+ if cast_to == float:
+ return cast(R, float(response.text))
+
+ if cast_to == bool:
+ return cast(R, response.text.lower() == "true")
+
+ if origin == APIResponse:
+ raise RuntimeError("Unexpected state - cast_to is `APIResponse`")
+
+ if inspect.isclass(origin) and issubclass(origin, httpx.Response):
+ # Because of the invariance of our ResponseT TypeVar, users can subclass httpx.Response
+ # and pass that class to our request functions. We cannot change the variance to be either
+ # covariant or contravariant as that makes our usage of ResponseT illegal. We could construct
+ # the response class ourselves but that is something that should be supported directly in httpx
+ # as it would be easy to incorrectly construct the Response object due to the multitude of arguments.
+ if cast_to != httpx.Response:
+ raise ValueError(f"Subclasses of httpx.Response cannot be passed to `cast_to`")
+ return cast(R, response)
+
+ origin_is_class = inspect.isclass(origin)
+ origin_is_base_model = origin_is_class and issubclass(origin, BaseModel)
+
+ if origin_is_class and not origin_is_base_model and issubclass(origin, pydantic.BaseModel):
+ raise TypeError(
+ "Pydantic models must subclass our base model type, e.g. `from scalar_api import BaseModel`"
+ )
+
+ if (
+ cast_to is not object
+ and not origin is list
+ and not origin is dict
+ and not origin is Union
+ and not origin_is_base_model
+ ):
+ raise RuntimeError(
+ f"Unsupported type, expected {cast_to} to be a subclass of {BaseModel}, {dict}, {list}, {Union}, {NoneType}, {str} or {httpx.Response}."
+ )
+
+ # split is required to handle cases where additional information is included
+ # in the response, e.g. application/json; charset=utf-8
+ content_type, *_ = response.headers.get("content-type", "*").split(";")
+ if not content_type.endswith("json"):
+ if is_basemodel(cast_to):
+ try:
+ data = response.json()
+ except Exception as exc:
+ log.debug("Could not read JSON from response data due to %s - %s", type(exc), exc)
+ else:
+ return self._client._process_response_data(
+ data=data,
+ cast_to=cast_to, # type: ignore
+ response=response,
+ )
+
+ if self._client._strict_response_validation:
+ raise APIResponseValidationError(
+ response=response,
+ message=f"Expected Content-Type response header to be `application/json` but received `{content_type}` instead.",
+ body=response.text,
+ )
+
+ # If the API responds with content that isn't JSON then we just return
+ # the (decoded) text without performing any parsing so that you can still
+ # handle the response however you need to.
+ return response.text # type: ignore
+
+ data = response.json()
+
+ return self._client._process_response_data(
+ data=data,
+ cast_to=cast_to, # type: ignore
+ response=response,
+ )
+
+
+class APIResponse(BaseAPIResponse[R]):
+ @overload
+ def parse(self, *, to: type[_T]) -> _T: ...
+
+ @overload
+ def parse(self) -> R: ...
+
+ def parse(self, *, to: type[_T] | None = None) -> R | _T:
+ """Returns the rich python representation of this response's data.
+
+ For lower-level control, see `.read()`, `.json()`, `.iter_bytes()`.
+
+ You can customise the type that the response is parsed into through
+ the `to` argument, e.g.
+
+ ```py
+ from scalar_api import BaseModel
+
+
+ class MyModel(BaseModel):
+ foo: str
+
+
+ obj = response.parse(to=MyModel)
+ print(obj.foo)
+ ```
+
+ We support parsing:
+ - `BaseModel`
+ - `dict`
+ - `list`
+ - `Union`
+ - `str`
+ - `int`
+ - `float`
+ - `httpx.Response`
+ """
+ cache_key = to if to is not None else self._cast_to
+ cached = self._parsed_by_type.get(cache_key)
+ if cached is not None:
+ return cached # type: ignore[no-any-return]
+
+ if not self._is_sse_stream:
+ self.read()
+
+ parsed = self._parse(to=to)
+ if is_given(self._options.post_parser):
+ parsed = self._options.post_parser(parsed)
+
+ self._parsed_by_type[cache_key] = parsed
+ return parsed
+
+ def read(self) -> bytes:
+ """Read and return the binary response content."""
+ try:
+ return self.http_response.read()
+ except httpx.StreamConsumed as exc:
+ # The default error raised by httpx isn't very
+ # helpful in our case so we re-raise it with
+ # a different error message.
+ raise StreamAlreadyConsumed() from exc
+
+ def text(self) -> str:
+ """Read and decode the response content into a string."""
+ self.read()
+ return self.http_response.text
+
+ def json(self) -> object:
+ """Read and decode the JSON response content."""
+ self.read()
+ return self.http_response.json()
+
+ def close(self) -> None:
+ """Close the response and release the connection.
+
+ Automatically called if the response body is read to completion.
+ """
+ self.http_response.close()
+
+ def iter_bytes(self, chunk_size: int | None = None) -> Iterator[bytes]:
+ """
+ A byte-iterator over the decoded response content.
+
+ This automatically handles gzip, deflate and brotli encoded responses.
+ """
+ for chunk in self.http_response.iter_bytes(chunk_size):
+ yield chunk
+
+ def iter_text(self, chunk_size: int | None = None) -> Iterator[str]:
+ """A str-iterator over the decoded response content
+ that handles both gzip, deflate, etc but also detects the content's
+ string encoding.
+ """
+ for chunk in self.http_response.iter_text(chunk_size):
+ yield chunk
+
+ def iter_lines(self) -> Iterator[str]:
+ """Like `iter_text()` but will only yield chunks for each line"""
+ for chunk in self.http_response.iter_lines():
+ yield chunk
+
+
+class AsyncAPIResponse(BaseAPIResponse[R]):
+ @overload
+ async def parse(self, *, to: type[_T]) -> _T: ...
+
+ @overload
+ async def parse(self) -> R: ...
+
+ async def parse(self, *, to: type[_T] | None = None) -> R | _T:
+ """Returns the rich python representation of this response's data.
+
+ For lower-level control, see `.read()`, `.json()`, `.iter_bytes()`.
+
+ You can customise the type that the response is parsed into through
+ the `to` argument, e.g.
+
+ ```py
+ from scalar_api import BaseModel
+
+
+ class MyModel(BaseModel):
+ foo: str
+
+
+ obj = response.parse(to=MyModel)
+ print(obj.foo)
+ ```
+
+ We support parsing:
+ - `BaseModel`
+ - `dict`
+ - `list`
+ - `Union`
+ - `str`
+ - `httpx.Response`
+ """
+ cache_key = to if to is not None else self._cast_to
+ cached = self._parsed_by_type.get(cache_key)
+ if cached is not None:
+ return cached # type: ignore[no-any-return]
+
+ if not self._is_sse_stream:
+ await self.read()
+
+ parsed = self._parse(to=to)
+ if is_given(self._options.post_parser):
+ parsed = self._options.post_parser(parsed)
+
+ self._parsed_by_type[cache_key] = parsed
+ return parsed
+
+ async def read(self) -> bytes:
+ """Read and return the binary response content."""
+ try:
+ return await self.http_response.aread()
+ except httpx.StreamConsumed as exc:
+ # the default error raised by httpx isn't very
+ # helpful in our case so we re-raise it with
+ # a different error message
+ raise StreamAlreadyConsumed() from exc
+
+ async def text(self) -> str:
+ """Read and decode the response content into a string."""
+ await self.read()
+ return self.http_response.text
+
+ async def json(self) -> object:
+ """Read and decode the JSON response content."""
+ await self.read()
+ return self.http_response.json()
+
+ async def close(self) -> None:
+ """Close the response and release the connection.
+
+ Automatically called if the response body is read to completion.
+ """
+ await self.http_response.aclose()
+
+ async def iter_bytes(self, chunk_size: int | None = None) -> AsyncIterator[bytes]:
+ """
+ A byte-iterator over the decoded response content.
+
+ This automatically handles gzip, deflate and brotli encoded responses.
+ """
+ async for chunk in self.http_response.aiter_bytes(chunk_size):
+ yield chunk
+
+ async def iter_text(self, chunk_size: int | None = None) -> AsyncIterator[str]:
+ """A str-iterator over the decoded response content
+ that handles both gzip, deflate, etc but also detects the content's
+ string encoding.
+ """
+ async for chunk in self.http_response.aiter_text(chunk_size):
+ yield chunk
+
+ async def iter_lines(self) -> AsyncIterator[str]:
+ """Like `iter_text()` but will only yield chunks for each line"""
+ async for chunk in self.http_response.aiter_lines():
+ yield chunk
+
+
+class BinaryAPIResponse(APIResponse[bytes]):
+ """Subclass of APIResponse providing helpers for dealing with binary data.
+
+ Note: If you want to stream the response data instead of eagerly reading it
+ all at once then you should use `.with_streaming_response` when making
+ the API request, e.g. `.with_streaming_response.get_binary_response()`
+ """
+
+ def write_to_file(
+ self,
+ file: str | os.PathLike[str],
+ ) -> None:
+ """Write the output to the given file.
+
+ Accepts a filename or any path-like object, e.g. pathlib.Path
+
+ Note: if you want to stream the data to the file instead of writing
+ all at once then you should use `.with_streaming_response` when making
+ the API request, e.g. `.with_streaming_response.get_binary_response()`
+ """
+ with open(file, mode="wb") as f:
+ for data in self.iter_bytes():
+ f.write(data)
+
+
+class AsyncBinaryAPIResponse(AsyncAPIResponse[bytes]):
+ """Subclass of APIResponse providing helpers for dealing with binary data.
+
+ Note: If you want to stream the response data instead of eagerly reading it
+ all at once then you should use `.with_streaming_response` when making
+ the API request, e.g. `.with_streaming_response.get_binary_response()`
+ """
+
+ async def write_to_file(
+ self,
+ file: str | os.PathLike[str],
+ ) -> None:
+ """Write the output to the given file.
+
+ Accepts a filename or any path-like object, e.g. pathlib.Path
+
+ Note: if you want to stream the data to the file instead of writing
+ all at once then you should use `.with_streaming_response` when making
+ the API request, e.g. `.with_streaming_response.get_binary_response()`
+ """
+ path = anyio.Path(file)
+ async with await path.open(mode="wb") as f:
+ async for data in self.iter_bytes():
+ await f.write(data)
+
+
+class StreamedBinaryAPIResponse(APIResponse[bytes]):
+ def stream_to_file(
+ self,
+ file: str | os.PathLike[str],
+ *,
+ chunk_size: int | None = None,
+ ) -> None:
+ """Streams the output to the given file.
+
+ Accepts a filename or any path-like object, e.g. pathlib.Path
+ """
+ with open(file, mode="wb") as f:
+ for data in self.iter_bytes(chunk_size):
+ f.write(data)
+
+
+class AsyncStreamedBinaryAPIResponse(AsyncAPIResponse[bytes]):
+ async def stream_to_file(
+ self,
+ file: str | os.PathLike[str],
+ *,
+ chunk_size: int | None = None,
+ ) -> None:
+ """Streams the output to the given file.
+
+ Accepts a filename or any path-like object, e.g. pathlib.Path
+ """
+ path = anyio.Path(file)
+ async with await path.open(mode="wb") as f:
+ async for data in self.iter_bytes(chunk_size):
+ await f.write(data)
+
+
+class MissingStreamClassError(TypeError):
+ def __init__(self) -> None:
+ super().__init__(
+ "The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `scalar_api._streaming` for reference",
+ )
+
+
+class StreamAlreadyConsumed(ScalarApiError):
+ """
+ Attempted to read or stream content, but the content has already
+ been streamed.
+
+ This can happen if you use a method like `.iter_lines()` and then attempt
+ to read th entire response body afterwards, e.g.
+
+ ```py
+ response = await client.post(...)
+ async for line in response.iter_lines():
+ ... # do something with `line`
+
+ content = await response.read()
+ # ^ error
+ ```
+
+ If you want this behaviour you'll need to either manually accumulate the response
+ content or call `await response.read()` before iterating over the stream.
+ """
+
+ def __init__(self) -> None:
+ message = (
+ "Attempted to read or stream some content, but the content has "
+ "already been streamed. "
+ "This could be due to attempting to stream the response "
+ "content more than once."
+ "\n\n"
+ "You can fix this by manually accumulating the response content while streaming "
+ "or by calling `.read()` before starting to stream."
+ )
+ super().__init__(message)
+
+
+class ResponseContextManager(Generic[_APIResponseT]):
+ """Context manager for ensuring that a request is not made
+ until it is entered and that the response will always be closed
+ when the context manager exits
+ """
+
+ def __init__(self, request_func: Callable[[], _APIResponseT]) -> None:
+ self._request_func = request_func
+ self.__response: _APIResponseT | None = None
+
+ def __enter__(self) -> _APIResponseT:
+ self.__response = self._request_func()
+ return self.__response
+
+ def __exit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc: BaseException | None,
+ exc_tb: TracebackType | None,
+ ) -> None:
+ if self.__response is not None:
+ self.__response.close()
+
+
+class AsyncResponseContextManager(Generic[_AsyncAPIResponseT]):
+ """Context manager for ensuring that a request is not made
+ until it is entered and that the response will always be closed
+ when the context manager exits
+ """
+
+ def __init__(self, api_request: Awaitable[_AsyncAPIResponseT]) -> None:
+ self._api_request = api_request
+ self.__response: _AsyncAPIResponseT | None = None
+
+ async def __aenter__(self) -> _AsyncAPIResponseT:
+ self.__response = await self._api_request
+ return self.__response
+
+ async def __aexit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc: BaseException | None,
+ exc_tb: TracebackType | None,
+ ) -> None:
+ if self.__response is not None:
+ await self.__response.close()
+
+
+def to_streamed_response_wrapper(func: Callable[P, R]) -> Callable[P, ResponseContextManager[APIResponse[R]]]:
+ """Higher order function that takes one of our bound API methods and wraps it
+ to support streaming and returning the raw `APIResponse` object directly.
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> ResponseContextManager[APIResponse[R]]:
+ extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "stream"
+
+ kwargs["extra_headers"] = extra_headers
+
+ make_request = functools.partial(func, *args, **kwargs)
+
+ return ResponseContextManager(cast(Callable[[], APIResponse[R]], make_request))
+
+ return wrapped
+
+
+def async_to_streamed_response_wrapper(
+ func: Callable[P, Awaitable[R]],
+) -> Callable[P, AsyncResponseContextManager[AsyncAPIResponse[R]]]:
+ """Higher order function that takes one of our bound API methods and wraps it
+ to support streaming and returning the raw `APIResponse` object directly.
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncResponseContextManager[AsyncAPIResponse[R]]:
+ extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "stream"
+
+ kwargs["extra_headers"] = extra_headers
+
+ make_request = func(*args, **kwargs)
+
+ return AsyncResponseContextManager(cast(Awaitable[AsyncAPIResponse[R]], make_request))
+
+ return wrapped
+
+
+def to_custom_streamed_response_wrapper(
+ func: Callable[P, object],
+ response_cls: type[_APIResponseT],
+) -> Callable[P, ResponseContextManager[_APIResponseT]]:
+ """Higher order function that takes one of our bound API methods and an `APIResponse` class
+ and wraps the method to support streaming and returning the given response class directly.
+
+ Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])`
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> ResponseContextManager[_APIResponseT]:
+ extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "stream"
+ extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls
+
+ kwargs["extra_headers"] = extra_headers
+
+ make_request = functools.partial(func, *args, **kwargs)
+
+ return ResponseContextManager(cast(Callable[[], _APIResponseT], make_request))
+
+ return wrapped
+
+
+def async_to_custom_streamed_response_wrapper(
+ func: Callable[P, Awaitable[object]],
+ response_cls: type[_AsyncAPIResponseT],
+) -> Callable[P, AsyncResponseContextManager[_AsyncAPIResponseT]]:
+ """Higher order function that takes one of our bound API methods and an `APIResponse` class
+ and wraps the method to support streaming and returning the given response class directly.
+
+ Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])`
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncResponseContextManager[_AsyncAPIResponseT]:
+ extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "stream"
+ extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls
+
+ kwargs["extra_headers"] = extra_headers
+
+ make_request = func(*args, **kwargs)
+
+ return AsyncResponseContextManager(cast(Awaitable[_AsyncAPIResponseT], make_request))
+
+ return wrapped
+
+
+def to_raw_response_wrapper(func: Callable[P, R]) -> Callable[P, APIResponse[R]]:
+ """Higher order function that takes one of our bound API methods and wraps it
+ to support returning the raw `APIResponse` object directly.
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> APIResponse[R]:
+ extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "raw"
+
+ kwargs["extra_headers"] = extra_headers
+
+ return cast(APIResponse[R], func(*args, **kwargs))
+
+ return wrapped
+
+
+def async_to_raw_response_wrapper(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[AsyncAPIResponse[R]]]:
+ """Higher order function that takes one of our bound API methods and wraps it
+ to support returning the raw `APIResponse` object directly.
+ """
+
+ @functools.wraps(func)
+ async def wrapped(*args: P.args, **kwargs: P.kwargs) -> AsyncAPIResponse[R]:
+ extra_headers: dict[str, str] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "raw"
+
+ kwargs["extra_headers"] = extra_headers
+
+ return cast(AsyncAPIResponse[R], await func(*args, **kwargs))
+
+ return wrapped
+
+
+def to_custom_raw_response_wrapper(
+ func: Callable[P, object],
+ response_cls: type[_APIResponseT],
+) -> Callable[P, _APIResponseT]:
+ """Higher order function that takes one of our bound API methods and an `APIResponse` class
+ and wraps the method to support returning the given response class directly.
+
+ Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])`
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> _APIResponseT:
+ extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "raw"
+ extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls
+
+ kwargs["extra_headers"] = extra_headers
+
+ return cast(_APIResponseT, func(*args, **kwargs))
+
+ return wrapped
+
+
+def async_to_custom_raw_response_wrapper(
+ func: Callable[P, Awaitable[object]],
+ response_cls: type[_AsyncAPIResponseT],
+) -> Callable[P, Awaitable[_AsyncAPIResponseT]]:
+ """Higher order function that takes one of our bound API methods and an `APIResponse` class
+ and wraps the method to support returning the given response class directly.
+
+ Note: the given `response_cls` *must* be concrete, e.g. `class BinaryAPIResponse(APIResponse[bytes])`
+ """
+
+ @functools.wraps(func)
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> Awaitable[_AsyncAPIResponseT]:
+ extra_headers: dict[str, Any] = {**(cast(Any, kwargs.get("extra_headers")) or {})}
+ extra_headers[RAW_RESPONSE_HEADER] = "raw"
+ extra_headers[OVERRIDE_CAST_TO_HEADER] = response_cls
+
+ kwargs["extra_headers"] = extra_headers
+
+ return cast(Awaitable[_AsyncAPIResponseT], func(*args, **kwargs))
+
+ return wrapped
+
+
+def extract_response_type(typ: type[BaseAPIResponse[Any]]) -> type:
+ """Given a type like `APIResponse[T]`, returns the generic type variable `T`.
+
+ This also handles the case where a concrete subclass is given, e.g.
+ ```py
+ class MyResponse(APIResponse[bytes]):
+ ...
+
+ extract_response_type(MyResponse) -> bytes
+ ```
+ """
+ return extract_type_var_from_base(
+ typ,
+ generic_bases=cast("tuple[type, ...]", (BaseAPIResponse, APIResponse, AsyncAPIResponse)),
+ index=0,
+ )
diff --git a/src/_send_queue.py b/src/_send_queue.py
new file mode 100644
index 0000000..3140d45
--- /dev/null
+++ b/src/_send_queue.py
@@ -0,0 +1,90 @@
+# File generated from our OpenAPI spec by Scalar. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import typing
+import threading
+
+from ._exceptions import WebSocketQueueFullError
+
+
+class SendQueue:
+ """Bounded byte-size queue for outgoing WebSocket messages.
+
+ Messages are stored as pre-serialized strings. The queue enforces a
+ maximum byte budget so that unbounded buffering cannot occur during
+ reconnection windows.
+ """
+
+ def __init__(self, max_bytes: int = 1_048_576) -> None:
+ self._queue: list[tuple[str, int]] = [] # (data, byte_length)
+ self._bytes: int = 0
+ self._max_bytes = max_bytes
+ self._lock = threading.Lock()
+
+ def enqueue(self, data: str) -> None:
+ """Append *data* to the queue.
+
+ Raises :class:`WebSocketQueueFullError` if the message would
+ exceed the byte-size limit.
+ """
+ byte_length = len(data.encode("utf-8"))
+ with self._lock:
+ if self._bytes + byte_length > self._max_bytes:
+ raise WebSocketQueueFullError("send queue is full, message discarded")
+ self._queue.append((data, byte_length))
+ self._bytes += byte_length
+
+ def flush_sync(self, send: typing.Callable[[str], object]) -> None:
+ """Send every queued message via *send*.
+
+ If *send* raises, the failing message and all subsequent messages
+ are re-queued and the error is re-raised.
+ """
+ with self._lock:
+ pending = list(self._queue)
+ self._queue.clear()
+ self._bytes = 0
+
+ for i, (data, _byte_length) in enumerate(pending):
+ try:
+ send(data)
+ except Exception:
+ with self._lock:
+ remaining = pending[i:]
+ self._queue = remaining + self._queue
+ self._bytes = sum(bl for _, bl in self._queue)
+ raise
+
+ async def flush_async(self, send: typing.Callable[[str], typing.Awaitable[object]]) -> None:
+ """Async variant of :meth:`flush_sync`."""
+ with self._lock:
+ pending = list(self._queue)
+ self._queue.clear()
+ self._bytes = 0
+
+ for i, (data, _byte_length) in enumerate(pending):
+ try:
+ await send(data)
+ except Exception:
+ with self._lock:
+ remaining = pending[i:]
+ self._queue = remaining + self._queue
+ self._bytes = sum(bl for _, bl in self._queue)
+ raise
+
+ def drain(self) -> list[str]:
+ """Remove and return all queued messages."""
+ with self._lock:
+ items = [data for data, _ in self._queue]
+ self._queue.clear()
+ self._bytes = 0
+ return items
+
+ def __len__(self) -> int:
+ with self._lock:
+ return len(self._queue)
+
+ def __bool__(self) -> bool:
+ with self._lock:
+ return len(self._queue) > 0
diff --git a/src/_streaming.py b/src/_streaming.py
new file mode 100644
index 0000000..8105558
--- /dev/null
+++ b/src/_streaming.py
@@ -0,0 +1,470 @@
+# Note: initially copied from https://github.com/florimondmanca/httpx-sse/blob/master/src/httpx_sse/_decoders.py
+from __future__ import annotations
+
+import json
+import inspect
+from types import TracebackType
+from typing import TYPE_CHECKING, Any, Generic, List, Mapping, Optional, Sequence, TypeVar, Union, Iterator, AsyncIterator, cast
+from typing_extensions import Self, Protocol, TypeGuard, override, get_origin, runtime_checkable
+
+import httpx
+
+from ._utils import extract_type_var_from_base
+
+if TYPE_CHECKING:
+ from ._client import ScalarApi, AsyncScalarApi
+ from ._models import FinalRequestOptions
+
+
+_T = TypeVar("_T")
+
+
+# Mirrors `StreamingEventHandler` from the IR (`packages/ir-compiler/src/
+# types.ts`). The generated client emits its own `_streaming_handlers`
+# list populated from `ctx.config.streaming.onEvent`; the runtime
+# dispatch below honors `continue`, `ignore`, `error`, and `yield`
+# actions the same way the TypeScript runtime does. When the client has
+# no handlers we fall back to the generic "yield every data-bearing
+# event" behavior so SDKs without a streaming config still work.
+StreamingEventHandler = Mapping[str, Any]
+
+
+def _event_type_matches(event: Optional[str], expected: Any) -> bool:
+ if expected is None:
+ return event is None
+ if isinstance(expected, (list, tuple)):
+ return (event or "") in expected
+ return expected is not None and event == expected
+
+
+def _stream_handler_for_sse(
+ sse: "ServerSentEvent",
+ handlers: Optional[Sequence[StreamingEventHandler]],
+) -> Optional[StreamingEventHandler]:
+ if not handlers:
+ return None
+ for handler in handlers:
+ if handler.get("kind") == "data":
+ prefix = handler.get("dataStartsWith")
+ if isinstance(prefix, str) and sse.data.startswith(prefix):
+ return handler
+ for handler in handlers:
+ kind = handler.get("kind")
+ if kind == "event" and _event_type_matches(sse.event, handler.get("eventType")):
+ return handler
+ if kind == "fallthrough":
+ return handler
+ return None
+
+
+def _stream_error_message(sse: "ServerSentEvent", handler: StreamingEventHandler) -> tuple[Any, str]:
+ body: Any = sse.data
+ try:
+ body = sse.json()
+ except Exception:
+ body = sse.data
+ error_property = handler.get("errorProperty")
+ payload = body
+ if isinstance(payload, dict) and isinstance(error_property, str) and error_property in payload:
+ payload = payload[error_property]
+ return body, f"{payload}" if payload is not None else (sse.data or "Stream error")
+
+
+class Stream(Generic[_T]):
+ """Provides the core interface to iterate over a synchronous stream response."""
+
+ response: httpx.Response
+ _options: Optional[FinalRequestOptions] = None
+ _decoder: SSEBytesDecoder
+
+ def __init__(
+ self,
+ *,
+ cast_to: type[_T],
+ response: httpx.Response,
+ client: ScalarApi,
+ options: Optional[FinalRequestOptions] = None,
+ ) -> None:
+ self.response = response
+ self._cast_to = cast_to
+ self._client = client
+ self._options = options
+ self._decoder = client._make_sse_decoder()
+ self._iterator = self.__stream__()
+
+ def __next__(self) -> _T:
+ return self._iterator.__next__()
+
+ def __iter__(self) -> Iterator[_T]:
+ for item in self._iterator:
+ yield item
+
+ def _iter_events(self) -> Iterator[ServerSentEvent]:
+ yield from self._decoder.iter_bytes(self.response.iter_bytes())
+
+ def __stream__(self) -> Iterator[_T]:
+ cast_to = cast(Any, self._cast_to)
+ response = self.response
+ process_data = self._client._process_response_data
+ iterator = self._iter_events()
+ handlers = getattr(self._client, "_streaming_handlers", None)
+ content_type = (response.headers.get("content-type") or "").lower()
+ is_jsonl = "json" in content_type and "event-stream" not in content_type
+
+ try:
+ if is_jsonl:
+ # Newline-delimited JSON (`application/jsonl`,
+ # `application/x-jsonl`, etc.) has no SSE framing, so the
+ # `_decoder.iter_bytes` path above would never yield. We
+ # parse each non-empty line as one event so callers can
+ # iterate without caring whether the wire format is SSE
+ # or JSONL.
+ buffer = b""
+ for chunk in response.iter_bytes():
+ if not chunk:
+ continue
+ buffer += chunk
+ while b"\n" in buffer:
+ line, buffer = buffer.split(b"\n", 1)
+ text = line.decode("utf-8").strip()
+ if not text:
+ continue
+ yield process_data(data=json.loads(text), cast_to=cast_to, response=response)
+ tail = buffer.decode("utf-8").strip()
+ if tail:
+ yield process_data(data=json.loads(tail), cast_to=cast_to, response=response)
+ return
+
+ for sse in iterator:
+ # Dispatch every SSE event through the
+ # config-derived handler list. With no handlers
+ # configured we fall back to "yield every data-bearing
+ # event" which matches the TypeScript runtime.
+ handler = _stream_handler_for_sse(sse, handlers)
+ action = handler.get("handle") if handler else None
+ if action in ("continue", "ignore"):
+ continue
+ if action == "error" and handler is not None:
+ body, err_msg = _stream_error_message(sse, handler)
+ raise self._client._make_status_error(err_msg, body=body, response=self.response)
+ if handlers and action != "yield":
+ continue
+ if not sse.data:
+ continue
+ try:
+ payload = sse.json()
+ except Exception:
+ payload = sse.data
+ yield process_data(data=payload, cast_to=cast_to, response=response)
+ finally:
+ # Ensure the response is closed even if the consumer doesn't read all data
+ response.close()
+
+ def __enter__(self) -> Self:
+ return self
+
+ def __exit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc: BaseException | None,
+ exc_tb: TracebackType | None,
+ ) -> None:
+ self.close()
+
+ def close(self) -> None:
+ """
+ Close the response and release the connection.
+
+ Automatically called if the response body is read to completion.
+ """
+ self.response.close()
+
+
+class AsyncStream(Generic[_T]):
+ """Provides the core interface to iterate over an asynchronous stream response."""
+
+ response: httpx.Response
+ _options: Optional[FinalRequestOptions] = None
+ _decoder: SSEDecoder | SSEBytesDecoder
+
+ def __init__(
+ self,
+ *,
+ cast_to: type[_T],
+ response: httpx.Response,
+ client: AsyncScalarApi,
+ options: Optional[FinalRequestOptions] = None,
+ ) -> None:
+ self.response = response
+ self._cast_to = cast_to
+ self._client = client
+ self._options = options
+ self._decoder = client._make_sse_decoder()
+ self._iterator = self.__stream__()
+
+ async def __anext__(self) -> _T:
+ return await self._iterator.__anext__()
+
+ async def __aiter__(self) -> AsyncIterator[_T]:
+ async for item in self._iterator:
+ yield item
+
+ async def _iter_events(self) -> AsyncIterator[ServerSentEvent]:
+ async for sse in self._decoder.aiter_bytes(self.response.aiter_bytes()):
+ yield sse
+
+ async def __stream__(self) -> AsyncIterator[_T]:
+ cast_to = cast(Any, self._cast_to)
+ response = self.response
+ process_data = self._client._process_response_data
+ iterator = self._iter_events()
+ handlers = getattr(self._client, "_streaming_handlers", None)
+ content_type = (response.headers.get("content-type") or "").lower()
+ is_jsonl = "json" in content_type and "event-stream" not in content_type
+
+ try:
+ if is_jsonl:
+ # See the sync sibling for why JSONL gets its own branch.
+ buffer = b""
+ async for chunk in response.aiter_bytes():
+ if not chunk:
+ continue
+ buffer += chunk
+ while b"\n" in buffer:
+ line, buffer = buffer.split(b"\n", 1)
+ text = line.decode("utf-8").strip()
+ if not text:
+ continue
+ yield process_data(data=json.loads(text), cast_to=cast_to, response=response)
+ tail = buffer.decode("utf-8").strip()
+ if tail:
+ yield process_data(data=json.loads(tail), cast_to=cast_to, response=response)
+ return
+
+ async for sse in iterator:
+ handler = _stream_handler_for_sse(sse, handlers)
+ action = handler.get("handle") if handler else None
+ if action in ("continue", "ignore"):
+ continue
+ if action == "error" and handler is not None:
+ body, err_msg = _stream_error_message(sse, handler)
+ raise self._client._make_status_error(err_msg, body=body, response=self.response)
+ if handlers and action != "yield":
+ continue
+ if not sse.data:
+ continue
+ try:
+ payload = sse.json()
+ except Exception:
+ payload = sse.data
+ yield process_data(data=payload, cast_to=cast_to, response=response)
+ finally:
+ # Ensure the response is closed even if the consumer doesn't read all data
+ await response.aclose()
+
+ async def __aenter__(self) -> Self:
+ return self
+
+ async def __aexit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc: BaseException | None,
+ exc_tb: TracebackType | None,
+ ) -> None:
+ await self.close()
+
+ async def close(self) -> None:
+ """
+ Close the response and release the connection.
+
+ Automatically called if the response body is read to completion.
+ """
+ await self.response.aclose()
+
+
+class ServerSentEvent:
+ def __init__(
+ self,
+ *,
+ event: str | None = None,
+ data: str | None = None,
+ id: str | None = None,
+ retry: int | None = None,
+ ) -> None:
+ if data is None:
+ data = ""
+
+ self._id = id
+ self._data = data
+ self._event = event or None
+ self._retry = retry
+
+ @property
+ def event(self) -> str | None:
+ return self._event
+
+ @property
+ def id(self) -> str | None:
+ return self._id
+
+ @property
+ def retry(self) -> int | None:
+ return self._retry
+
+ @property
+ def data(self) -> str:
+ return self._data
+
+ def json(self) -> Any:
+ return json.loads(self.data)
+
+ @override
+ def __repr__(self) -> str:
+ return f"ServerSentEvent(event={self.event}, data={self.data}, id={self.id}, retry={self.retry})"
+
+
+class SSEDecoder:
+ _data: list[str]
+ _event: str | None
+ _retry: int | None
+ _last_event_id: str | None
+
+ def __init__(self) -> None:
+ self._event = None
+ self._data = []
+ self._last_event_id = None
+ self._retry = None
+
+ def iter_bytes(self, iterator: Iterator[bytes]) -> Iterator[ServerSentEvent]:
+ """Given an iterator that yields raw binary data, iterate over it & yield every event encountered"""
+ for chunk in self._iter_chunks(iterator):
+ # Split before decoding so splitlines() only uses \r and \n
+ for raw_line in chunk.splitlines():
+ line = raw_line.decode("utf-8")
+ sse = self.decode(line)
+ if sse:
+ yield sse
+
+ def _iter_chunks(self, iterator: Iterator[bytes]) -> Iterator[bytes]:
+ """Given an iterator that yields raw binary data, iterate over it and yield individual SSE chunks"""
+ data = b""
+ for chunk in iterator:
+ for line in chunk.splitlines(keepends=True):
+ data += line
+ if data.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")):
+ yield data
+ data = b""
+ if data:
+ yield data
+
+ async def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]:
+ """Given an iterator that yields raw binary data, iterate over it & yield every event encountered"""
+ async for chunk in self._aiter_chunks(iterator):
+ # Split before decoding so splitlines() only uses \r and \n
+ for raw_line in chunk.splitlines():
+ line = raw_line.decode("utf-8")
+ sse = self.decode(line)
+ if sse:
+ yield sse
+
+ async def _aiter_chunks(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[bytes]:
+ """Given an iterator that yields raw binary data, iterate over it and yield individual SSE chunks"""
+ data = b""
+ async for chunk in iterator:
+ for line in chunk.splitlines(keepends=True):
+ data += line
+ if data.endswith((b"\r\r", b"\n\n", b"\r\n\r\n")):
+ yield data
+ data = b""
+ if data:
+ yield data
+
+ def decode(self, line: str) -> ServerSentEvent | None:
+ # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501
+
+ if not line:
+ if not self._event and not self._data and not self._last_event_id and self._retry is None:
+ return None
+
+ sse = ServerSentEvent(
+ event=self._event,
+ data="\n".join(self._data),
+ id=self._last_event_id,
+ retry=self._retry,
+ )
+
+ # NOTE: as per the SSE spec, do not reset last_event_id.
+ self._event = None
+ self._data = []
+ self._retry = None
+
+ return sse
+
+ if line.startswith(":"):
+ return None
+
+ fieldname, _, value = line.partition(":")
+
+ if value.startswith(" "):
+ value = value[1:]
+
+ if fieldname == "event":
+ self._event = value
+ elif fieldname == "data":
+ self._data.append(value)
+ elif fieldname == "id":
+ if "\0" in value:
+ pass
+ else:
+ self._last_event_id = value
+ elif fieldname == "retry":
+ try:
+ self._retry = int(value)
+ except (TypeError, ValueError):
+ pass
+ else:
+ pass # Field is ignored.
+
+ return None
+
+
+@runtime_checkable
+class SSEBytesDecoder(Protocol):
+ def iter_bytes(self, iterator: Iterator[bytes]) -> Iterator[ServerSentEvent]:
+ """Given an iterator that yields raw binary data, iterate over it & yield every event encountered"""
+ ...
+
+ def aiter_bytes(self, iterator: AsyncIterator[bytes]) -> AsyncIterator[ServerSentEvent]:
+ """Given an async iterator that yields raw binary data, iterate over it & yield every event encountered"""
+ ...
+
+
+def is_stream_class_type(typ: type) -> TypeGuard[type[Stream[object]] | type[AsyncStream[object]]]:
+ """TypeGuard for determining whether or not the given type is a subclass of `Stream` / `AsyncStream`"""
+ origin = get_origin(typ) or typ
+ return inspect.isclass(origin) and issubclass(origin, (Stream, AsyncStream))
+
+
+def extract_stream_chunk_type(
+ stream_cls: type,
+ *,
+ failure_message: str | None = None,
+) -> type:
+ """Given a type like `Stream[T]`, returns the generic type variable `T`.
+
+ This also handles the case where a concrete subclass is given, e.g.
+ ```py
+ class MyStream(Stream[bytes]):
+ ...
+
+ extract_stream_chunk_type(MyStream) -> bytes
+ ```
+ """
+ from ._base_client import Stream, AsyncStream
+
+ return extract_type_var_from_base(
+ stream_cls,
+ index=0,
+ generic_bases=cast("tuple[type, ...]", (Stream, AsyncStream)),
+ failure_message=failure_message,
+ )
diff --git a/src/_types.py b/src/_types.py
new file mode 100644
index 0000000..047012f
--- /dev/null
+++ b/src/_types.py
@@ -0,0 +1,274 @@
+from __future__ import annotations
+
+from os import PathLike
+from typing import (
+ IO,
+ TYPE_CHECKING,
+ Any,
+ Dict,
+ List,
+ Type,
+ Tuple,
+ Union,
+ Mapping,
+ TypeVar,
+ Callable,
+ Iterable,
+ Iterator,
+ Optional,
+ Sequence,
+ AsyncIterable,
+)
+from typing_extensions import (
+ Set,
+ Literal,
+ Protocol,
+ TypeAlias,
+ TypedDict,
+ SupportsIndex,
+ overload,
+ override,
+ runtime_checkable,
+)
+
+import httpx
+import pydantic
+from httpx import URL, Proxy, Timeout, Response, BaseTransport, AsyncBaseTransport
+
+if TYPE_CHECKING:
+ from ._models import BaseModel, SecurityOptions
+ from ._response import APIResponse, AsyncAPIResponse
+
+Transport = BaseTransport
+AsyncTransport = AsyncBaseTransport
+Query = Mapping[str, object]
+Body = object
+AnyMapping = Mapping[str, object]
+ModelT = TypeVar("ModelT", bound=pydantic.BaseModel)
+_T = TypeVar("_T")
+
+ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
+NestedFormat = Literal["dots", "brackets"]
+
+
+# Approximates httpx internal ProxiesTypes and RequestFiles types
+# while adding support for `PathLike` instances
+ProxiesDict = Dict["str | URL", Union[None, str, URL, Proxy]]
+ProxiesTypes = Union[str, Proxy, ProxiesDict]
+if TYPE_CHECKING:
+ Base64FileInput = Union[IO[bytes], PathLike[str]]
+ FileContent = Union[IO[bytes], bytes, PathLike[str]]
+else:
+ Base64FileInput = Union[IO[bytes], PathLike]
+ FileContent = Union[IO[bytes], bytes, PathLike] # PathLike is not subscriptable in Python 3.8.
+
+
+# Used for sending raw binary data / streaming data in request bodies
+# e.g. for file uploads without multipart encoding
+BinaryTypes = Union[bytes, bytearray, IO[bytes], Iterable[bytes]]
+AsyncBinaryTypes = Union[bytes, bytearray, IO[bytes], AsyncIterable[bytes]]
+
+FileTypes = Union[
+ # file (or bytes)
+ FileContent,
+ # (filename, file (or bytes))
+ Tuple[Optional[str], FileContent],
+ # (filename, file (or bytes), content_type)
+ Tuple[Optional[str], FileContent, Optional[str]],
+ # (filename, file (or bytes), content_type, headers)
+ Tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]],
+]
+RequestFiles = Union[Mapping[str, FileTypes], Sequence[Tuple[str, FileTypes]]]
+
+# duplicate of the above but without our custom file support
+HttpxFileContent = Union[IO[bytes], bytes]
+HttpxFileTypes = Union[
+ # file (or bytes)
+ HttpxFileContent,
+ # (filename, file (or bytes))
+ Tuple[Optional[str], HttpxFileContent],
+ # (filename, file (or bytes), content_type)
+ Tuple[Optional[str], HttpxFileContent, Optional[str]],
+ # (filename, file (or bytes), content_type, headers)
+ Tuple[Optional[str], HttpxFileContent, Optional[str], Mapping[str, str]],
+]
+HttpxRequestFiles = Union[Mapping[str, HttpxFileTypes], Sequence[Tuple[str, HttpxFileTypes]]]
+
+# Workaround to support (cast_to: Type[ResponseT]) -> ResponseT
+# where ResponseT includes `None`. In order to support directly
+# passing `None`, overloads would have to be defined for every
+# method that uses `ResponseT` which would lead to an unacceptable
+# amount of code duplication and make it unreadable. See _base_client.py
+# for example usage.
+#
+# This unfortunately means that you will either have
+# to import this type and pass it explicitly:
+#
+# from scalar_api import NoneType
+# client.get('/foo', cast_to=NoneType)
+#
+# or build it yourself:
+#
+# client.get('/foo', cast_to=type(None))
+if TYPE_CHECKING:
+ NoneType: Type[None]
+else:
+ NoneType = type(None)
+
+
+class RequestOptions(TypedDict, total=False):
+ headers: Headers
+ max_retries: int
+ timeout: float | Timeout | None
+ params: Query
+ extra_json: AnyMapping
+ idempotency_key: str
+ follow_redirects: bool
+ security: SecurityOptions
+
+
+# Sentinel class used until PEP 0661 is accepted
+class NotGiven:
+ """
+ For parameters with a meaningful None value, we need to distinguish between
+ the user explicitly passing None, and the user not passing the parameter at
+ all.
+
+ User code shouldn't need to use not_given directly.
+
+ For example:
+
+ ```py
+ def create(timeout: Timeout | None | NotGiven = not_given): ...
+
+
+ create(timeout=1) # 1s timeout
+ create(timeout=None) # No timeout
+ create() # Default timeout behavior
+ ```
+ """
+
+ def __bool__(self) -> Literal[False]:
+ return False
+
+ @override
+ def __repr__(self) -> str:
+ return "NOT_GIVEN"
+
+
+not_given = NotGiven()
+# for backwards compatibility:
+NOT_GIVEN = NotGiven()
+
+
+class Omit:
+ """
+ To explicitly omit something from being sent in a request, use `omit`.
+
+ ```py
+ # as the default `Content-Type` header is `application/json` that will be sent
+ client.post("/upload/files", files={"file": b"my raw file content"})
+
+ # you can't explicitly override the header as it has to be dynamically generated
+ # to look something like: 'multipart/form-data; boundary=0d8382fcf5f8c3be01ca2e11002d2983'
+ client.post(..., headers={"Content-Type": "multipart/form-data"})
+
+ # instead you can remove the default `application/json` header by passing omit
+ client.post(..., headers={"Content-Type": omit})
+ ```
+ """
+
+ def __bool__(self) -> Literal[False]:
+ return False
+
+
+omit = Omit()
+
+
+@runtime_checkable
+class ModelBuilderProtocol(Protocol):
+ @classmethod
+ def build(
+ cls: type[_T],
+ *,
+ response: Response,
+ data: object,
+ ) -> _T: ...
+
+
+Headers = Mapping[str, Union[str, Omit]]
+
+
+class HeadersLikeProtocol(Protocol):
+ def get(self, __key: str) -> str | None: ...
+
+
+HeadersLike = Union[Headers, HeadersLikeProtocol]
+
+ResponseT = TypeVar(
+ "ResponseT",
+ bound=Union[
+ object,
+ str,
+ None,
+ "BaseModel",
+ List[Any],
+ Dict[str, Any],
+ Response,
+ ModelBuilderProtocol,
+ "APIResponse[Any]",
+ "AsyncAPIResponse[Any]",
+ ],
+)
+
+StrBytesIntFloat = Union[str, bytes, int, float]
+
+# Note: copied from Pydantic
+# https://github.com/pydantic/pydantic/blob/6f31f8f68ef011f84357330186f603ff295312fd/pydantic/main.py#L79
+IncEx: TypeAlias = Union[Set[int], Set[str], Mapping[int, Union["IncEx", bool]], Mapping[str, Union["IncEx", bool]]]
+
+PostParser = Callable[[Any], Any]
+
+
+@runtime_checkable
+class InheritsGeneric(Protocol):
+ """Represents a type that has inherited from `Generic`
+
+ The `__orig_bases__` property can be used to determine the resolved
+ type variable for a given base class.
+ """
+
+ __orig_bases__: tuple[_GenericAlias]
+
+
+class _GenericAlias(Protocol):
+ __origin__: type[object]
+
+
+class HttpxSendArgs(TypedDict, total=False):
+ auth: httpx.Auth
+ follow_redirects: bool
+
+
+_T_co = TypeVar("_T_co", covariant=True)
+
+
+if TYPE_CHECKING:
+ # This works because str.__contains__ does not accept object (either in typeshed or at runtime)
+ # https://github.com/hauntsaninja/useful_types/blob/5e9710f3875107d068e7679fd7fec9cfab0eff3b/useful_types/__init__.py#L285
+ #
+ # Note: index() and count() methods are intentionally omitted to allow pyright to properly
+ # infer TypedDict types when dict literals are used in lists assigned to SequenceNotStr.
+ class SequenceNotStr(Protocol[_T_co]):
+ @overload
+ def __getitem__(self, index: SupportsIndex, /) -> _T_co: ...
+ @overload
+ def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ...
+ def __contains__(self, value: object, /) -> bool: ...
+ def __len__(self) -> int: ...
+ def __iter__(self) -> Iterator[_T_co]: ...
+ def __reversed__(self) -> Iterator[_T_co]: ...
+else:
+ # just point this to a normal `Sequence` at runtime to avoid having to special case
+ # deserializing our custom sequence type
+ SequenceNotStr = Sequence
diff --git a/src/_utils/__init__.py b/src/_utils/__init__.py
new file mode 100644
index 0000000..1c090e5
--- /dev/null
+++ b/src/_utils/__init__.py
@@ -0,0 +1,64 @@
+from ._path import path_template as path_template
+from ._sync import asyncify as asyncify
+from ._proxy import LazyProxy as LazyProxy
+from ._utils import (
+ flatten as flatten,
+ is_dict as is_dict,
+ is_list as is_list,
+ is_given as is_given,
+ is_tuple as is_tuple,
+ json_safe as json_safe,
+ lru_cache as lru_cache,
+ is_mapping as is_mapping,
+ is_tuple_t as is_tuple_t,
+ is_iterable as is_iterable,
+ is_sequence as is_sequence,
+ coerce_float as coerce_float,
+ is_mapping_t as is_mapping_t,
+ removeprefix as removeprefix,
+ removesuffix as removesuffix,
+ extract_files as extract_files,
+ is_sequence_t as is_sequence_t,
+ required_args as required_args,
+ coerce_boolean as coerce_boolean,
+ coerce_integer as coerce_integer,
+ file_from_path as file_from_path,
+ strip_not_given as strip_not_given,
+ get_async_library as get_async_library,
+ maybe_coerce_float as maybe_coerce_float,
+ get_required_header as get_required_header,
+ maybe_coerce_boolean as maybe_coerce_boolean,
+ maybe_coerce_integer as maybe_coerce_integer,
+)
+from ._compat import (
+ get_args as get_args,
+ is_union as is_union,
+ get_origin as get_origin,
+ is_typeddict as is_typeddict,
+ is_literal_type as is_literal_type,
+)
+from ._typing import (
+ is_list_type as is_list_type,
+ is_union_type as is_union_type,
+ extract_type_arg as extract_type_arg,
+ is_iterable_type as is_iterable_type,
+ is_required_type as is_required_type,
+ is_sequence_type as is_sequence_type,
+ is_annotated_type as is_annotated_type,
+ is_type_alias_type as is_type_alias_type,
+ strip_annotated_type as strip_annotated_type,
+ extract_type_var_from_base as extract_type_var_from_base,
+)
+from ._streams import consume_sync_iterator as consume_sync_iterator, consume_async_iterator as consume_async_iterator
+from ._transform import (
+ PropertyInfo as PropertyInfo,
+ transform as transform,
+ async_transform as async_transform,
+ maybe_transform as maybe_transform,
+ async_maybe_transform as async_maybe_transform,
+)
+from ._reflection import (
+ function_has_argument as function_has_argument,
+ assert_signatures_in_sync as assert_signatures_in_sync,
+)
+from ._datetime_parse import parse_date as parse_date, parse_datetime as parse_datetime
diff --git a/src/_utils/_compat.py b/src/_utils/_compat.py
new file mode 100644
index 0000000..2c70b29
--- /dev/null
+++ b/src/_utils/_compat.py
@@ -0,0 +1,45 @@
+from __future__ import annotations
+
+import sys
+import typing_extensions
+from typing import Any, Type, Union, Literal, Optional
+from datetime import date, datetime
+from typing_extensions import get_args as _get_args, get_origin as _get_origin
+
+from .._types import StrBytesIntFloat
+from ._datetime_parse import parse_date as _parse_date, parse_datetime as _parse_datetime
+
+_LITERAL_TYPES = {Literal, typing_extensions.Literal}
+
+
+def get_args(tp: type[Any]) -> tuple[Any, ...]:
+ return _get_args(tp)
+
+
+def get_origin(tp: type[Any]) -> type[Any] | None:
+ return _get_origin(tp)
+
+
+def is_union(tp: Optional[Type[Any]]) -> bool:
+ if sys.version_info < (3, 10):
+ return tp is Union # type: ignore[comparison-overlap]
+ else:
+ import types
+
+ return tp is Union or tp is types.UnionType # type: ignore[comparison-overlap]
+
+
+def is_typeddict(tp: Type[Any]) -> bool:
+ return typing_extensions.is_typeddict(tp)
+
+
+def is_literal_type(tp: Type[Any]) -> bool:
+ return get_origin(tp) in _LITERAL_TYPES
+
+
+def parse_date(value: Union[date, StrBytesIntFloat]) -> date:
+ return _parse_date(value)
+
+
+def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime:
+ return _parse_datetime(value)
diff --git a/src/_utils/_datetime_parse.py b/src/_utils/_datetime_parse.py
new file mode 100644
index 0000000..7cb9d9e
--- /dev/null
+++ b/src/_utils/_datetime_parse.py
@@ -0,0 +1,136 @@
+"""
+This file contains code from https://github.com/pydantic/pydantic/blob/main/pydantic/v1/datetime_parse.py
+without the Pydantic v1 specific errors.
+"""
+
+from __future__ import annotations
+
+import re
+from typing import Dict, Union, Optional
+from datetime import date, datetime, timezone, timedelta
+
+from .._types import StrBytesIntFloat
+
+date_expr = r"(?P\d{4})-(?P\d{1,2})-(?P\d{1,2})"
+time_expr = (
+ r"(?P\d{1,2}):(?P\d{1,2})"
+ r"(?::(?P\d{1,2})(?:\.(?P\d{1,6})\d{0,6})?)?"
+ r"(?PZ|[+-]\d{2}(?::?\d{2})?)?$"
+)
+
+date_re = re.compile(f"{date_expr}$")
+datetime_re = re.compile(f"{date_expr}[T ]{time_expr}")
+
+
+EPOCH = datetime(1970, 1, 1)
+# if greater than this, the number is in ms, if less than or equal it's in seconds
+# (in seconds this is 11th October 2603, in ms it's 20th August 1970)
+MS_WATERSHED = int(2e10)
+# slightly more than datetime.max in ns - (datetime.max - EPOCH).total_seconds() * 1e9
+MAX_NUMBER = int(3e20)
+
+
+def _get_numeric(value: StrBytesIntFloat, native_expected_type: str) -> Union[None, int, float]:
+ if isinstance(value, (int, float)):
+ return value
+ try:
+ return float(value)
+ except ValueError:
+ return None
+ except TypeError:
+ raise TypeError(f"invalid type; expected {native_expected_type}, string, bytes, int or float") from None
+
+
+def _from_unix_seconds(seconds: Union[int, float]) -> datetime:
+ if seconds > MAX_NUMBER:
+ return datetime.max
+ elif seconds < -MAX_NUMBER:
+ return datetime.min
+
+ while abs(seconds) > MS_WATERSHED:
+ seconds /= 1000
+ dt = EPOCH + timedelta(seconds=seconds)
+ return dt.replace(tzinfo=timezone.utc)
+
+
+def _parse_timezone(value: Optional[str]) -> Union[None, int, timezone]:
+ if value == "Z":
+ return timezone.utc
+ elif value is not None:
+ offset_mins = int(value[-2:]) if len(value) > 3 else 0
+ offset = 60 * int(value[1:3]) + offset_mins
+ if value[0] == "-":
+ offset = -offset
+ return timezone(timedelta(minutes=offset))
+ else:
+ return None
+
+
+def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime:
+ """
+ Parse a datetime/int/float/string and return a datetime.datetime.
+
+ This function supports time zone offsets. When the input contains one,
+ the output uses a timezone with a fixed offset from UTC.
+
+ Raise ValueError if the input is well formatted but not a valid datetime.
+ Raise ValueError if the input isn't well formatted.
+ """
+ if isinstance(value, datetime):
+ return value
+
+ number = _get_numeric(value, "datetime")
+ if number is not None:
+ return _from_unix_seconds(number)
+
+ if isinstance(value, bytes):
+ value = value.decode()
+
+ assert not isinstance(value, (float, int))
+
+ match = datetime_re.match(value)
+ if match is None:
+ raise ValueError("invalid datetime format")
+
+ kw = match.groupdict()
+ if kw["microsecond"]:
+ kw["microsecond"] = kw["microsecond"].ljust(6, "0")
+
+ tzinfo = _parse_timezone(kw.pop("tzinfo"))
+ kw_: Dict[str, Union[None, int, timezone]] = {k: int(v) for k, v in kw.items() if v is not None}
+ kw_["tzinfo"] = tzinfo
+
+ return datetime(**kw_) # type: ignore
+
+
+def parse_date(value: Union[date, StrBytesIntFloat]) -> date:
+ """
+ Parse a date/int/float/string and return a datetime.date.
+
+ Raise ValueError if the input is well formatted but not a valid date.
+ Raise ValueError if the input isn't well formatted.
+ """
+ if isinstance(value, date):
+ if isinstance(value, datetime):
+ return value.date()
+ else:
+ return value
+
+ number = _get_numeric(value, "date")
+ if number is not None:
+ return _from_unix_seconds(number).date()
+
+ if isinstance(value, bytes):
+ value = value.decode()
+
+ assert not isinstance(value, (float, int))
+ match = date_re.match(value)
+ if match is None:
+ raise ValueError("invalid date format")
+
+ kw = {k: int(v) for k, v in match.groupdict().items()}
+
+ try:
+ return date(**kw)
+ except ValueError:
+ raise ValueError("invalid date format") from None
diff --git a/src/_utils/_json.py b/src/_utils/_json.py
new file mode 100644
index 0000000..6058421
--- /dev/null
+++ b/src/_utils/_json.py
@@ -0,0 +1,35 @@
+import json
+from typing import Any
+from datetime import datetime
+from typing_extensions import override
+
+import pydantic
+
+from .._compat import model_dump
+
+
+def openapi_dumps(obj: Any) -> bytes:
+ """
+ Serialize an object to UTF-8 encoded JSON bytes.
+
+ Extends the standard json.dumps with support for additional types
+ commonly used in the SDK, such as `datetime`, `pydantic.BaseModel`, etc.
+ """
+ return json.dumps(
+ obj,
+ cls=_CustomEncoder,
+ # Uses the same defaults as httpx's JSON serialization
+ ensure_ascii=False,
+ separators=(",", ":"),
+ allow_nan=False,
+ ).encode()
+
+
+class _CustomEncoder(json.JSONEncoder):
+ @override
+ def default(self, o: Any) -> Any:
+ if isinstance(o, datetime):
+ return o.isoformat()
+ if isinstance(o, pydantic.BaseModel):
+ return model_dump(o, exclude_unset=True, mode="json", by_alias=True)
+ return super().default(o)
diff --git a/src/_utils/_logs.py b/src/_utils/_logs.py
new file mode 100644
index 0000000..bad6b59
--- /dev/null
+++ b/src/_utils/_logs.py
@@ -0,0 +1,25 @@
+import os
+import logging
+
+logger: logging.Logger = logging.getLogger("scalar_api")
+httpx_logger: logging.Logger = logging.getLogger("httpx")
+
+
+def _basic_config() -> None:
+ # e.g. [2023-10-05 14:12:26 - scalar_api._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK"
+ logging.basicConfig(
+ format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s",
+ datefmt="%Y-%m-%d %H:%M:%S",
+ )
+
+
+def setup_logging() -> None:
+ env = os.environ.get("SCALAR_LOG")
+ if env == "debug":
+ _basic_config()
+ logger.setLevel(logging.DEBUG)
+ httpx_logger.setLevel(logging.DEBUG)
+ elif env == "info":
+ _basic_config()
+ logger.setLevel(logging.INFO)
+ httpx_logger.setLevel(logging.INFO)
diff --git a/src/_utils/_path.py b/src/_utils/_path.py
new file mode 100644
index 0000000..4d6e1e4
--- /dev/null
+++ b/src/_utils/_path.py
@@ -0,0 +1,127 @@
+from __future__ import annotations
+
+import re
+from typing import (
+ Any,
+ Mapping,
+ Callable,
+)
+from urllib.parse import quote
+
+# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
+_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
+
+_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
+
+
+def _quote_path_segment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI path segment.
+
+ Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
+ """
+ # quote() already treats unreserved characters (letters, digits, and -._~)
+ # as safe, so we only need to add sub-delims, ':', and '@'.
+ # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
+ return quote(value, safe="!$&'()*+,;=:@")
+
+
+def _quote_query_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI query string.
+
+ Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
+ """
+ return quote(value, safe="!$'()*+,;:@/?")
+
+
+def _quote_fragment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI fragment.
+
+ Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
+ """
+ return quote(value, safe="!$&'()*+,;=:@/?")
+
+
+def _interpolate(
+ template: str,
+ values: Mapping[str, Any],
+ quoter: Callable[[str], str],
+) -> str:
+ """Replace {name} placeholders in `template`, quoting each value with `quoter`.
+
+ Placeholder names are looked up in `values`.
+
+ Raises:
+ KeyError: If a placeholder is not found in `values`.
+ """
+ # re.split with a capturing group returns alternating
+ # [text, name, text, name, ..., text] elements.
+ parts = _PLACEHOLDER_RE.split(template)
+
+ for i in range(1, len(parts), 2):
+ name = parts[i]
+ if name not in values:
+ raise KeyError(f"a value for placeholder {{{name}}} was not provided")
+ val = values[name]
+ if val is None:
+ parts[i] = "null"
+ elif isinstance(val, bool):
+ parts[i] = "true" if val else "false"
+ else:
+ parts[i] = quoter(str(values[name]))
+
+ return "".join(parts)
+
+
+def path_template(template: str, /, **kwargs: Any) -> str:
+ """Interpolate {name} placeholders in `template` from keyword arguments.
+
+ Args:
+ template: The template string containing {name} placeholders.
+ **kwargs: Keyword arguments to interpolate into the template.
+
+ Returns:
+ The template with placeholders interpolated and percent-encoded.
+
+ Safe characters for percent-encoding are dependent on the URI component.
+ Placeholders in path and fragment portions are percent-encoded where the `segment`
+ and `fragment` sets from RFC 3986 respectively are considered safe.
+ Placeholders in the query portion are percent-encoded where the `query` set from
+ RFC 3986 §3.3 is considered safe except for = and & characters.
+
+ Raises:
+ KeyError: If a placeholder is not found in `kwargs`.
+ ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
+ """
+ # Split the template into path, query, and fragment portions.
+ fragment_template: str | None = None
+ query_template: str | None = None
+
+ rest = template
+ if "#" in rest:
+ rest, fragment_template = rest.split("#", 1)
+ if "?" in rest:
+ rest, query_template = rest.split("?", 1)
+ path_template = rest
+
+ # Interpolate each portion with the appropriate quoting rules.
+ path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
+
+ # Reject dot-segments (. and ..) in the final assembled path. The check
+ # runs after interpolation so that adjacent placeholders or a mix of static
+ # text and placeholders that together form a dot-segment are caught.
+ # Also reject percent-encoded dot-segments to protect against incorrectly
+ # implemented normalization in servers/proxies.
+ for segment in path_result.split("/"):
+ if _DOT_SEGMENT_RE.match(segment):
+ raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
+
+ result = path_result
+ if query_template is not None:
+ result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
+ if fragment_template is not None:
+ result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
+
+ return result
diff --git a/src/_utils/_proxy.py b/src/_utils/_proxy.py
new file mode 100644
index 0000000..0f239a3
--- /dev/null
+++ b/src/_utils/_proxy.py
@@ -0,0 +1,65 @@
+from __future__ import annotations
+
+from abc import ABC, abstractmethod
+from typing import Generic, TypeVar, Iterable, cast
+from typing_extensions import override
+
+T = TypeVar("T")
+
+
+class LazyProxy(Generic[T], ABC):
+ """Implements data methods to pretend that an instance is another instance.
+
+ This includes forwarding attribute access and other methods.
+ """
+
+ # Note: we have to special case proxies that themselves return proxies
+ # to support using a proxy as a catch-all for any random access, e.g. `proxy.foo.bar.baz`
+
+ def __getattr__(self, attr: str) -> object:
+ proxied = self.__get_proxied__()
+ if isinstance(proxied, LazyProxy):
+ return proxied # pyright: ignore
+ return getattr(proxied, attr)
+
+ @override
+ def __repr__(self) -> str:
+ proxied = self.__get_proxied__()
+ if isinstance(proxied, LazyProxy):
+ return proxied.__class__.__name__
+ return repr(self.__get_proxied__())
+
+ @override
+ def __str__(self) -> str:
+ proxied = self.__get_proxied__()
+ if isinstance(proxied, LazyProxy):
+ return proxied.__class__.__name__
+ return str(proxied)
+
+ @override
+ def __dir__(self) -> Iterable[str]:
+ proxied = self.__get_proxied__()
+ if isinstance(proxied, LazyProxy):
+ return []
+ return proxied.__dir__()
+
+ @property # type: ignore
+ @override
+ def __class__(self) -> type: # pyright: ignore
+ try:
+ proxied = self.__get_proxied__()
+ except Exception:
+ return type(self)
+ if issubclass(type(proxied), LazyProxy):
+ return type(proxied)
+ return proxied.__class__
+
+ def __get_proxied__(self) -> T:
+ return self.__load__()
+
+ def __as_proxied__(self) -> T:
+ """Helper method that returns the current proxy, typed as the loaded object"""
+ return cast(T, self)
+
+ @abstractmethod
+ def __load__(self) -> T: ...
diff --git a/src/_utils/_reflection.py b/src/_utils/_reflection.py
new file mode 100644
index 0000000..89aa712
--- /dev/null
+++ b/src/_utils/_reflection.py
@@ -0,0 +1,42 @@
+from __future__ import annotations
+
+import inspect
+from typing import Any, Callable
+
+
+def function_has_argument(func: Callable[..., Any], arg_name: str) -> bool:
+ """Returns whether or not the given function has a specific parameter"""
+ sig = inspect.signature(func)
+ return arg_name in sig.parameters
+
+
+def assert_signatures_in_sync(
+ source_func: Callable[..., Any],
+ check_func: Callable[..., Any],
+ *,
+ exclude_params: set[str] = set(),
+) -> None:
+ """Ensure that the signature of the second function matches the first."""
+
+ check_sig = inspect.signature(check_func)
+ source_sig = inspect.signature(source_func)
+
+ errors: list[str] = []
+
+ for name, source_param in source_sig.parameters.items():
+ if name in exclude_params:
+ continue
+
+ custom_param = check_sig.parameters.get(name)
+ if not custom_param:
+ errors.append(f"the `{name}` param is missing")
+ continue
+
+ if custom_param.annotation != source_param.annotation:
+ errors.append(
+ f"types for the `{name}` param are do not match; source={repr(source_param.annotation)} checking={repr(custom_param.annotation)}"
+ )
+ continue
+
+ if errors:
+ raise AssertionError(f"{len(errors)} errors encountered when comparing signatures:\n\n" + "\n\n".join(errors))
diff --git a/src/_utils/_resources_proxy.py b/src/_utils/_resources_proxy.py
new file mode 100644
index 0000000..6d86fbe
--- /dev/null
+++ b/src/_utils/_resources_proxy.py
@@ -0,0 +1,24 @@
+from __future__ import annotations
+
+from typing import Any
+from typing_extensions import override
+
+from ._proxy import LazyProxy
+
+
+class ResourcesProxy(LazyProxy[Any]):
+ """A proxy for the `scalar_api.resources` module.
+
+ This is used so that we can lazily import `scalar_api.resources` only when
+ needed *and* so that users can just import `scalar_api` and reference `scalar_api.resources`
+ """
+
+ @override
+ def __load__(self) -> Any:
+ import importlib
+
+ mod = importlib.import_module("scalar_api.resources")
+ return mod
+
+
+resources = ResourcesProxy().__as_proxied__()
diff --git a/src/_utils/_streams.py b/src/_utils/_streams.py
new file mode 100644
index 0000000..f4a0208
--- /dev/null
+++ b/src/_utils/_streams.py
@@ -0,0 +1,12 @@
+from typing import Any
+from typing_extensions import Iterator, AsyncIterator
+
+
+def consume_sync_iterator(iterator: Iterator[Any]) -> None:
+ for _ in iterator:
+ ...
+
+
+async def consume_async_iterator(iterator: AsyncIterator[Any]) -> None:
+ async for _ in iterator:
+ ...
diff --git a/src/_utils/_sync.py b/src/_utils/_sync.py
new file mode 100644
index 0000000..f6027c1
--- /dev/null
+++ b/src/_utils/_sync.py
@@ -0,0 +1,58 @@
+from __future__ import annotations
+
+import asyncio
+import functools
+from typing import TypeVar, Callable, Awaitable
+from typing_extensions import ParamSpec
+
+import anyio
+import sniffio
+import anyio.to_thread
+
+T_Retval = TypeVar("T_Retval")
+T_ParamSpec = ParamSpec("T_ParamSpec")
+
+
+async def to_thread(
+ func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
+) -> T_Retval:
+ if sniffio.current_async_library() == "asyncio":
+ return await asyncio.to_thread(func, *args, **kwargs)
+
+ return await anyio.to_thread.run_sync(
+ functools.partial(func, *args, **kwargs),
+ )
+
+
+# inspired by `asyncer`, https://github.com/tiangolo/asyncer
+def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]:
+ """
+ Take a blocking function and create an async one that receives the same
+ positional and keyword arguments.
+
+ Usage:
+
+ ```python
+ def blocking_func(arg1, arg2, kwarg1=None):
+ # blocking code
+ return result
+
+
+ result = asyncify(blocking_function)(arg1, arg2, kwarg1=value1)
+ ```
+
+ ## Arguments
+
+ `function`: a blocking regular callable (e.g. a function)
+
+ ## Return
+
+ An async function that takes the same positional and keyword arguments as the
+ original one, that when called runs the same original function in a thread worker
+ and returns the result.
+ """
+
+ async def wrapper(*args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs) -> T_Retval:
+ return await to_thread(function, *args, **kwargs)
+
+ return wrapper
diff --git a/src/_utils/_transform.py b/src/_utils/_transform.py
new file mode 100644
index 0000000..5207549
--- /dev/null
+++ b/src/_utils/_transform.py
@@ -0,0 +1,457 @@
+from __future__ import annotations
+
+import io
+import base64
+import pathlib
+from typing import Any, Mapping, TypeVar, cast
+from datetime import date, datetime
+from typing_extensions import Literal, get_args, override, get_type_hints as _get_type_hints
+
+import anyio
+import pydantic
+
+from ._utils import (
+ is_list,
+ is_given,
+ lru_cache,
+ is_mapping,
+ is_iterable,
+ is_sequence,
+)
+from .._files import is_base64_file_input
+from ._compat import get_origin, is_typeddict
+from ._typing import (
+ is_list_type,
+ is_union_type,
+ extract_type_arg,
+ is_iterable_type,
+ is_required_type,
+ is_sequence_type,
+ is_annotated_type,
+ strip_annotated_type,
+)
+
+_T = TypeVar("_T")
+
+
+# TODO: support for drilling globals() and locals()
+# TODO: ensure works correctly with forward references in all cases
+
+
+PropertyFormat = Literal["iso8601", "base64", "custom"]
+
+
+class PropertyInfo:
+ """Metadata class to be used in Annotated types to provide information about a given type.
+
+ For example:
+
+ class MyParams(TypedDict):
+ account_holder_name: Annotated[str, PropertyInfo(alias='accountHolderName')]
+
+ This means that {'account_holder_name': 'Robert'} will be transformed to {'accountHolderName': 'Robert'} before being sent to the API.
+ """
+
+ alias: str | None
+ format: PropertyFormat | None
+ format_template: str | None
+ discriminator: str | None
+
+ def __init__(
+ self,
+ *,
+ alias: str | None = None,
+ format: PropertyFormat | None = None,
+ format_template: str | None = None,
+ discriminator: str | None = None,
+ ) -> None:
+ self.alias = alias
+ self.format = format
+ self.format_template = format_template
+ self.discriminator = discriminator
+
+ @override
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(alias='{self.alias}', format={self.format}, format_template='{self.format_template}', discriminator='{self.discriminator}')"
+
+
+def maybe_transform(
+ data: object,
+ expected_type: object,
+) -> Any | None:
+ """Wrapper over `transform()` that allows `None` to be passed.
+
+ See `transform()` for more details.
+ """
+ if data is None:
+ return None
+ return transform(data, expected_type)
+
+
+# Wrapper over _transform_recursive providing fake types
+def transform(
+ data: _T,
+ expected_type: object,
+) -> _T:
+ """Transform dictionaries based off of type information from the given type, for example:
+
+ ```py
+ class Params(TypedDict, total=False):
+ card_id: Required[Annotated[str, PropertyInfo(alias="cardID")]]
+
+
+ transformed = transform({"card_id": ""}, Params)
+ # {'cardID': ''}
+ ```
+
+ Any keys / data that does not have type information given will be included as is.
+
+ It should be noted that the transformations that this function does are not represented in the type system.
+ """
+ transformed = _transform_recursive(data, annotation=cast(type, expected_type))
+ return cast(_T, transformed)
+
+
+@lru_cache(maxsize=8096)
+def _get_annotated_type(type_: type) -> type | None:
+ """If the given type is an `Annotated` type then it is returned, if not `None` is returned.
+
+ This also unwraps the type when applicable, e.g. `Required[Annotated[T, ...]]`
+ """
+ if is_required_type(type_):
+ # Unwrap `Required[Annotated[T, ...]]` to `Annotated[T, ...]`
+ type_ = get_args(type_)[0]
+
+ if is_annotated_type(type_):
+ return type_
+
+ return None
+
+
+def _maybe_transform_key(key: str, type_: type) -> str:
+ """Transform the given `data` based on the annotations provided in `type_`.
+
+ Note: this function only looks at `Annotated` types that contain `PropertyInfo` metadata.
+ """
+ annotated_type = _get_annotated_type(type_)
+ if annotated_type is None:
+ # no `Annotated` definition for this type, no transformation needed
+ return key
+
+ # ignore the first argument as it is the actual type
+ annotations = get_args(annotated_type)[1:]
+ for annotation in annotations:
+ if isinstance(annotation, PropertyInfo) and annotation.alias is not None:
+ return annotation.alias
+
+ return key
+
+
+def _no_transform_needed(annotation: type) -> bool:
+ return annotation == float or annotation == int
+
+
+def _transform_recursive(
+ data: object,
+ *,
+ annotation: type,
+ inner_type: type | None = None,
+) -> object:
+ """Transform the given data against the expected type.
+
+ Args:
+ annotation: The direct type annotation given to the particular piece of data.
+ This may or may not be wrapped in metadata types, e.g. `Required[T]`, `Annotated[T, ...]` etc
+
+ inner_type: If applicable, this is the "inside" type. This is useful in certain cases where the outside type
+ is a container type such as `List[T]`. In that case `inner_type` should be set to `T` so that each entry in
+ the list can be transformed using the metadata from the container type.
+
+ Defaults to the same value as the `annotation` argument.
+ """
+ from .._compat import model_dump
+
+ if inner_type is None:
+ inner_type = annotation
+
+ stripped_type = strip_annotated_type(inner_type)
+ origin = get_origin(stripped_type) or stripped_type
+ if is_typeddict(stripped_type) and is_mapping(data):
+ return _transform_typeddict(data, stripped_type)
+
+ if origin == dict and is_mapping(data):
+ items_type = get_args(stripped_type)[1]
+ return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()}
+
+ if (
+ # List[T]
+ (is_list_type(stripped_type) and is_list(data))
+ # Iterable[T]
+ or (is_iterable_type(stripped_type) and is_iterable(data) and not isinstance(data, str))
+ # Sequence[T]
+ or (is_sequence_type(stripped_type) and is_sequence(data) and not isinstance(data, str))
+ ):
+ # dicts are technically iterable, but it is an iterable on the keys of the dict and is not usually
+ # intended as an iterable, so we don't transform it.
+ if isinstance(data, dict):
+ return cast(object, data)
+
+ inner_type = extract_type_arg(stripped_type, 0)
+ if _no_transform_needed(inner_type):
+ # for some types there is no need to transform anything, so we can get a small
+ # perf boost from skipping that work.
+ #
+ # but we still need to convert to a list to ensure the data is json-serializable
+ if is_list(data):
+ return data
+ return list(data)
+
+ return [_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
+
+ if is_union_type(stripped_type):
+ # For union types we run the transformation against all subtypes to ensure that everything is transformed.
+ #
+ # TODO: there may be edge cases where the same normalized field name will transform to two different names
+ # in different subtypes.
+ for subtype in get_args(stripped_type):
+ data = _transform_recursive(data, annotation=annotation, inner_type=subtype)
+ return data
+
+ if isinstance(data, pydantic.BaseModel):
+ return model_dump(data, exclude_unset=True, mode="json")
+
+ annotated_type = _get_annotated_type(annotation)
+ if annotated_type is None:
+ return data
+
+ # ignore the first argument as it is the actual type
+ annotations = get_args(annotated_type)[1:]
+ for annotation in annotations:
+ if isinstance(annotation, PropertyInfo) and annotation.format is not None:
+ return _format_data(data, annotation.format, annotation.format_template)
+
+ return data
+
+
+def _format_data(data: object, format_: PropertyFormat, format_template: str | None) -> object:
+ if isinstance(data, (date, datetime)):
+ if format_ == "iso8601":
+ return data.isoformat()
+
+ if format_ == "custom" and format_template is not None:
+ return data.strftime(format_template)
+
+ if format_ == "base64" and is_base64_file_input(data):
+ binary: str | bytes | None = None
+
+ if isinstance(data, pathlib.Path):
+ binary = data.read_bytes()
+ elif isinstance(data, io.IOBase):
+ binary = data.read()
+
+ if isinstance(binary, str): # type: ignore[unreachable]
+ binary = binary.encode()
+
+ if not isinstance(binary, bytes):
+ raise RuntimeError(f"Could not read bytes from {data}; Received {type(binary)}")
+
+ return base64.b64encode(binary).decode("ascii")
+
+ return data
+
+
+def _transform_typeddict(
+ data: Mapping[str, object],
+ expected_type: type,
+) -> Mapping[str, object]:
+ result: dict[str, object] = {}
+ annotations = get_type_hints(expected_type, include_extras=True)
+ for key, value in data.items():
+ if not is_given(value):
+ # we don't need to include omitted values here as they'll
+ # be stripped out before the request is sent anyway
+ continue
+
+ type_ = annotations.get(key)
+ if type_ is None:
+ # we do not have a type annotation for this field, leave it as is
+ result[key] = value
+ else:
+ result[_maybe_transform_key(key, type_)] = _transform_recursive(value, annotation=type_)
+ return result
+
+
+async def async_maybe_transform(
+ data: object,
+ expected_type: object,
+) -> Any | None:
+ """Wrapper over `async_transform()` that allows `None` to be passed.
+
+ See `async_transform()` for more details.
+ """
+ if data is None:
+ return None
+ return await async_transform(data, expected_type)
+
+
+async def async_transform(
+ data: _T,
+ expected_type: object,
+) -> _T:
+ """Transform dictionaries based off of type information from the given type, for example:
+
+ ```py
+ class Params(TypedDict, total=False):
+ card_id: Required[Annotated[str, PropertyInfo(alias="cardID")]]
+
+
+ transformed = transform({"card_id": ""}, Params)
+ # {'cardID': ''}
+ ```
+
+ Any keys / data that does not have type information given will be included as is.
+
+ It should be noted that the transformations that this function does are not represented in the type system.
+ """
+ transformed = await _async_transform_recursive(data, annotation=cast(type, expected_type))
+ return cast(_T, transformed)
+
+
+async def _async_transform_recursive(
+ data: object,
+ *,
+ annotation: type,
+ inner_type: type | None = None,
+) -> object:
+ """Transform the given data against the expected type.
+
+ Args:
+ annotation: The direct type annotation given to the particular piece of data.
+ This may or may not be wrapped in metadata types, e.g. `Required[T]`, `Annotated[T, ...]` etc
+
+ inner_type: If applicable, this is the "inside" type. This is useful in certain cases where the outside type
+ is a container type such as `List[T]`. In that case `inner_type` should be set to `T` so that each entry in
+ the list can be transformed using the metadata from the container type.
+
+ Defaults to the same value as the `annotation` argument.
+ """
+ from .._compat import model_dump
+
+ if inner_type is None:
+ inner_type = annotation
+
+ stripped_type = strip_annotated_type(inner_type)
+ origin = get_origin(stripped_type) or stripped_type
+ if is_typeddict(stripped_type) and is_mapping(data):
+ return await _async_transform_typeddict(data, stripped_type)
+
+ if origin == dict and is_mapping(data):
+ items_type = get_args(stripped_type)[1]
+ return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()}
+
+ if (
+ # List[T]
+ (is_list_type(stripped_type) and is_list(data))
+ # Iterable[T]
+ or (is_iterable_type(stripped_type) and is_iterable(data) and not isinstance(data, str))
+ # Sequence[T]
+ or (is_sequence_type(stripped_type) and is_sequence(data) and not isinstance(data, str))
+ ):
+ # dicts are technically iterable, but it is an iterable on the keys of the dict and is not usually
+ # intended as an iterable, so we don't transform it.
+ if isinstance(data, dict):
+ return cast(object, data)
+
+ inner_type = extract_type_arg(stripped_type, 0)
+ if _no_transform_needed(inner_type):
+ # for some types there is no need to transform anything, so we can get a small
+ # perf boost from skipping that work.
+ #
+ # but we still need to convert to a list to ensure the data is json-serializable
+ if is_list(data):
+ return data
+ return list(data)
+
+ return [await _async_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
+
+ if is_union_type(stripped_type):
+ # For union types we run the transformation against all subtypes to ensure that everything is transformed.
+ #
+ # TODO: there may be edge cases where the same normalized field name will transform to two different names
+ # in different subtypes.
+ for subtype in get_args(stripped_type):
+ data = await _async_transform_recursive(data, annotation=annotation, inner_type=subtype)
+ return data
+
+ if isinstance(data, pydantic.BaseModel):
+ return model_dump(data, exclude_unset=True, mode="json")
+
+ annotated_type = _get_annotated_type(annotation)
+ if annotated_type is None:
+ return data
+
+ # ignore the first argument as it is the actual type
+ annotations = get_args(annotated_type)[1:]
+ for annotation in annotations:
+ if isinstance(annotation, PropertyInfo) and annotation.format is not None:
+ return await _async_format_data(data, annotation.format, annotation.format_template)
+
+ return data
+
+
+async def _async_format_data(data: object, format_: PropertyFormat, format_template: str | None) -> object:
+ if isinstance(data, (date, datetime)):
+ if format_ == "iso8601":
+ return data.isoformat()
+
+ if format_ == "custom" and format_template is not None:
+ return data.strftime(format_template)
+
+ if format_ == "base64" and is_base64_file_input(data):
+ binary: str | bytes | None = None
+
+ if isinstance(data, pathlib.Path):
+ binary = await anyio.Path(data).read_bytes()
+ elif isinstance(data, io.IOBase):
+ binary = data.read()
+
+ if isinstance(binary, str): # type: ignore[unreachable]
+ binary = binary.encode()
+
+ if not isinstance(binary, bytes):
+ raise RuntimeError(f"Could not read bytes from {data}; Received {type(binary)}")
+
+ return base64.b64encode(binary).decode("ascii")
+
+ return data
+
+
+async def _async_transform_typeddict(
+ data: Mapping[str, object],
+ expected_type: type,
+) -> Mapping[str, object]:
+ result: dict[str, object] = {}
+ annotations = get_type_hints(expected_type, include_extras=True)
+ for key, value in data.items():
+ if not is_given(value):
+ # we don't need to include omitted values here as they'll
+ # be stripped out before the request is sent anyway
+ continue
+
+ type_ = annotations.get(key)
+ if type_ is None:
+ # we do not have a type annotation for this field, leave it as is
+ result[key] = value
+ else:
+ result[_maybe_transform_key(key, type_)] = await _async_transform_recursive(value, annotation=type_)
+ return result
+
+
+@lru_cache(maxsize=8096)
+def get_type_hints(
+ obj: Any,
+ globalns: dict[str, Any] | None = None,
+ localns: Mapping[str, Any] | None = None,
+ include_extras: bool = False,
+) -> dict[str, Any]:
+ return _get_type_hints(obj, globalns=globalns, localns=localns, include_extras=include_extras)
diff --git a/src/_utils/_typing.py b/src/_utils/_typing.py
new file mode 100644
index 0000000..193109f
--- /dev/null
+++ b/src/_utils/_typing.py
@@ -0,0 +1,156 @@
+from __future__ import annotations
+
+import sys
+import typing
+import typing_extensions
+from typing import Any, TypeVar, Iterable, cast
+from collections import abc as _c_abc
+from typing_extensions import (
+ TypeIs,
+ Required,
+ Annotated,
+ get_args,
+ get_origin,
+)
+
+from ._utils import lru_cache
+from .._types import InheritsGeneric
+from ._compat import is_union as _is_union
+
+
+def is_annotated_type(typ: type) -> bool:
+ return get_origin(typ) == Annotated
+
+
+def is_list_type(typ: type) -> bool:
+ return (get_origin(typ) or typ) == list
+
+
+def is_sequence_type(typ: type) -> bool:
+ origin = get_origin(typ) or typ
+ return origin == typing_extensions.Sequence or origin == typing.Sequence or origin == _c_abc.Sequence
+
+
+def is_iterable_type(typ: type) -> bool:
+ """If the given type is `typing.Iterable[T]`"""
+ origin = get_origin(typ) or typ
+ return origin == Iterable or origin == _c_abc.Iterable
+
+
+def is_union_type(typ: type) -> bool:
+ return _is_union(get_origin(typ))
+
+
+def is_required_type(typ: type) -> bool:
+ return get_origin(typ) == Required
+
+
+def is_typevar(typ: type) -> bool:
+ # type ignore is required because type checkers
+ # think this expression will always return False
+ return type(typ) == TypeVar # type: ignore
+
+
+_TYPE_ALIAS_TYPES: tuple[type[typing_extensions.TypeAliasType], ...] = (typing_extensions.TypeAliasType,)
+if sys.version_info >= (3, 12):
+ _TYPE_ALIAS_TYPES = (*_TYPE_ALIAS_TYPES, typing.TypeAliasType)
+
+
+def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]:
+ """Return whether the provided argument is an instance of `TypeAliasType`.
+
+ ```python
+ type Int = int
+ is_type_alias_type(Int)
+ # > True
+ Str = TypeAliasType("Str", str)
+ is_type_alias_type(Str)
+ # > True
+ ```
+ """
+ return isinstance(tp, _TYPE_ALIAS_TYPES)
+
+
+# Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]]
+@lru_cache(maxsize=8096)
+def strip_annotated_type(typ: type) -> type:
+ if is_required_type(typ) or is_annotated_type(typ):
+ return strip_annotated_type(cast(type, get_args(typ)[0]))
+
+ return typ
+
+
+def extract_type_arg(typ: type, index: int) -> type:
+ args = get_args(typ)
+ try:
+ return cast(type, args[index])
+ except IndexError as err:
+ raise RuntimeError(f"Expected type {typ} to have a type argument at index {index} but it did not") from err
+
+
+def extract_type_var_from_base(
+ typ: type,
+ *,
+ generic_bases: tuple[type, ...],
+ index: int,
+ failure_message: str | None = None,
+) -> type:
+ """Given a type like `Foo[T]`, returns the generic type variable `T`.
+
+ This also handles the case where a concrete subclass is given, e.g.
+ ```py
+ class MyResponse(Foo[bytes]):
+ ...
+
+ extract_type_var(MyResponse, bases=(Foo,), index=0) -> bytes
+ ```
+
+ And where a generic subclass is given:
+ ```py
+ _T = TypeVar('_T')
+ class MyResponse(Foo[_T]):
+ ...
+
+ extract_type_var(MyResponse[bytes], bases=(Foo,), index=0) -> bytes
+ ```
+ """
+ cls = cast(object, get_origin(typ) or typ)
+ if cls in generic_bases: # pyright: ignore[reportUnnecessaryContains]
+ # we're given the class directly
+ return extract_type_arg(typ, index)
+
+ # if a subclass is given
+ # ---
+ # this is needed as __orig_bases__ is not present in the typeshed stubs
+ # because it is intended to be for internal use only, however there does
+ # not seem to be a way to resolve generic TypeVars for inherited subclasses
+ # without using it.
+ if isinstance(cls, InheritsGeneric):
+ target_base_class: Any | None = None
+ for base in cls.__orig_bases__:
+ if base.__origin__ in generic_bases:
+ target_base_class = base
+ break
+
+ if target_base_class is None:
+ raise RuntimeError(
+ "Could not find the generic base class;\n"
+ "This should never happen;\n"
+ f"Does {cls} inherit from one of {generic_bases} ?"
+ )
+
+ extracted = extract_type_arg(target_base_class, index)
+ if is_typevar(extracted):
+ # If the extracted type argument is itself a type variable
+ # then that means the subclass itself is generic, so we have
+ # to resolve the type argument from the class itself, not
+ # the base class.
+ #
+ # Note: if there is more than 1 type argument, the subclass could
+ # change the ordering of the type arguments, this is not currently
+ # supported.
+ return extract_type_arg(typ, index)
+
+ return extracted
+
+ raise RuntimeError(failure_message or f"Could not resolve inner type variable at index {index} for {typ}")
diff --git a/src/_utils/_utils.py b/src/_utils/_utils.py
new file mode 100644
index 0000000..8b051e2
--- /dev/null
+++ b/src/_utils/_utils.py
@@ -0,0 +1,433 @@
+from __future__ import annotations
+
+import os
+import re
+import inspect
+import functools
+from typing import (
+ Any,
+ Tuple,
+ Mapping,
+ TypeVar,
+ Callable,
+ Iterable,
+ Sequence,
+ cast,
+ overload,
+)
+from pathlib import Path
+from datetime import date, datetime
+from typing_extensions import TypeGuard, get_args
+
+import sniffio
+
+from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike
+
+_T = TypeVar("_T")
+_TupleT = TypeVar("_TupleT", bound=Tuple[object, ...])
+_MappingT = TypeVar("_MappingT", bound=Mapping[str, object])
+_SequenceT = TypeVar("_SequenceT", bound=Sequence[object])
+CallableT = TypeVar("CallableT", bound=Callable[..., Any])
+
+
+def flatten(t: Iterable[Iterable[_T]]) -> list[_T]:
+ return [item for sublist in t for item in sublist]
+
+
+def extract_files(
+ # TODO: this needs to take Dict but variance issues.....
+ # create protocol type ?
+ query: Mapping[str, object],
+ *,
+ paths: Sequence[Sequence[str]],
+ array_format: ArrayFormat = "brackets",
+) -> list[tuple[str, FileTypes]]:
+ """Recursively extract files from the given dictionary based on specified paths.
+
+ A path may look like this ['foo', 'files', '', 'data'].
+
+ ``array_format`` controls how ```` segments contribute to the emitted
+ field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and
+ ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``).
+
+ Note: this mutates the given dictionary.
+ """
+ files: list[tuple[str, FileTypes]] = []
+ for path in paths:
+ files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format))
+ return files
+
+
+def _array_suffix(array_format: ArrayFormat, array_index: int) -> str:
+ if array_format == "brackets":
+ return "[]"
+ if array_format == "indices":
+ return f"[{array_index}]"
+ if array_format == "repeat" or array_format == "comma":
+ # Both repeat the bare field name for each file part; there is no
+ # meaningful way to comma-join binary parts.
+ return ""
+ raise NotImplementedError(
+ f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}"
+ )
+
+
+def _extract_items(
+ obj: object,
+ path: Sequence[str],
+ *,
+ index: int,
+ flattened_key: str | None,
+ array_format: ArrayFormat,
+) -> list[tuple[str, FileTypes]]:
+ try:
+ key = path[index]
+ except IndexError:
+ if not is_given(obj):
+ # no value was provided - we can safely ignore
+ return []
+
+ # cyclical import
+ from .._files import assert_is_file_content
+
+ # We have exhausted the path, return the entry we found.
+ assert flattened_key is not None
+
+ if is_list(obj):
+ files: list[tuple[str, FileTypes]] = []
+ for array_index, entry in enumerate(obj):
+ suffix = _array_suffix(array_format, array_index)
+ emitted_key = (flattened_key + suffix) if flattened_key else suffix
+ assert_is_file_content(entry, key=emitted_key)
+ files.append((emitted_key, cast(FileTypes, entry)))
+ return files
+
+ assert_is_file_content(obj, key=flattened_key)
+ return [(flattened_key, cast(FileTypes, obj))]
+
+ index += 1
+ if is_dict(obj):
+ try:
+ # Remove the field if there are no more dict keys in the path,
+ # only "" traversal markers or end.
+ if all(p == "" for p in path[index:]):
+ item = obj.pop(key)
+ else:
+ item = obj[key]
+ except KeyError:
+ # Key was not present in the dictionary, this is not indicative of an error
+ # as the given path may not point to a required field. We also do not want
+ # to enforce required fields as the API may differ from the spec in some cases.
+ return []
+ if flattened_key is None:
+ flattened_key = key
+ else:
+ flattened_key += f"[{key}]"
+ return _extract_items(
+ item,
+ path,
+ index=index,
+ flattened_key=flattened_key,
+ array_format=array_format,
+ )
+ elif is_list(obj):
+ if key != "":
+ return []
+
+ return flatten(
+ [
+ _extract_items(
+ item,
+ path,
+ index=index,
+ flattened_key=(
+ (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index)
+ ),
+ array_format=array_format,
+ )
+ for array_index, item in enumerate(obj)
+ ]
+ )
+
+ # Something unexpected was passed, just ignore it.
+ return []
+
+
+def is_given(obj: _T | NotGiven | Omit) -> TypeGuard[_T]:
+ return not isinstance(obj, NotGiven) and not isinstance(obj, Omit)
+
+
+# Type safe methods for narrowing types with TypeVars.
+# The default narrowing for isinstance(obj, dict) is dict[unknown, unknown],
+# however this cause Pyright to rightfully report errors. As we know we don't
+# care about the contained types we can safely use `object` in its place.
+#
+# There are two separate functions defined, `is_*` and `is_*_t` for different use cases.
+# `is_*` is for when you're dealing with an unknown input
+# `is_*_t` is for when you're narrowing a known union type to a specific subset
+
+
+def is_tuple(obj: object) -> TypeGuard[tuple[object, ...]]:
+ return isinstance(obj, tuple)
+
+
+def is_tuple_t(obj: _TupleT | object) -> TypeGuard[_TupleT]:
+ return isinstance(obj, tuple)
+
+
+def is_sequence(obj: object) -> TypeGuard[Sequence[object]]:
+ return isinstance(obj, Sequence)
+
+
+def is_sequence_t(obj: _SequenceT | object) -> TypeGuard[_SequenceT]:
+ return isinstance(obj, Sequence)
+
+
+def is_mapping(obj: object) -> TypeGuard[Mapping[str, object]]:
+ return isinstance(obj, Mapping)
+
+
+def is_mapping_t(obj: _MappingT | object) -> TypeGuard[_MappingT]:
+ return isinstance(obj, Mapping)
+
+
+def is_dict(obj: object) -> TypeGuard[dict[object, object]]:
+ return isinstance(obj, dict)
+
+
+def is_list(obj: object) -> TypeGuard[list[object]]:
+ return isinstance(obj, list)
+
+
+def is_iterable(obj: object) -> TypeGuard[Iterable[object]]:
+ return isinstance(obj, Iterable)
+
+
+# copied from https://github.com/Rapptz/RoboDanny
+def human_join(seq: Sequence[str], *, delim: str = ", ", final: str = "or") -> str:
+ size = len(seq)
+ if size == 0:
+ return ""
+
+ if size == 1:
+ return seq[0]
+
+ if size == 2:
+ return f"{seq[0]} {final} {seq[1]}"
+
+ return delim.join(seq[:-1]) + f" {final} {seq[-1]}"
+
+
+def quote(string: str) -> str:
+ """Add single quotation marks around the given string. Does *not* do any escaping."""
+ return f"'{string}'"
+
+
+def required_args(*variants: Sequence[str]) -> Callable[[CallableT], CallableT]:
+ """Decorator to enforce a given set of arguments or variants of arguments are passed to the decorated function.
+
+ Useful for enforcing runtime validation of overloaded functions.
+
+ Example usage:
+ ```py
+ @overload
+ def foo(*, a: str) -> str: ...
+
+
+ @overload
+ def foo(*, b: bool) -> str: ...
+
+
+ # This enforces the same constraints that a static type checker would
+ # i.e. that either a or b must be passed to the function
+ @required_args(["a"], ["b"])
+ def foo(*, a: str | None = None, b: bool | None = None) -> str: ...
+ ```
+ """
+
+ def inner(func: CallableT) -> CallableT:
+ params = inspect.signature(func).parameters
+ positional = [
+ name
+ for name, param in params.items()
+ if param.kind
+ in {
+ param.POSITIONAL_ONLY,
+ param.POSITIONAL_OR_KEYWORD,
+ }
+ ]
+
+ @functools.wraps(func)
+ def wrapper(*args: object, **kwargs: object) -> object:
+ given_params: set[str] = set()
+ for i, _ in enumerate(args):
+ try:
+ given_params.add(positional[i])
+ except IndexError:
+ raise TypeError(
+ f"{func.__name__}() takes {len(positional)} argument(s) but {len(args)} were given"
+ ) from None
+
+ for key in kwargs.keys():
+ given_params.add(key)
+
+ for variant in variants:
+ matches = all((param in given_params for param in variant))
+ if matches:
+ break
+ else: # no break
+ if len(variants) > 1:
+ variations = human_join(
+ ["(" + human_join([quote(arg) for arg in variant], final="and") + ")" for variant in variants]
+ )
+ msg = f"Missing required arguments; Expected either {variations} arguments to be given"
+ else:
+ assert len(variants) > 0
+
+ # TODO: this error message is not deterministic
+ missing = list(set(variants[0]) - given_params)
+ if len(missing) > 1:
+ msg = f"Missing required arguments: {human_join([quote(arg) for arg in missing])}"
+ else:
+ msg = f"Missing required argument: {quote(missing[0])}"
+ raise TypeError(msg)
+ return func(*args, **kwargs)
+
+ return wrapper # type: ignore
+
+ return inner
+
+
+_K = TypeVar("_K")
+_V = TypeVar("_V")
+
+
+@overload
+def strip_not_given(obj: None) -> None: ...
+
+
+@overload
+def strip_not_given(obj: Mapping[_K, _V | NotGiven]) -> dict[_K, _V]: ...
+
+
+@overload
+def strip_not_given(obj: object) -> object: ...
+
+
+def strip_not_given(obj: object | None) -> object:
+ """Remove all top-level keys where their values are instances of `NotGiven`"""
+ if obj is None:
+ return None
+
+ if not is_mapping(obj):
+ return obj
+
+ return {key: value for key, value in obj.items() if not isinstance(value, NotGiven)}
+
+
+def coerce_integer(val: str) -> int:
+ return int(val, base=10)
+
+
+def coerce_float(val: str) -> float:
+ return float(val)
+
+
+def coerce_boolean(val: str) -> bool:
+ return val == "true" or val == "1" or val == "on"
+
+
+def maybe_coerce_integer(val: str | None) -> int | None:
+ if val is None:
+ return None
+ return coerce_integer(val)
+
+
+def maybe_coerce_float(val: str | None) -> float | None:
+ if val is None:
+ return None
+ return coerce_float(val)
+
+
+def maybe_coerce_boolean(val: str | None) -> bool | None:
+ if val is None:
+ return None
+ return coerce_boolean(val)
+
+
+def removeprefix(string: str, prefix: str) -> str:
+ """Remove a prefix from a string.
+
+ Backport of `str.removeprefix` for Python < 3.9
+ """
+ if string.startswith(prefix):
+ return string[len(prefix) :]
+ return string
+
+
+def removesuffix(string: str, suffix: str) -> str:
+ """Remove a suffix from a string.
+
+ Backport of `str.removesuffix` for Python < 3.9
+ """
+ if string.endswith(suffix):
+ return string[: -len(suffix)]
+ return string
+
+
+def file_from_path(path: str) -> FileTypes:
+ contents = Path(path).read_bytes()
+ file_name = os.path.basename(path)
+ return (file_name, contents)
+
+
+def get_required_header(headers: HeadersLike, header: str) -> str:
+ lower_header = header.lower()
+ if is_mapping_t(headers):
+ # mypy doesn't understand the type narrowing here
+ for k, v in headers.items(): # type: ignore
+ if k.lower() == lower_header and isinstance(v, str):
+ return v
+
+ # to deal with the case where the header looks like Scalar-Event-Id
+ intercaps_header = re.sub(r"([^\w])(\w)", lambda pat: pat.group(1) + pat.group(2).upper(), header.capitalize())
+
+ for normalized_header in [header, lower_header, header.upper(), intercaps_header]:
+ value = headers.get(normalized_header)
+ if value:
+ return value
+
+ raise ValueError(f"Could not find {header} header")
+
+
+def get_async_library() -> str:
+ try:
+ return sniffio.current_async_library()
+ except Exception:
+ return "false"
+
+
+def lru_cache(*, maxsize: int | None = 128) -> Callable[[CallableT], CallableT]:
+ """A version of functools.lru_cache that retains the type signature
+ for the wrapped function arguments.
+ """
+ wrapper = functools.lru_cache( # noqa: TID251
+ maxsize=maxsize,
+ )
+ return cast(Any, wrapper) # type: ignore[no-any-return]
+
+
+def json_safe(data: object) -> object:
+ """Translates a mapping / sequence recursively in the same fashion
+ as `pydantic` v2's `model_dump(mode="json")`.
+ """
+ if is_mapping(data):
+ return {json_safe(key): json_safe(value) for key, value in data.items()}
+
+ if is_iterable(data) and not isinstance(data, (str, bytes, bytearray)):
+ return [json_safe(item) for item in data]
+
+ if isinstance(data, (datetime, date)):
+ return data.isoformat()
+
+ return data
diff --git a/src/_version.py b/src/_version.py
new file mode 100644
index 0000000..5e43458
--- /dev/null
+++ b/src/_version.py
@@ -0,0 +1,4 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+__title__ = "scalarApi"
+__version__ = "0.1.9"
diff --git a/src/py.typed b/src/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/src/resources/__init__.py b/src/resources/__init__.py
new file mode 100644
index 0000000..e5d8992
--- /dev/null
+++ b/src/resources/__init__.py
@@ -0,0 +1,131 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from .registry import (
+ RegistryResource,
+ AsyncRegistryResource,
+ RegistryResourceWithRawResponse,
+ AsyncRegistryResourceWithRawResponse,
+ RegistryResourceWithStreamingResponse,
+ AsyncRegistryResourceWithStreamingResponse,
+)
+from .schemas import (
+ SchemasResource,
+ AsyncSchemasResource,
+ SchemasResourceWithRawResponse,
+ AsyncSchemasResourceWithRawResponse,
+ SchemasResourceWithStreamingResponse,
+ AsyncSchemasResourceWithStreamingResponse,
+)
+from .login_portals import (
+ LoginPortalsResource,
+ AsyncLoginPortalsResource,
+ LoginPortalsResourceWithRawResponse,
+ AsyncLoginPortalsResourceWithRawResponse,
+ LoginPortalsResourceWithStreamingResponse,
+ AsyncLoginPortalsResourceWithStreamingResponse,
+)
+from .rules import (
+ RulesResource,
+ AsyncRulesResource,
+ RulesResourceWithRawResponse,
+ AsyncRulesResourceWithRawResponse,
+ RulesResourceWithStreamingResponse,
+ AsyncRulesResourceWithStreamingResponse,
+)
+from .themes import (
+ ThemesResource,
+ AsyncThemesResource,
+ ThemesResourceWithRawResponse,
+ AsyncThemesResourceWithRawResponse,
+ ThemesResourceWithStreamingResponse,
+ AsyncThemesResourceWithStreamingResponse,
+)
+from .teams import (
+ TeamsResource,
+ AsyncTeamsResource,
+ TeamsResourceWithRawResponse,
+ AsyncTeamsResourceWithRawResponse,
+ TeamsResourceWithStreamingResponse,
+ AsyncTeamsResourceWithStreamingResponse,
+)
+from .scalar_docs import (
+ ScalarDocsResource,
+ AsyncScalarDocsResource,
+ ScalarDocsResourceWithRawResponse,
+ AsyncScalarDocsResourceWithRawResponse,
+ ScalarDocsResourceWithStreamingResponse,
+ AsyncScalarDocsResourceWithStreamingResponse,
+)
+from .namespaces import (
+ NamespacesResource,
+ AsyncNamespacesResource,
+ NamespacesResourceWithRawResponse,
+ AsyncNamespacesResourceWithRawResponse,
+ NamespacesResourceWithStreamingResponse,
+ AsyncNamespacesResourceWithStreamingResponse,
+)
+from .authentication import (
+ AuthenticationResource,
+ AsyncAuthenticationResource,
+ AuthenticationResourceWithRawResponse,
+ AsyncAuthenticationResourceWithRawResponse,
+ AuthenticationResourceWithStreamingResponse,
+ AsyncAuthenticationResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "RegistryResource",
+ "AsyncRegistryResource",
+ "RegistryResourceWithRawResponse",
+ "AsyncRegistryResourceWithRawResponse",
+ "RegistryResourceWithStreamingResponse",
+ "AsyncRegistryResourceWithStreamingResponse",
+ "SchemasResource",
+ "AsyncSchemasResource",
+ "SchemasResourceWithRawResponse",
+ "AsyncSchemasResourceWithRawResponse",
+ "SchemasResourceWithStreamingResponse",
+ "AsyncSchemasResourceWithStreamingResponse",
+ "LoginPortalsResource",
+ "AsyncLoginPortalsResource",
+ "LoginPortalsResourceWithRawResponse",
+ "AsyncLoginPortalsResourceWithRawResponse",
+ "LoginPortalsResourceWithStreamingResponse",
+ "AsyncLoginPortalsResourceWithStreamingResponse",
+ "RulesResource",
+ "AsyncRulesResource",
+ "RulesResourceWithRawResponse",
+ "AsyncRulesResourceWithRawResponse",
+ "RulesResourceWithStreamingResponse",
+ "AsyncRulesResourceWithStreamingResponse",
+ "ThemesResource",
+ "AsyncThemesResource",
+ "ThemesResourceWithRawResponse",
+ "AsyncThemesResourceWithRawResponse",
+ "ThemesResourceWithStreamingResponse",
+ "AsyncThemesResourceWithStreamingResponse",
+ "TeamsResource",
+ "AsyncTeamsResource",
+ "TeamsResourceWithRawResponse",
+ "AsyncTeamsResourceWithRawResponse",
+ "TeamsResourceWithStreamingResponse",
+ "AsyncTeamsResourceWithStreamingResponse",
+ "ScalarDocsResource",
+ "AsyncScalarDocsResource",
+ "ScalarDocsResourceWithRawResponse",
+ "AsyncScalarDocsResourceWithRawResponse",
+ "ScalarDocsResourceWithStreamingResponse",
+ "AsyncScalarDocsResourceWithStreamingResponse",
+ "NamespacesResource",
+ "AsyncNamespacesResource",
+ "NamespacesResourceWithRawResponse",
+ "AsyncNamespacesResourceWithRawResponse",
+ "NamespacesResourceWithStreamingResponse",
+ "AsyncNamespacesResourceWithStreamingResponse",
+ "AuthenticationResource",
+ "AsyncAuthenticationResource",
+ "AuthenticationResourceWithRawResponse",
+ "AsyncAuthenticationResourceWithRawResponse",
+ "AuthenticationResourceWithStreamingResponse",
+ "AsyncAuthenticationResourceWithStreamingResponse",
+]
diff --git a/src/resources/authentication.py b/src/resources/authentication.py
new file mode 100644
index 0000000..37d5e9e
--- /dev/null
+++ b/src/resources/authentication.py
@@ -0,0 +1,172 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.authentication_exchange_personal_token_response import AuthenticationExchangePersonalTokenResponse
+from ..types import authentication_exchange_personal_token_params
+from ..types.authentication_list_current_user_response import AuthenticationListCurrentUserResponse
+
+__all__ = ["AuthenticationResource", "AsyncAuthenticationResource"]
+
+
+class AuthenticationResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AuthenticationResourceWithRawResponse:
+ return AuthenticationResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AuthenticationResourceWithStreamingResponse:
+ return AuthenticationResourceWithStreamingResponse(self)
+
+ def exchange_personal_token(
+ self,
+ *,
+ personal_token: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> AuthenticationExchangePersonalTokenResponse:
+ """Exchange an API key for an access token."""
+ return self._post(
+ "/v1/auth/exchange",
+ body=maybe_transform(
+ {"personal_token": personal_token},
+ authentication_exchange_personal_token_params.AuthenticationExchangePersonalTokenParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=AuthenticationExchangePersonalTokenResponse,
+ )
+
+ def list_current_user(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AuthenticationListCurrentUserResponse:
+ """Get the authenticated user, including their available teams and theme."""
+ return self._get(
+ "/v1/auth/me",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=AuthenticationListCurrentUserResponse,
+ )
+
+
+class AsyncAuthenticationResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncAuthenticationResourceWithRawResponse:
+ return AsyncAuthenticationResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAuthenticationResourceWithStreamingResponse:
+ return AsyncAuthenticationResourceWithStreamingResponse(self)
+
+ async def exchange_personal_token(
+ self,
+ *,
+ personal_token: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> AuthenticationExchangePersonalTokenResponse:
+ """Exchange an API key for an access token."""
+ return await self._post(
+ "/v1/auth/exchange",
+ body=await async_maybe_transform(
+ {"personal_token": personal_token},
+ authentication_exchange_personal_token_params.AuthenticationExchangePersonalTokenParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=AuthenticationExchangePersonalTokenResponse,
+ )
+
+ async def list_current_user(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AuthenticationListCurrentUserResponse:
+ """Get the authenticated user, including their available teams and theme."""
+ return await self._get(
+ "/v1/auth/me",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=AuthenticationListCurrentUserResponse,
+ )
+
+
+class AuthenticationResourceWithRawResponse:
+ def __init__(self, authentication: AuthenticationResource) -> None:
+ self._authentication = authentication
+
+ self.exchange_personal_token = to_raw_response_wrapper(
+ authentication.exchange_personal_token,
+ )
+ self.list_current_user = to_raw_response_wrapper(
+ authentication.list_current_user,
+ )
+
+
+class AsyncAuthenticationResourceWithRawResponse:
+ def __init__(self, authentication: AsyncAuthenticationResource) -> None:
+ self._authentication = authentication
+
+ self.exchange_personal_token = async_to_raw_response_wrapper(
+ authentication.exchange_personal_token,
+ )
+ self.list_current_user = async_to_raw_response_wrapper(
+ authentication.list_current_user,
+ )
+
+
+class AuthenticationResourceWithStreamingResponse:
+ def __init__(self, authentication: AuthenticationResource) -> None:
+ self._authentication = authentication
+
+ self.exchange_personal_token = to_streamed_response_wrapper(
+ authentication.exchange_personal_token,
+ )
+ self.list_current_user = to_streamed_response_wrapper(
+ authentication.list_current_user,
+ )
+
+
+class AsyncAuthenticationResourceWithStreamingResponse:
+ def __init__(self, authentication: AsyncAuthenticationResource) -> None:
+ self._authentication = authentication
+
+ self.exchange_personal_token = async_to_streamed_response_wrapper(
+ authentication.exchange_personal_token,
+ )
+ self.list_current_user = async_to_streamed_response_wrapper(
+ authentication.list_current_user,
+ )
diff --git a/src/resources/login_portals.py b/src/resources/login_portals.py
new file mode 100644
index 0000000..ff4d9bf
--- /dev/null
+++ b/src/resources/login_portals.py
@@ -0,0 +1,362 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.login_portal_retrieve_response import LoginPortalRetrieveResponse
+from ..types.login_portal_update_response import LoginPortalUpdateResponse
+from ..types import login_portal_update_params
+from ..types.login_portal_delete_response import LoginPortalDeleteResponse
+from ..types.login_portal_create_response import LoginPortalCreateResponse
+from ..types import login_portal_create_params
+from ..types.login_portal_list_response import LoginPortalListResponse
+
+__all__ = ["LoginPortalsResource", "AsyncLoginPortalsResource"]
+
+
+class LoginPortalsResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> LoginPortalsResourceWithRawResponse:
+ return LoginPortalsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> LoginPortalsResourceWithStreamingResponse:
+ return LoginPortalsResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> LoginPortalRetrieveResponse:
+ """Get a login portal by slug."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._get(
+ path_template("/v1/login-portals/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=LoginPortalRetrieveResponse,
+ )
+
+ def update(
+ self,
+ slug: str,
+ *,
+ title: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> LoginPortalUpdateResponse:
+ """Update metadata for a login portal."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._patch(
+ path_template("/v1/login-portals/{slug}", **{"slug": slug}),
+ body=maybe_transform(
+ {"title": title},
+ login_portal_update_params.LoginPortalUpdateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=LoginPortalUpdateResponse,
+ )
+
+ def delete(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> LoginPortalDeleteResponse:
+ """Delete a login portal."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/login-portals/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=LoginPortalDeleteResponse,
+ )
+
+ def create(
+ self,
+ *,
+ title: str,
+ slug: str,
+ email: object,
+ page: object,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> LoginPortalCreateResponse:
+ """Create a login portal for the current team."""
+ return self._post(
+ "/v1/login-portals",
+ body=maybe_transform(
+ {
+ "title": title,
+ "slug": slug,
+ "email": email,
+ "page": page,
+ },
+ login_portal_create_params.LoginPortalCreateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=LoginPortalCreateResponse,
+ )
+
+ def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> LoginPortalListResponse:
+ """List all login portals for the current team."""
+ return self._get(
+ "/v1/login-portals",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=LoginPortalListResponse,
+ )
+
+
+class AsyncLoginPortalsResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncLoginPortalsResourceWithRawResponse:
+ return AsyncLoginPortalsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncLoginPortalsResourceWithStreamingResponse:
+ return AsyncLoginPortalsResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> LoginPortalRetrieveResponse:
+ """Get a login portal by slug."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._get(
+ path_template("/v1/login-portals/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=LoginPortalRetrieveResponse,
+ )
+
+ async def update(
+ self,
+ slug: str,
+ *,
+ title: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> LoginPortalUpdateResponse:
+ """Update metadata for a login portal."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._patch(
+ path_template("/v1/login-portals/{slug}", **{"slug": slug}),
+ body=await async_maybe_transform(
+ {"title": title},
+ login_portal_update_params.LoginPortalUpdateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=LoginPortalUpdateResponse,
+ )
+
+ async def delete(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> LoginPortalDeleteResponse:
+ """Delete a login portal."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/login-portals/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=LoginPortalDeleteResponse,
+ )
+
+ async def create(
+ self,
+ *,
+ title: str,
+ slug: str,
+ email: object,
+ page: object,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> LoginPortalCreateResponse:
+ """Create a login portal for the current team."""
+ return await self._post(
+ "/v1/login-portals",
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "slug": slug,
+ "email": email,
+ "page": page,
+ },
+ login_portal_create_params.LoginPortalCreateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=LoginPortalCreateResponse,
+ )
+
+ async def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> LoginPortalListResponse:
+ """List all login portals for the current team."""
+ return await self._get(
+ "/v1/login-portals",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=LoginPortalListResponse,
+ )
+
+
+class LoginPortalsResourceWithRawResponse:
+ def __init__(self, login_portals: LoginPortalsResource) -> None:
+ self._login_portals = login_portals
+
+ self.retrieve = to_raw_response_wrapper(
+ login_portals.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ login_portals.update,
+ )
+ self.delete = to_raw_response_wrapper(
+ login_portals.delete,
+ )
+ self.create = to_raw_response_wrapper(
+ login_portals.create,
+ )
+ self.list = to_raw_response_wrapper(
+ login_portals.list,
+ )
+
+
+class AsyncLoginPortalsResourceWithRawResponse:
+ def __init__(self, login_portals: AsyncLoginPortalsResource) -> None:
+ self._login_portals = login_portals
+
+ self.retrieve = async_to_raw_response_wrapper(
+ login_portals.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ login_portals.update,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ login_portals.delete,
+ )
+ self.create = async_to_raw_response_wrapper(
+ login_portals.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ login_portals.list,
+ )
+
+
+class LoginPortalsResourceWithStreamingResponse:
+ def __init__(self, login_portals: LoginPortalsResource) -> None:
+ self._login_portals = login_portals
+
+ self.retrieve = to_streamed_response_wrapper(
+ login_portals.retrieve,
+ )
+ self.update = to_streamed_response_wrapper(
+ login_portals.update,
+ )
+ self.delete = to_streamed_response_wrapper(
+ login_portals.delete,
+ )
+ self.create = to_streamed_response_wrapper(
+ login_portals.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ login_portals.list,
+ )
+
+
+class AsyncLoginPortalsResourceWithStreamingResponse:
+ def __init__(self, login_portals: AsyncLoginPortalsResource) -> None:
+ self._login_portals = login_portals
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ login_portals.retrieve,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ login_portals.update,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ login_portals.delete,
+ )
+ self.create = async_to_streamed_response_wrapper(
+ login_portals.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ login_portals.list,
+ )
diff --git a/src/resources/namespaces.py b/src/resources/namespaces.py
new file mode 100644
index 0000000..52f6303
--- /dev/null
+++ b/src/resources/namespaces.py
@@ -0,0 +1,112 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.namespace_list_response import NamespaceListResponse
+
+__all__ = ["NamespacesResource", "AsyncNamespacesResource"]
+
+
+class NamespacesResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> NamespacesResourceWithRawResponse:
+ return NamespacesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> NamespacesResourceWithStreamingResponse:
+ return NamespacesResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> NamespaceListResponse:
+ """Get all namespaces for the current team"""
+ return self._get(
+ "/v1/namespaces",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=NamespaceListResponse,
+ )
+
+
+class AsyncNamespacesResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncNamespacesResourceWithRawResponse:
+ return AsyncNamespacesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncNamespacesResourceWithStreamingResponse:
+ return AsyncNamespacesResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> NamespaceListResponse:
+ """Get all namespaces for the current team"""
+ return await self._get(
+ "/v1/namespaces",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=NamespaceListResponse,
+ )
+
+
+class NamespacesResourceWithRawResponse:
+ def __init__(self, namespaces: NamespacesResource) -> None:
+ self._namespaces = namespaces
+
+ self.list = to_raw_response_wrapper(
+ namespaces.list,
+ )
+
+
+class AsyncNamespacesResourceWithRawResponse:
+ def __init__(self, namespaces: AsyncNamespacesResource) -> None:
+ self._namespaces = namespaces
+
+ self.list = async_to_raw_response_wrapper(
+ namespaces.list,
+ )
+
+
+class NamespacesResourceWithStreamingResponse:
+ def __init__(self, namespaces: NamespacesResource) -> None:
+ self._namespaces = namespaces
+
+ self.list = to_streamed_response_wrapper(
+ namespaces.list,
+ )
+
+
+class AsyncNamespacesResourceWithStreamingResponse:
+ def __init__(self, namespaces: AsyncNamespacesResource) -> None:
+ self._namespaces = namespaces
+
+ self.list = async_to_streamed_response_wrapper(
+ namespaces.list,
+ )
diff --git a/src/resources/registry.py b/src/resources/registry.py
new file mode 100644
index 0000000..be45f27
--- /dev/null
+++ b/src/resources/registry.py
@@ -0,0 +1,923 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.registry_list_all_api_documents_response import RegistryListAllApiDocumentsResponse
+from ..types.registry_list_api_documents_response import RegistryListApiDocumentsResponse
+from ..types.registry_create_api_document_response import RegistryCreateApiDocumentResponse
+from ..types import registry_create_api_document_params
+from ..types.registry_update_api_document_response import RegistryUpdateApiDocumentResponse
+from ..types import registry_update_api_document_params
+from ..types.registry_delete_api_document_response import RegistryDeleteApiDocumentResponse
+from ..types.registry_retrieve_api_document_version_response import RegistryRetrieveApiDocumentVersionResponse
+from ..types.registry_update_api_document_version_response import RegistryUpdateApiDocumentVersionResponse
+from ..types import registry_update_api_document_version_params
+from ..types.registry_delete_api_document_version_response import RegistryDeleteApiDocumentVersionResponse
+from ..types.registry_list_api_document_version_metadata_response import RegistryListApiDocumentVersionMetadataResponse
+from ..types.registry_create_api_document_version_response import RegistryCreateApiDocumentVersionResponse
+from ..types import registry_create_api_document_version_params
+from ..types.registry_create_api_document_access_group_response import RegistryCreateApiDocumentAccessGroupResponse
+from ..types import registry_create_api_document_access_group_params
+from ..types.registry_delete_api_document_access_group_response import RegistryDeleteApiDocumentAccessGroupResponse
+from ..types import registry_delete_api_document_access_group_params
+
+__all__ = ["RegistryResource", "AsyncRegistryResource"]
+
+
+class RegistryResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> RegistryResourceWithRawResponse:
+ return RegistryResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RegistryResourceWithStreamingResponse:
+ return RegistryResourceWithStreamingResponse(self)
+
+ def list_all_api_documents(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryListAllApiDocumentsResponse:
+ """List all API documents across every namespace the caller can access."""
+ return self._get(
+ "/v1/apis",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryListAllApiDocumentsResponse,
+ )
+
+ def list_api_documents(
+ self,
+ namespace: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryListApiDocumentsResponse:
+ """List API documents in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return self._get(
+ path_template("/v1/apis/{namespace}", **{"namespace": namespace}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryListApiDocumentsResponse,
+ )
+
+ def create_api_document(
+ self,
+ namespace: str,
+ *,
+ title: str,
+ description: str | Omit = omit,
+ version: str,
+ slug: str,
+ ruleset: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryCreateApiDocumentResponse:
+ """Create an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return self._post(
+ path_template("/v1/apis/{namespace}", **{"namespace": namespace}),
+ body=maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "version": version,
+ "slug": slug,
+ "ruleset": ruleset,
+ "is_private": is_private,
+ "document": document,
+ },
+ registry_create_api_document_params.RegistryCreateApiDocumentParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryCreateApiDocumentResponse,
+ )
+
+ def update_api_document(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ title: str | Omit = omit,
+ description: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ ruleset: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryUpdateApiDocumentResponse:
+ """Update metadata for an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._patch(
+ path_template("/v1/apis/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "is_private": is_private,
+ "ruleset": ruleset,
+ },
+ registry_update_api_document_params.RegistryUpdateApiDocumentParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryUpdateApiDocumentResponse,
+ )
+
+ def delete_api_document(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryDeleteApiDocumentResponse:
+ """Delete an API document and all versions."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/apis/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryDeleteApiDocumentResponse,
+ )
+
+ def retrieve_api_document_version(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryRetrieveApiDocumentVersionResponse:
+ """Get a specific API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return self._get(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryRetrieveApiDocumentVersionResponse,
+ )
+
+ def update_api_document_version(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ document: str,
+ last_known_version_sha: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryUpdateApiDocumentVersionResponse:
+ """Update the registry file content for an API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return self._patch(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ body=maybe_transform(
+ {
+ "document": document,
+ "last_known_version_sha": last_known_version_sha,
+ },
+ registry_update_api_document_version_params.RegistryUpdateApiDocumentVersionParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryUpdateApiDocumentVersionResponse,
+ )
+
+ def delete_api_document_version(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryDeleteApiDocumentVersionResponse:
+ """Delete a specific API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return self._delete(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryDeleteApiDocumentVersionResponse,
+ )
+
+ def list_api_document_version_metadata(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryListApiDocumentVersionMetadataResponse:
+ """Get metadata (uid, content shas, version sha, tags) for a specific API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return self._get(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}/metadata", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryListApiDocumentVersionMetadataResponse,
+ )
+
+ def create_api_document_version(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ version: str,
+ document: str,
+ force: bool | Omit = omit,
+ last_known_version_sha: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryCreateApiDocumentVersionResponse:
+ """Create a new API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._post(
+ path_template("/v1/apis/{namespace}/{slug}/version", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {
+ "version": version,
+ "document": document,
+ "force": force,
+ "last_known_version_sha": last_known_version_sha,
+ },
+ registry_create_api_document_version_params.RegistryCreateApiDocumentVersionParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryCreateApiDocumentVersionResponse,
+ )
+
+ def create_api_document_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryCreateApiDocumentAccessGroupResponse:
+ """Add an access group to an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._post(
+ path_template("/v1/apis/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {"access_group_slug": access_group_slug},
+ registry_create_api_document_access_group_params.RegistryCreateApiDocumentAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryCreateApiDocumentAccessGroupResponse,
+ )
+
+ def delete_api_document_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryDeleteApiDocumentAccessGroupResponse:
+ """Remove an access group from an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/apis/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {"access_group_slug": access_group_slug},
+ registry_delete_api_document_access_group_params.RegistryDeleteApiDocumentAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryDeleteApiDocumentAccessGroupResponse,
+ )
+
+
+class AsyncRegistryResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncRegistryResourceWithRawResponse:
+ return AsyncRegistryResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRegistryResourceWithStreamingResponse:
+ return AsyncRegistryResourceWithStreamingResponse(self)
+
+ async def list_all_api_documents(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryListAllApiDocumentsResponse:
+ """List all API documents across every namespace the caller can access."""
+ return await self._get(
+ "/v1/apis",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryListAllApiDocumentsResponse,
+ )
+
+ async def list_api_documents(
+ self,
+ namespace: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryListApiDocumentsResponse:
+ """List API documents in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return await self._get(
+ path_template("/v1/apis/{namespace}", **{"namespace": namespace}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryListApiDocumentsResponse,
+ )
+
+ async def create_api_document(
+ self,
+ namespace: str,
+ *,
+ title: str,
+ description: str | Omit = omit,
+ version: str,
+ slug: str,
+ ruleset: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryCreateApiDocumentResponse:
+ """Create an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return await self._post(
+ path_template("/v1/apis/{namespace}", **{"namespace": namespace}),
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "version": version,
+ "slug": slug,
+ "ruleset": ruleset,
+ "is_private": is_private,
+ "document": document,
+ },
+ registry_create_api_document_params.RegistryCreateApiDocumentParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryCreateApiDocumentResponse,
+ )
+
+ async def update_api_document(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ title: str | Omit = omit,
+ description: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ ruleset: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryUpdateApiDocumentResponse:
+ """Update metadata for an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._patch(
+ path_template("/v1/apis/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "is_private": is_private,
+ "ruleset": ruleset,
+ },
+ registry_update_api_document_params.RegistryUpdateApiDocumentParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryUpdateApiDocumentResponse,
+ )
+
+ async def delete_api_document(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryDeleteApiDocumentResponse:
+ """Delete an API document and all versions."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/apis/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryDeleteApiDocumentResponse,
+ )
+
+ async def retrieve_api_document_version(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryRetrieveApiDocumentVersionResponse:
+ """Get a specific API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return await self._get(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryRetrieveApiDocumentVersionResponse,
+ )
+
+ async def update_api_document_version(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ document: str,
+ last_known_version_sha: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryUpdateApiDocumentVersionResponse:
+ """Update the registry file content for an API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return await self._patch(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ body=await async_maybe_transform(
+ {
+ "document": document,
+ "last_known_version_sha": last_known_version_sha,
+ },
+ registry_update_api_document_version_params.RegistryUpdateApiDocumentVersionParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryUpdateApiDocumentVersionResponse,
+ )
+
+ async def delete_api_document_version(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryDeleteApiDocumentVersionResponse:
+ """Delete a specific API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return await self._delete(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryDeleteApiDocumentVersionResponse,
+ )
+
+ async def list_api_document_version_metadata(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RegistryListApiDocumentVersionMetadataResponse:
+ """Get metadata (uid, content shas, version sha, tags) for a specific API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return await self._get(
+ path_template("/v1/apis/{namespace}/{slug}/version/{semver}/metadata", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RegistryListApiDocumentVersionMetadataResponse,
+ )
+
+ async def create_api_document_version(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ version: str,
+ document: str,
+ force: bool | Omit = omit,
+ last_known_version_sha: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryCreateApiDocumentVersionResponse:
+ """Create a new API document version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._post(
+ path_template("/v1/apis/{namespace}/{slug}/version", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {
+ "version": version,
+ "document": document,
+ "force": force,
+ "last_known_version_sha": last_known_version_sha,
+ },
+ registry_create_api_document_version_params.RegistryCreateApiDocumentVersionParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryCreateApiDocumentVersionResponse,
+ )
+
+ async def create_api_document_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryCreateApiDocumentAccessGroupResponse:
+ """Add an access group to an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._post(
+ path_template("/v1/apis/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {"access_group_slug": access_group_slug},
+ registry_create_api_document_access_group_params.RegistryCreateApiDocumentAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryCreateApiDocumentAccessGroupResponse,
+ )
+
+ async def delete_api_document_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RegistryDeleteApiDocumentAccessGroupResponse:
+ """Remove an access group from an API document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/apis/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {"access_group_slug": access_group_slug},
+ registry_delete_api_document_access_group_params.RegistryDeleteApiDocumentAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RegistryDeleteApiDocumentAccessGroupResponse,
+ )
+
+
+class RegistryResourceWithRawResponse:
+ def __init__(self, registry: RegistryResource) -> None:
+ self._registry = registry
+
+ self.list_all_api_documents = to_raw_response_wrapper(
+ registry.list_all_api_documents,
+ )
+ self.list_api_documents = to_raw_response_wrapper(
+ registry.list_api_documents,
+ )
+ self.create_api_document = to_raw_response_wrapper(
+ registry.create_api_document,
+ )
+ self.update_api_document = to_raw_response_wrapper(
+ registry.update_api_document,
+ )
+ self.delete_api_document = to_raw_response_wrapper(
+ registry.delete_api_document,
+ )
+ self.retrieve_api_document_version = to_raw_response_wrapper(
+ registry.retrieve_api_document_version,
+ )
+ self.update_api_document_version = to_raw_response_wrapper(
+ registry.update_api_document_version,
+ )
+ self.delete_api_document_version = to_raw_response_wrapper(
+ registry.delete_api_document_version,
+ )
+ self.list_api_document_version_metadata = to_raw_response_wrapper(
+ registry.list_api_document_version_metadata,
+ )
+ self.create_api_document_version = to_raw_response_wrapper(
+ registry.create_api_document_version,
+ )
+ self.create_api_document_access_group = to_raw_response_wrapper(
+ registry.create_api_document_access_group,
+ )
+ self.delete_api_document_access_group = to_raw_response_wrapper(
+ registry.delete_api_document_access_group,
+ )
+
+
+class AsyncRegistryResourceWithRawResponse:
+ def __init__(self, registry: AsyncRegistryResource) -> None:
+ self._registry = registry
+
+ self.list_all_api_documents = async_to_raw_response_wrapper(
+ registry.list_all_api_documents,
+ )
+ self.list_api_documents = async_to_raw_response_wrapper(
+ registry.list_api_documents,
+ )
+ self.create_api_document = async_to_raw_response_wrapper(
+ registry.create_api_document,
+ )
+ self.update_api_document = async_to_raw_response_wrapper(
+ registry.update_api_document,
+ )
+ self.delete_api_document = async_to_raw_response_wrapper(
+ registry.delete_api_document,
+ )
+ self.retrieve_api_document_version = async_to_raw_response_wrapper(
+ registry.retrieve_api_document_version,
+ )
+ self.update_api_document_version = async_to_raw_response_wrapper(
+ registry.update_api_document_version,
+ )
+ self.delete_api_document_version = async_to_raw_response_wrapper(
+ registry.delete_api_document_version,
+ )
+ self.list_api_document_version_metadata = async_to_raw_response_wrapper(
+ registry.list_api_document_version_metadata,
+ )
+ self.create_api_document_version = async_to_raw_response_wrapper(
+ registry.create_api_document_version,
+ )
+ self.create_api_document_access_group = async_to_raw_response_wrapper(
+ registry.create_api_document_access_group,
+ )
+ self.delete_api_document_access_group = async_to_raw_response_wrapper(
+ registry.delete_api_document_access_group,
+ )
+
+
+class RegistryResourceWithStreamingResponse:
+ def __init__(self, registry: RegistryResource) -> None:
+ self._registry = registry
+
+ self.list_all_api_documents = to_streamed_response_wrapper(
+ registry.list_all_api_documents,
+ )
+ self.list_api_documents = to_streamed_response_wrapper(
+ registry.list_api_documents,
+ )
+ self.create_api_document = to_streamed_response_wrapper(
+ registry.create_api_document,
+ )
+ self.update_api_document = to_streamed_response_wrapper(
+ registry.update_api_document,
+ )
+ self.delete_api_document = to_streamed_response_wrapper(
+ registry.delete_api_document,
+ )
+ self.retrieve_api_document_version = to_streamed_response_wrapper(
+ registry.retrieve_api_document_version,
+ )
+ self.update_api_document_version = to_streamed_response_wrapper(
+ registry.update_api_document_version,
+ )
+ self.delete_api_document_version = to_streamed_response_wrapper(
+ registry.delete_api_document_version,
+ )
+ self.list_api_document_version_metadata = to_streamed_response_wrapper(
+ registry.list_api_document_version_metadata,
+ )
+ self.create_api_document_version = to_streamed_response_wrapper(
+ registry.create_api_document_version,
+ )
+ self.create_api_document_access_group = to_streamed_response_wrapper(
+ registry.create_api_document_access_group,
+ )
+ self.delete_api_document_access_group = to_streamed_response_wrapper(
+ registry.delete_api_document_access_group,
+ )
+
+
+class AsyncRegistryResourceWithStreamingResponse:
+ def __init__(self, registry: AsyncRegistryResource) -> None:
+ self._registry = registry
+
+ self.list_all_api_documents = async_to_streamed_response_wrapper(
+ registry.list_all_api_documents,
+ )
+ self.list_api_documents = async_to_streamed_response_wrapper(
+ registry.list_api_documents,
+ )
+ self.create_api_document = async_to_streamed_response_wrapper(
+ registry.create_api_document,
+ )
+ self.update_api_document = async_to_streamed_response_wrapper(
+ registry.update_api_document,
+ )
+ self.delete_api_document = async_to_streamed_response_wrapper(
+ registry.delete_api_document,
+ )
+ self.retrieve_api_document_version = async_to_streamed_response_wrapper(
+ registry.retrieve_api_document_version,
+ )
+ self.update_api_document_version = async_to_streamed_response_wrapper(
+ registry.update_api_document_version,
+ )
+ self.delete_api_document_version = async_to_streamed_response_wrapper(
+ registry.delete_api_document_version,
+ )
+ self.list_api_document_version_metadata = async_to_streamed_response_wrapper(
+ registry.list_api_document_version_metadata,
+ )
+ self.create_api_document_version = async_to_streamed_response_wrapper(
+ registry.create_api_document_version,
+ )
+ self.create_api_document_access_group = async_to_streamed_response_wrapper(
+ registry.create_api_document_access_group,
+ )
+ self.delete_api_document_access_group = async_to_streamed_response_wrapper(
+ registry.delete_api_document_access_group,
+ )
diff --git a/src/resources/rules.py b/src/resources/rules.py
new file mode 100644
index 0000000..a37deb2
--- /dev/null
+++ b/src/resources/rules.py
@@ -0,0 +1,552 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.rule_list_rulesets_response import RuleListRulesetsResponse
+from ..types.rule_create_ruleset_response import RuleCreateRulesetResponse
+from ..types import rule_create_ruleset_params
+from ..types.rule_update_ruleset_response import RuleUpdateRulesetResponse
+from ..types import rule_update_ruleset_params
+from ..types.rule_delete_ruleset_response import RuleDeleteRulesetResponse
+from ..types.rule_retrieve_ruleset_document_response import RuleRetrieveRulesetDocumentResponse
+from ..types.rule_create_ruleset_access_group_response import RuleCreateRulesetAccessGroupResponse
+from ..types import rule_create_ruleset_access_group_params
+from ..types.rule_delete_ruleset_access_group_response import RuleDeleteRulesetAccessGroupResponse
+from ..types import rule_delete_ruleset_access_group_params
+
+__all__ = ["RulesResource", "AsyncRulesResource"]
+
+
+class RulesResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> RulesResourceWithRawResponse:
+ return RulesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RulesResourceWithStreamingResponse:
+ return RulesResourceWithStreamingResponse(self)
+
+ def list_rulesets(
+ self,
+ namespace: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RuleListRulesetsResponse:
+ """List all rulesets in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return self._get(
+ path_template("/v1/rulesets/{namespace}", **{"namespace": namespace}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RuleListRulesetsResponse,
+ )
+
+ def create_ruleset(
+ self,
+ namespace: str,
+ *,
+ title: str,
+ description: str | Omit = omit,
+ slug: str,
+ is_private: bool | Omit = omit,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleCreateRulesetResponse:
+ """Create a rule in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return self._post(
+ path_template("/v1/rulesets/{namespace}", **{"namespace": namespace}),
+ body=maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "slug": slug,
+ "is_private": is_private,
+ "document": document,
+ },
+ rule_create_ruleset_params.RuleCreateRulesetParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleCreateRulesetResponse,
+ )
+
+ def update_ruleset(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ title: str | Omit = omit,
+ description: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleUpdateRulesetResponse:
+ """Update rule metadata by slug."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._patch(
+ path_template("/v1/rulesets/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "is_private": is_private,
+ },
+ rule_update_ruleset_params.RuleUpdateRulesetParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleUpdateRulesetResponse,
+ )
+
+ def delete_ruleset(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleDeleteRulesetResponse:
+ """Delete a rule by slug."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/rulesets/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleDeleteRulesetResponse,
+ )
+
+ def retrieve_ruleset_document(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RuleRetrieveRulesetDocumentResponse:
+ """Get a rule document by slug."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._get(
+ path_template("/v1/rulesets/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RuleRetrieveRulesetDocumentResponse,
+ )
+
+ def create_ruleset_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleCreateRulesetAccessGroupResponse:
+ """Grant an access group to a rule."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._post(
+ path_template("/v1/rulesets/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {"access_group_slug": access_group_slug},
+ rule_create_ruleset_access_group_params.RuleCreateRulesetAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleCreateRulesetAccessGroupResponse,
+ )
+
+ def delete_ruleset_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleDeleteRulesetAccessGroupResponse:
+ """Remove an access group from a rule."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/rulesets/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {"access_group_slug": access_group_slug},
+ rule_delete_ruleset_access_group_params.RuleDeleteRulesetAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleDeleteRulesetAccessGroupResponse,
+ )
+
+
+class AsyncRulesResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncRulesResourceWithRawResponse:
+ return AsyncRulesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRulesResourceWithStreamingResponse:
+ return AsyncRulesResourceWithStreamingResponse(self)
+
+ async def list_rulesets(
+ self,
+ namespace: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RuleListRulesetsResponse:
+ """List all rulesets in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return await self._get(
+ path_template("/v1/rulesets/{namespace}", **{"namespace": namespace}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RuleListRulesetsResponse,
+ )
+
+ async def create_ruleset(
+ self,
+ namespace: str,
+ *,
+ title: str,
+ description: str | Omit = omit,
+ slug: str,
+ is_private: bool | Omit = omit,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleCreateRulesetResponse:
+ """Create a rule in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return await self._post(
+ path_template("/v1/rulesets/{namespace}", **{"namespace": namespace}),
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "slug": slug,
+ "is_private": is_private,
+ "document": document,
+ },
+ rule_create_ruleset_params.RuleCreateRulesetParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleCreateRulesetResponse,
+ )
+
+ async def update_ruleset(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ title: str | Omit = omit,
+ description: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleUpdateRulesetResponse:
+ """Update rule metadata by slug."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._patch(
+ path_template("/v1/rulesets/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "is_private": is_private,
+ },
+ rule_update_ruleset_params.RuleUpdateRulesetParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleUpdateRulesetResponse,
+ )
+
+ async def delete_ruleset(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleDeleteRulesetResponse:
+ """Delete a rule by slug."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/rulesets/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleDeleteRulesetResponse,
+ )
+
+ async def retrieve_ruleset_document(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RuleRetrieveRulesetDocumentResponse:
+ """Get a rule document by slug."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._get(
+ path_template("/v1/rulesets/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=RuleRetrieveRulesetDocumentResponse,
+ )
+
+ async def create_ruleset_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleCreateRulesetAccessGroupResponse:
+ """Grant an access group to a rule."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._post(
+ path_template("/v1/rulesets/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {"access_group_slug": access_group_slug},
+ rule_create_ruleset_access_group_params.RuleCreateRulesetAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleCreateRulesetAccessGroupResponse,
+ )
+
+ async def delete_ruleset_access_group(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> RuleDeleteRulesetAccessGroupResponse:
+ """Remove an access group from a rule."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/rulesets/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {"access_group_slug": access_group_slug},
+ rule_delete_ruleset_access_group_params.RuleDeleteRulesetAccessGroupParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=RuleDeleteRulesetAccessGroupResponse,
+ )
+
+
+class RulesResourceWithRawResponse:
+ def __init__(self, rules: RulesResource) -> None:
+ self._rules = rules
+
+ self.list_rulesets = to_raw_response_wrapper(
+ rules.list_rulesets,
+ )
+ self.create_ruleset = to_raw_response_wrapper(
+ rules.create_ruleset,
+ )
+ self.update_ruleset = to_raw_response_wrapper(
+ rules.update_ruleset,
+ )
+ self.delete_ruleset = to_raw_response_wrapper(
+ rules.delete_ruleset,
+ )
+ self.retrieve_ruleset_document = to_raw_response_wrapper(
+ rules.retrieve_ruleset_document,
+ )
+ self.create_ruleset_access_group = to_raw_response_wrapper(
+ rules.create_ruleset_access_group,
+ )
+ self.delete_ruleset_access_group = to_raw_response_wrapper(
+ rules.delete_ruleset_access_group,
+ )
+
+
+class AsyncRulesResourceWithRawResponse:
+ def __init__(self, rules: AsyncRulesResource) -> None:
+ self._rules = rules
+
+ self.list_rulesets = async_to_raw_response_wrapper(
+ rules.list_rulesets,
+ )
+ self.create_ruleset = async_to_raw_response_wrapper(
+ rules.create_ruleset,
+ )
+ self.update_ruleset = async_to_raw_response_wrapper(
+ rules.update_ruleset,
+ )
+ self.delete_ruleset = async_to_raw_response_wrapper(
+ rules.delete_ruleset,
+ )
+ self.retrieve_ruleset_document = async_to_raw_response_wrapper(
+ rules.retrieve_ruleset_document,
+ )
+ self.create_ruleset_access_group = async_to_raw_response_wrapper(
+ rules.create_ruleset_access_group,
+ )
+ self.delete_ruleset_access_group = async_to_raw_response_wrapper(
+ rules.delete_ruleset_access_group,
+ )
+
+
+class RulesResourceWithStreamingResponse:
+ def __init__(self, rules: RulesResource) -> None:
+ self._rules = rules
+
+ self.list_rulesets = to_streamed_response_wrapper(
+ rules.list_rulesets,
+ )
+ self.create_ruleset = to_streamed_response_wrapper(
+ rules.create_ruleset,
+ )
+ self.update_ruleset = to_streamed_response_wrapper(
+ rules.update_ruleset,
+ )
+ self.delete_ruleset = to_streamed_response_wrapper(
+ rules.delete_ruleset,
+ )
+ self.retrieve_ruleset_document = to_streamed_response_wrapper(
+ rules.retrieve_ruleset_document,
+ )
+ self.create_ruleset_access_group = to_streamed_response_wrapper(
+ rules.create_ruleset_access_group,
+ )
+ self.delete_ruleset_access_group = to_streamed_response_wrapper(
+ rules.delete_ruleset_access_group,
+ )
+
+
+class AsyncRulesResourceWithStreamingResponse:
+ def __init__(self, rules: AsyncRulesResource) -> None:
+ self._rules = rules
+
+ self.list_rulesets = async_to_streamed_response_wrapper(
+ rules.list_rulesets,
+ )
+ self.create_ruleset = async_to_streamed_response_wrapper(
+ rules.create_ruleset,
+ )
+ self.update_ruleset = async_to_streamed_response_wrapper(
+ rules.update_ruleset,
+ )
+ self.delete_ruleset = async_to_streamed_response_wrapper(
+ rules.delete_ruleset,
+ )
+ self.retrieve_ruleset_document = async_to_streamed_response_wrapper(
+ rules.retrieve_ruleset_document,
+ )
+ self.create_ruleset_access_group = async_to_streamed_response_wrapper(
+ rules.create_ruleset_access_group,
+ )
+ self.delete_ruleset_access_group = async_to_streamed_response_wrapper(
+ rules.delete_ruleset_access_group,
+ )
diff --git a/src/resources/scalar_docs.py b/src/resources/scalar_docs.py
new file mode 100644
index 0000000..ef55373
--- /dev/null
+++ b/src/resources/scalar_docs.py
@@ -0,0 +1,249 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from typing import List
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.scalar_doc_list_guides_response import ScalarDocListGuidesResponse
+from ..types.scalar_doc_create_guide_response import ScalarDocCreateGuideResponse
+from ..types import scalar_doc_create_guide_params
+from ..types.scalar_doc_publish_guide_response import ScalarDocPublishGuideResponse
+
+__all__ = ["ScalarDocsResource", "AsyncScalarDocsResource"]
+
+
+class ScalarDocsResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> ScalarDocsResourceWithRawResponse:
+ return ScalarDocsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ScalarDocsResourceWithStreamingResponse:
+ return ScalarDocsResourceWithStreamingResponse(self)
+
+ def list_guides(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ScalarDocListGuidesResponse:
+ """List all guide projects."""
+ return self._get(
+ "/v1/guides",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=ScalarDocListGuidesResponse,
+ )
+
+ def create_guide(
+ self,
+ *,
+ name: str,
+ slug: str | Omit = omit,
+ is_private: bool,
+ allowed_users: List[str],
+ allowed_domains: List[str],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ScalarDocCreateGuideResponse:
+ """Create a guide project."""
+ return self._post(
+ "/v1/guides",
+ body=maybe_transform(
+ {
+ "name": name,
+ "slug": slug,
+ "is_private": is_private,
+ "allowed_users": allowed_users,
+ "allowed_domains": allowed_domains,
+ },
+ scalar_doc_create_guide_params.ScalarDocCreateGuideParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ScalarDocCreateGuideResponse,
+ )
+
+ def publish_guide(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ScalarDocPublishGuideResponse:
+ """Start a new publish process."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._post(
+ path_template("/v1/guides/{slug}/publish", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ScalarDocPublishGuideResponse,
+ )
+
+
+class AsyncScalarDocsResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncScalarDocsResourceWithRawResponse:
+ return AsyncScalarDocsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncScalarDocsResourceWithStreamingResponse:
+ return AsyncScalarDocsResourceWithStreamingResponse(self)
+
+ async def list_guides(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ScalarDocListGuidesResponse:
+ """List all guide projects."""
+ return await self._get(
+ "/v1/guides",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=ScalarDocListGuidesResponse,
+ )
+
+ async def create_guide(
+ self,
+ *,
+ name: str,
+ slug: str | Omit = omit,
+ is_private: bool,
+ allowed_users: List[str],
+ allowed_domains: List[str],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ScalarDocCreateGuideResponse:
+ """Create a guide project."""
+ return await self._post(
+ "/v1/guides",
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "slug": slug,
+ "is_private": is_private,
+ "allowed_users": allowed_users,
+ "allowed_domains": allowed_domains,
+ },
+ scalar_doc_create_guide_params.ScalarDocCreateGuideParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ScalarDocCreateGuideResponse,
+ )
+
+ async def publish_guide(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ScalarDocPublishGuideResponse:
+ """Start a new publish process."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._post(
+ path_template("/v1/guides/{slug}/publish", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ScalarDocPublishGuideResponse,
+ )
+
+
+class ScalarDocsResourceWithRawResponse:
+ def __init__(self, scalar_docs: ScalarDocsResource) -> None:
+ self._scalar_docs = scalar_docs
+
+ self.list_guides = to_raw_response_wrapper(
+ scalar_docs.list_guides,
+ )
+ self.create_guide = to_raw_response_wrapper(
+ scalar_docs.create_guide,
+ )
+ self.publish_guide = to_raw_response_wrapper(
+ scalar_docs.publish_guide,
+ )
+
+
+class AsyncScalarDocsResourceWithRawResponse:
+ def __init__(self, scalar_docs: AsyncScalarDocsResource) -> None:
+ self._scalar_docs = scalar_docs
+
+ self.list_guides = async_to_raw_response_wrapper(
+ scalar_docs.list_guides,
+ )
+ self.create_guide = async_to_raw_response_wrapper(
+ scalar_docs.create_guide,
+ )
+ self.publish_guide = async_to_raw_response_wrapper(
+ scalar_docs.publish_guide,
+ )
+
+
+class ScalarDocsResourceWithStreamingResponse:
+ def __init__(self, scalar_docs: ScalarDocsResource) -> None:
+ self._scalar_docs = scalar_docs
+
+ self.list_guides = to_streamed_response_wrapper(
+ scalar_docs.list_guides,
+ )
+ self.create_guide = to_streamed_response_wrapper(
+ scalar_docs.create_guide,
+ )
+ self.publish_guide = to_streamed_response_wrapper(
+ scalar_docs.publish_guide,
+ )
+
+
+class AsyncScalarDocsResourceWithStreamingResponse:
+ def __init__(self, scalar_docs: AsyncScalarDocsResource) -> None:
+ self._scalar_docs = scalar_docs
+
+ self.list_guides = async_to_streamed_response_wrapper(
+ scalar_docs.list_guides,
+ )
+ self.create_guide = async_to_streamed_response_wrapper(
+ scalar_docs.create_guide,
+ )
+ self.publish_guide = async_to_streamed_response_wrapper(
+ scalar_docs.publish_guide,
+ )
diff --git a/src/resources/schemas/__init__.py b/src/resources/schemas/__init__.py
new file mode 100644
index 0000000..bee0515
--- /dev/null
+++ b/src/resources/schemas/__init__.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from .schemas import (
+ SchemasResource,
+ AsyncSchemasResource,
+ SchemasResourceWithRawResponse,
+ AsyncSchemasResourceWithRawResponse,
+ SchemasResourceWithStreamingResponse,
+ AsyncSchemasResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "SchemasResource",
+ "AsyncSchemasResource",
+ "SchemasResourceWithRawResponse",
+ "AsyncSchemasResourceWithRawResponse",
+ "SchemasResourceWithStreamingResponse",
+ "AsyncSchemasResourceWithStreamingResponse",
+]
diff --git a/src/resources/schemas/access_group.py b/src/resources/schemas/access_group.py
new file mode 100644
index 0000000..5ef4064
--- /dev/null
+++ b/src/resources/schemas/access_group.py
@@ -0,0 +1,209 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.schemas.access_group_create_schema_response import AccessGroupCreateSchemaResponse
+from ...types.schemas import access_group_create_schema_params
+from ...types.schemas.access_group_delete_schema_response import AccessGroupDeleteSchemaResponse
+from ...types.schemas import access_group_delete_schema_params
+
+__all__ = ["AccessGroupResource", "AsyncAccessGroupResource"]
+
+
+class AccessGroupResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AccessGroupResourceWithRawResponse:
+ return AccessGroupResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AccessGroupResourceWithStreamingResponse:
+ return AccessGroupResourceWithStreamingResponse(self)
+
+ def create_schema(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> AccessGroupCreateSchemaResponse:
+ """Add an access group to a schema."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._post(
+ path_template("/v1/schemas/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {"access_group_slug": access_group_slug},
+ access_group_create_schema_params.AccessGroupCreateSchemaParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=AccessGroupCreateSchemaResponse,
+ )
+
+ def delete_schema(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> AccessGroupDeleteSchemaResponse:
+ """Remove an access group from a schema."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/schemas/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {"access_group_slug": access_group_slug},
+ access_group_delete_schema_params.AccessGroupDeleteSchemaParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=AccessGroupDeleteSchemaResponse,
+ )
+
+
+class AsyncAccessGroupResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncAccessGroupResourceWithRawResponse:
+ return AsyncAccessGroupResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAccessGroupResourceWithStreamingResponse:
+ return AsyncAccessGroupResourceWithStreamingResponse(self)
+
+ async def create_schema(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> AccessGroupCreateSchemaResponse:
+ """Add an access group to a schema."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._post(
+ path_template("/v1/schemas/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {"access_group_slug": access_group_slug},
+ access_group_create_schema_params.AccessGroupCreateSchemaParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=AccessGroupCreateSchemaResponse,
+ )
+
+ async def delete_schema(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ access_group_slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> AccessGroupDeleteSchemaResponse:
+ """Remove an access group from a schema."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/schemas/{namespace}/{slug}/access-group", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {"access_group_slug": access_group_slug},
+ access_group_delete_schema_params.AccessGroupDeleteSchemaParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=AccessGroupDeleteSchemaResponse,
+ )
+
+
+class AccessGroupResourceWithRawResponse:
+ def __init__(self, access_group: AccessGroupResource) -> None:
+ self._access_group = access_group
+
+ self.create_schema = to_raw_response_wrapper(
+ access_group.create_schema,
+ )
+ self.delete_schema = to_raw_response_wrapper(
+ access_group.delete_schema,
+ )
+
+
+class AsyncAccessGroupResourceWithRawResponse:
+ def __init__(self, access_group: AsyncAccessGroupResource) -> None:
+ self._access_group = access_group
+
+ self.create_schema = async_to_raw_response_wrapper(
+ access_group.create_schema,
+ )
+ self.delete_schema = async_to_raw_response_wrapper(
+ access_group.delete_schema,
+ )
+
+
+class AccessGroupResourceWithStreamingResponse:
+ def __init__(self, access_group: AccessGroupResource) -> None:
+ self._access_group = access_group
+
+ self.create_schema = to_streamed_response_wrapper(
+ access_group.create_schema,
+ )
+ self.delete_schema = to_streamed_response_wrapper(
+ access_group.delete_schema,
+ )
+
+
+class AsyncAccessGroupResourceWithStreamingResponse:
+ def __init__(self, access_group: AsyncAccessGroupResource) -> None:
+ self._access_group = access_group
+
+ self.create_schema = async_to_streamed_response_wrapper(
+ access_group.create_schema,
+ )
+ self.delete_schema = async_to_streamed_response_wrapper(
+ access_group.delete_schema,
+ )
diff --git a/src/resources/schemas/schemas.py b/src/resources/schemas/schemas.py
new file mode 100644
index 0000000..45feea1
--- /dev/null
+++ b/src/resources/schemas/schemas.py
@@ -0,0 +1,417 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from .version import (
+ VersionResource,
+ AsyncVersionResource,
+)
+from .access_group import (
+ AccessGroupResource,
+ AsyncAccessGroupResource,
+)
+from ...types.schema_list_response import SchemaListResponse
+from ...types.schema_create_response import SchemaCreateResponse
+from ...types import schema_create_params
+from ...types.schema_update_response import SchemaUpdateResponse
+from ...types import schema_update_params
+from ...types.schema_delete_response import SchemaDeleteResponse
+
+__all__ = ["SchemasResource", "AsyncSchemasResource"]
+
+
+class SchemasResource(SyncAPIResource):
+
+ @cached_property
+ def version(self) -> VersionResource:
+ return VersionResource(self._client)
+
+ @cached_property
+ def access_group(self) -> AccessGroupResource:
+ return AccessGroupResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> SchemasResourceWithRawResponse:
+ return SchemasResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> SchemasResourceWithStreamingResponse:
+ return SchemasResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ namespace: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SchemaListResponse:
+ """List schemas in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return self._get(
+ path_template("/v1/schemas/{namespace}", **{"namespace": namespace}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=SchemaListResponse,
+ )
+
+ def create(
+ self,
+ namespace: str,
+ *,
+ title: str,
+ description: str | Omit = omit,
+ version: str,
+ slug: str,
+ is_private: bool | Omit = omit,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> SchemaCreateResponse:
+ """Create a schema in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return self._post(
+ path_template("/v1/schemas/{namespace}", **{"namespace": namespace}),
+ body=maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "version": version,
+ "slug": slug,
+ "is_private": is_private,
+ "document": document,
+ },
+ schema_create_params.SchemaCreateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=SchemaCreateResponse,
+ )
+
+ def update(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ title: str | Omit = omit,
+ description: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> SchemaUpdateResponse:
+ """Update schema metadata."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._patch(
+ path_template("/v1/schemas/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "is_private": is_private,
+ },
+ schema_update_params.SchemaUpdateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=SchemaUpdateResponse,
+ )
+
+ def delete(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> SchemaDeleteResponse:
+ """Delete a schema and all related versions."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/schemas/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=SchemaDeleteResponse,
+ )
+
+
+class AsyncSchemasResource(AsyncAPIResource):
+
+ @cached_property
+ def version(self) -> AsyncVersionResource:
+ return AsyncVersionResource(self._client)
+
+ @cached_property
+ def access_group(self) -> AsyncAccessGroupResource:
+ return AsyncAccessGroupResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncSchemasResourceWithRawResponse:
+ return AsyncSchemasResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncSchemasResourceWithStreamingResponse:
+ return AsyncSchemasResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ namespace: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SchemaListResponse:
+ """List schemas in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return await self._get(
+ path_template("/v1/schemas/{namespace}", **{"namespace": namespace}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=SchemaListResponse,
+ )
+
+ async def create(
+ self,
+ namespace: str,
+ *,
+ title: str,
+ description: str | Omit = omit,
+ version: str,
+ slug: str,
+ is_private: bool | Omit = omit,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> SchemaCreateResponse:
+ """Create a schema in a namespace."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ return await self._post(
+ path_template("/v1/schemas/{namespace}", **{"namespace": namespace}),
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "version": version,
+ "slug": slug,
+ "is_private": is_private,
+ "document": document,
+ },
+ schema_create_params.SchemaCreateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=SchemaCreateResponse,
+ )
+
+ async def update(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ title: str | Omit = omit,
+ description: str | Omit = omit,
+ is_private: bool | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> SchemaUpdateResponse:
+ """Update schema metadata."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._patch(
+ path_template("/v1/schemas/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {
+ "title": title,
+ "description": description,
+ "is_private": is_private,
+ },
+ schema_update_params.SchemaUpdateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=SchemaUpdateResponse,
+ )
+
+ async def delete(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> SchemaDeleteResponse:
+ """Delete a schema and all related versions."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/schemas/{namespace}/{slug}", **{"namespace": namespace, "slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=SchemaDeleteResponse,
+ )
+
+
+class SchemasResourceWithRawResponse:
+ def __init__(self, schemas: SchemasResource) -> None:
+ self._schemas = schemas
+
+ self.list = to_raw_response_wrapper(
+ schemas.list,
+ )
+ self.create = to_raw_response_wrapper(
+ schemas.create,
+ )
+ self.update = to_raw_response_wrapper(
+ schemas.update,
+ )
+ self.delete = to_raw_response_wrapper(
+ schemas.delete,
+ )
+
+ @cached_property
+ def version(self) -> "VersionResourceWithRawResponse":
+ from .version import VersionResourceWithRawResponse
+ return VersionResourceWithRawResponse(self._schemas.version)
+
+ @cached_property
+ def access_group(self) -> "AccessGroupResourceWithRawResponse":
+ from .access_group import AccessGroupResourceWithRawResponse
+ return AccessGroupResourceWithRawResponse(self._schemas.access_group)
+
+
+class AsyncSchemasResourceWithRawResponse:
+ def __init__(self, schemas: AsyncSchemasResource) -> None:
+ self._schemas = schemas
+
+ self.list = async_to_raw_response_wrapper(
+ schemas.list,
+ )
+ self.create = async_to_raw_response_wrapper(
+ schemas.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ schemas.update,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ schemas.delete,
+ )
+
+ @cached_property
+ def version(self) -> "AsyncVersionResourceWithRawResponse":
+ from .version import AsyncVersionResourceWithRawResponse
+ return AsyncVersionResourceWithRawResponse(self._schemas.version)
+
+ @cached_property
+ def access_group(self) -> "AsyncAccessGroupResourceWithRawResponse":
+ from .access_group import AsyncAccessGroupResourceWithRawResponse
+ return AsyncAccessGroupResourceWithRawResponse(self._schemas.access_group)
+
+
+class SchemasResourceWithStreamingResponse:
+ def __init__(self, schemas: SchemasResource) -> None:
+ self._schemas = schemas
+
+ self.list = to_streamed_response_wrapper(
+ schemas.list,
+ )
+ self.create = to_streamed_response_wrapper(
+ schemas.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ schemas.update,
+ )
+ self.delete = to_streamed_response_wrapper(
+ schemas.delete,
+ )
+
+ @cached_property
+ def version(self) -> "VersionResourceWithStreamingResponse":
+ from .version import VersionResourceWithStreamingResponse
+ return VersionResourceWithStreamingResponse(self._schemas.version)
+
+ @cached_property
+ def access_group(self) -> "AccessGroupResourceWithStreamingResponse":
+ from .access_group import AccessGroupResourceWithStreamingResponse
+ return AccessGroupResourceWithStreamingResponse(self._schemas.access_group)
+
+
+class AsyncSchemasResourceWithStreamingResponse:
+ def __init__(self, schemas: AsyncSchemasResource) -> None:
+ self._schemas = schemas
+
+ self.list = async_to_streamed_response_wrapper(
+ schemas.list,
+ )
+ self.create = async_to_streamed_response_wrapper(
+ schemas.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ schemas.update,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ schemas.delete,
+ )
+
+ @cached_property
+ def version(self) -> "AsyncVersionResourceWithStreamingResponse":
+ from .version import AsyncVersionResourceWithStreamingResponse
+ return AsyncVersionResourceWithStreamingResponse(self._schemas.version)
+
+ @cached_property
+ def access_group(self) -> "AsyncAccessGroupResourceWithStreamingResponse":
+ from .access_group import AsyncAccessGroupResourceWithStreamingResponse
+ return AsyncAccessGroupResourceWithStreamingResponse(self._schemas.access_group)
diff --git a/src/resources/schemas/version.py b/src/resources/schemas/version.py
new file mode 100644
index 0000000..9c2e01f
--- /dev/null
+++ b/src/resources/schemas/version.py
@@ -0,0 +1,277 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.schemas.version_retrieve_schema_response import VersionRetrieveSchemaResponse
+from ...types.schemas.version_delete_schema_response import VersionDeleteSchemaResponse
+from ...types.schemas.version_create_schema_response import VersionCreateSchemaResponse
+from ...types.schemas import version_create_schema_params
+
+__all__ = ["VersionResource", "AsyncVersionResource"]
+
+
+class VersionResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> VersionResourceWithRawResponse:
+ return VersionResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> VersionResourceWithStreamingResponse:
+ return VersionResourceWithStreamingResponse(self)
+
+ def retrieve_schema(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> VersionRetrieveSchemaResponse:
+ """Get a specific schema version document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return self._get(
+ path_template("/v1/schemas/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=VersionRetrieveSchemaResponse,
+ )
+
+ def delete_schema(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> VersionDeleteSchemaResponse:
+ """Delete a schema version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return self._delete(
+ path_template("/v1/schemas/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=VersionDeleteSchemaResponse,
+ )
+
+ def create_schema(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ version: str,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> VersionCreateSchemaResponse:
+ """Create a schema version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._post(
+ path_template("/v1/schemas/{namespace}/{slug}/version", **{"namespace": namespace, "slug": slug}),
+ body=maybe_transform(
+ {
+ "version": version,
+ "document": document,
+ },
+ version_create_schema_params.VersionCreateSchemaParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=VersionCreateSchemaResponse,
+ )
+
+
+class AsyncVersionResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncVersionResourceWithRawResponse:
+ return AsyncVersionResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncVersionResourceWithStreamingResponse:
+ return AsyncVersionResourceWithStreamingResponse(self)
+
+ async def retrieve_schema(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> VersionRetrieveSchemaResponse:
+ """Get a specific schema version document."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return await self._get(
+ path_template("/v1/schemas/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=VersionRetrieveSchemaResponse,
+ )
+
+ async def delete_schema(
+ self,
+ semver: str,
+ *,
+ namespace: str,
+ slug: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> VersionDeleteSchemaResponse:
+ """Delete a schema version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ if not semver:
+ raise ValueError(f"Expected a non-empty value for `semver` but received {semver!r}")
+ return await self._delete(
+ path_template("/v1/schemas/{namespace}/{slug}/version/{semver}", **{"namespace": namespace, "slug": slug, "semver": semver}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=VersionDeleteSchemaResponse,
+ )
+
+ async def create_schema(
+ self,
+ slug: str,
+ *,
+ namespace: str,
+ version: str,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> VersionCreateSchemaResponse:
+ """Create a schema version."""
+ if not namespace:
+ raise ValueError(f"Expected a non-empty value for `namespace` but received {namespace!r}")
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._post(
+ path_template("/v1/schemas/{namespace}/{slug}/version", **{"namespace": namespace, "slug": slug}),
+ body=await async_maybe_transform(
+ {
+ "version": version,
+ "document": document,
+ },
+ version_create_schema_params.VersionCreateSchemaParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=VersionCreateSchemaResponse,
+ )
+
+
+class VersionResourceWithRawResponse:
+ def __init__(self, version: VersionResource) -> None:
+ self._version = version
+
+ self.retrieve_schema = to_raw_response_wrapper(
+ version.retrieve_schema,
+ )
+ self.delete_schema = to_raw_response_wrapper(
+ version.delete_schema,
+ )
+ self.create_schema = to_raw_response_wrapper(
+ version.create_schema,
+ )
+
+
+class AsyncVersionResourceWithRawResponse:
+ def __init__(self, version: AsyncVersionResource) -> None:
+ self._version = version
+
+ self.retrieve_schema = async_to_raw_response_wrapper(
+ version.retrieve_schema,
+ )
+ self.delete_schema = async_to_raw_response_wrapper(
+ version.delete_schema,
+ )
+ self.create_schema = async_to_raw_response_wrapper(
+ version.create_schema,
+ )
+
+
+class VersionResourceWithStreamingResponse:
+ def __init__(self, version: VersionResource) -> None:
+ self._version = version
+
+ self.retrieve_schema = to_streamed_response_wrapper(
+ version.retrieve_schema,
+ )
+ self.delete_schema = to_streamed_response_wrapper(
+ version.delete_schema,
+ )
+ self.create_schema = to_streamed_response_wrapper(
+ version.create_schema,
+ )
+
+
+class AsyncVersionResourceWithStreamingResponse:
+ def __init__(self, version: AsyncVersionResource) -> None:
+ self._version = version
+
+ self.retrieve_schema = async_to_streamed_response_wrapper(
+ version.retrieve_schema,
+ )
+ self.delete_schema = async_to_streamed_response_wrapper(
+ version.delete_schema,
+ )
+ self.create_schema = async_to_streamed_response_wrapper(
+ version.create_schema,
+ )
diff --git a/src/resources/teams.py b/src/resources/teams.py
new file mode 100644
index 0000000..4b1a3e8
--- /dev/null
+++ b/src/resources/teams.py
@@ -0,0 +1,112 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.team_list_response import TeamListResponse
+
+__all__ = ["TeamsResource", "AsyncTeamsResource"]
+
+
+class TeamsResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> TeamsResourceWithRawResponse:
+ return TeamsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> TeamsResourceWithStreamingResponse:
+ return TeamsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TeamListResponse:
+ """List all available teams"""
+ return self._get(
+ "/v1/teams",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=TeamListResponse,
+ )
+
+
+class AsyncTeamsResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncTeamsResourceWithRawResponse:
+ return AsyncTeamsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncTeamsResourceWithStreamingResponse:
+ return AsyncTeamsResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TeamListResponse:
+ """List all available teams"""
+ return await self._get(
+ "/v1/teams",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=TeamListResponse,
+ )
+
+
+class TeamsResourceWithRawResponse:
+ def __init__(self, teams: TeamsResource) -> None:
+ self._teams = teams
+
+ self.list = to_raw_response_wrapper(
+ teams.list,
+ )
+
+
+class AsyncTeamsResourceWithRawResponse:
+ def __init__(self, teams: AsyncTeamsResource) -> None:
+ self._teams = teams
+
+ self.list = async_to_raw_response_wrapper(
+ teams.list,
+ )
+
+
+class TeamsResourceWithStreamingResponse:
+ def __init__(self, teams: TeamsResource) -> None:
+ self._teams = teams
+
+ self.list = to_streamed_response_wrapper(
+ teams.list,
+ )
+
+
+class AsyncTeamsResourceWithStreamingResponse:
+ def __init__(self, teams: AsyncTeamsResource) -> None:
+ self._teams = teams
+
+ self.list = async_to_streamed_response_wrapper(
+ teams.list,
+ )
diff --git a/src/resources/themes.py b/src/resources/themes.py
new file mode 100644
index 0000000..3cefa68
--- /dev/null
+++ b/src/resources/themes.py
@@ -0,0 +1,436 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.theme_list_response import ThemeListResponse
+from ..types.theme_create_response import ThemeCreateResponse
+from ..types import theme_create_params
+from ..types.theme_update_response import ThemeUpdateResponse
+from ..types import theme_update_params
+from ..types.theme_replace_document_response import ThemeReplaceDocumentResponse
+from ..types import theme_replace_document_params
+from ..types.theme_delete_response import ThemeDeleteResponse
+from ..types.theme_retrieve_response import ThemeRetrieveResponse
+
+__all__ = ["ThemesResource", "AsyncThemesResource"]
+
+
+class ThemesResource(SyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> ThemesResourceWithRawResponse:
+ return ThemesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ThemesResourceWithStreamingResponse:
+ return ThemesResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ThemeListResponse:
+ """List all team themes."""
+ return self._get(
+ "/v1/themes",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=ThemeListResponse,
+ )
+
+ def create(
+ self,
+ *,
+ name: str,
+ description: str | Omit = omit,
+ slug: str,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeCreateResponse:
+ """Create a team theme."""
+ return self._post(
+ "/v1/themes",
+ body=maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ "slug": slug,
+ "document": document,
+ },
+ theme_create_params.ThemeCreateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeCreateResponse,
+ )
+
+ def update(
+ self,
+ slug: str,
+ *,
+ name: str | Omit = omit,
+ description: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeUpdateResponse:
+ """Update theme metadata."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._patch(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ body=maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ },
+ theme_update_params.ThemeUpdateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeUpdateResponse,
+ )
+
+ def replace_document(
+ self,
+ slug: str,
+ *,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeReplaceDocumentResponse:
+ """Replace the theme document."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._put(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ body=maybe_transform(
+ {"document": document},
+ theme_replace_document_params.ThemeReplaceDocumentParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeReplaceDocumentResponse,
+ )
+
+ def delete(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeDeleteResponse:
+ """Delete a theme by slug."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._delete(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeDeleteResponse,
+ )
+
+ def retrieve(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ThemeRetrieveResponse:
+ """Get the theme document by slug."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return self._get(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=ThemeRetrieveResponse,
+ )
+
+
+class AsyncThemesResource(AsyncAPIResource):
+
+ @cached_property
+ def with_raw_response(self) -> AsyncThemesResourceWithRawResponse:
+ return AsyncThemesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncThemesResourceWithStreamingResponse:
+ return AsyncThemesResourceWithStreamingResponse(self)
+
+ async def list(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ThemeListResponse:
+ """List all team themes."""
+ return await self._get(
+ "/v1/themes",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=ThemeListResponse,
+ )
+
+ async def create(
+ self,
+ *,
+ name: str,
+ description: str | Omit = omit,
+ slug: str,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeCreateResponse:
+ """Create a team theme."""
+ return await self._post(
+ "/v1/themes",
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ "slug": slug,
+ "document": document,
+ },
+ theme_create_params.ThemeCreateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeCreateResponse,
+ )
+
+ async def update(
+ self,
+ slug: str,
+ *,
+ name: str | Omit = omit,
+ description: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeUpdateResponse:
+ """Update theme metadata."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._patch(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ },
+ theme_update_params.ThemeUpdateParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeUpdateResponse,
+ )
+
+ async def replace_document(
+ self,
+ slug: str,
+ *,
+ document: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeReplaceDocumentResponse:
+ """Replace the theme document."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._put(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ body=await async_maybe_transform(
+ {"document": document},
+ theme_replace_document_params.ThemeReplaceDocumentParams,
+ ),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeReplaceDocumentResponse,
+ )
+
+ async def delete(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> ThemeDeleteResponse:
+ """Delete a theme by slug."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._delete(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout, idempotency_key=idempotency_key),
+ cast_to=ThemeDeleteResponse,
+ )
+
+ async def retrieve(
+ self,
+ slug: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ThemeRetrieveResponse:
+ """Get the theme document by slug."""
+ if not slug:
+ raise ValueError(f"Expected a non-empty value for `slug` but received {slug!r}")
+ return await self._get(
+ path_template("/v1/themes/{slug}", **{"slug": slug}),
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout),
+ cast_to=ThemeRetrieveResponse,
+ )
+
+
+class ThemesResourceWithRawResponse:
+ def __init__(self, themes: ThemesResource) -> None:
+ self._themes = themes
+
+ self.list = to_raw_response_wrapper(
+ themes.list,
+ )
+ self.create = to_raw_response_wrapper(
+ themes.create,
+ )
+ self.update = to_raw_response_wrapper(
+ themes.update,
+ )
+ self.replace_document = to_raw_response_wrapper(
+ themes.replace_document,
+ )
+ self.delete = to_raw_response_wrapper(
+ themes.delete,
+ )
+ self.retrieve = to_raw_response_wrapper(
+ themes.retrieve,
+ )
+
+
+class AsyncThemesResourceWithRawResponse:
+ def __init__(self, themes: AsyncThemesResource) -> None:
+ self._themes = themes
+
+ self.list = async_to_raw_response_wrapper(
+ themes.list,
+ )
+ self.create = async_to_raw_response_wrapper(
+ themes.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ themes.update,
+ )
+ self.replace_document = async_to_raw_response_wrapper(
+ themes.replace_document,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ themes.delete,
+ )
+ self.retrieve = async_to_raw_response_wrapper(
+ themes.retrieve,
+ )
+
+
+class ThemesResourceWithStreamingResponse:
+ def __init__(self, themes: ThemesResource) -> None:
+ self._themes = themes
+
+ self.list = to_streamed_response_wrapper(
+ themes.list,
+ )
+ self.create = to_streamed_response_wrapper(
+ themes.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ themes.update,
+ )
+ self.replace_document = to_streamed_response_wrapper(
+ themes.replace_document,
+ )
+ self.delete = to_streamed_response_wrapper(
+ themes.delete,
+ )
+ self.retrieve = to_streamed_response_wrapper(
+ themes.retrieve,
+ )
+
+
+class AsyncThemesResourceWithStreamingResponse:
+ def __init__(self, themes: AsyncThemesResource) -> None:
+ self._themes = themes
+
+ self.list = async_to_streamed_response_wrapper(
+ themes.list,
+ )
+ self.create = async_to_streamed_response_wrapper(
+ themes.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ themes.update,
+ )
+ self.replace_document = async_to_streamed_response_wrapper(
+ themes.replace_document,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ themes.delete,
+ )
+ self.retrieve = async_to_streamed_response_wrapper(
+ themes.retrieve,
+ )
diff --git a/src/types/_400.py b/src/types/_400.py
new file mode 100644
index 0000000..d2a35a0
--- /dev/null
+++ b/src/types/_400.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["_400"]
+
+
+class _400(BaseModel):
+
+ message: str
+
+ code: str
diff --git a/src/types/_401.py b/src/types/_401.py
new file mode 100644
index 0000000..1d7e2e3
--- /dev/null
+++ b/src/types/_401.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["_401"]
+
+
+class _401(BaseModel):
+
+ message: str
+
+ code: str
diff --git a/src/types/_403.py b/src/types/_403.py
new file mode 100644
index 0000000..80cf160
--- /dev/null
+++ b/src/types/_403.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["_403"]
+
+
+class _403(BaseModel):
+
+ message: str
+
+ code: str
diff --git a/src/types/_404.py b/src/types/_404.py
new file mode 100644
index 0000000..40cc635
--- /dev/null
+++ b/src/types/_404.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["_404"]
+
+
+class _404(BaseModel):
+
+ message: str
+
+ code: str
diff --git a/src/types/_422.py b/src/types/_422.py
new file mode 100644
index 0000000..b3191c8
--- /dev/null
+++ b/src/types/_422.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["_422"]
+
+
+class _422(BaseModel):
+
+ message: str
+
+ code: str
diff --git a/src/types/_500.py b/src/types/_500.py
new file mode 100644
index 0000000..0888545
--- /dev/null
+++ b/src/types/_500.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["_500"]
+
+
+class _500(BaseModel):
+
+ message: str
+
+ code: str
diff --git a/src/types/__init__.py b/src/types/__init__.py
new file mode 100644
index 0000000..2f3be9d
--- /dev/null
+++ b/src/types/__init__.py
@@ -0,0 +1,96 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from ._400 import _400 as _400
+from ._401 import _401 as _401
+from ._403 import _403 as _403
+from ._404 import _404 as _404
+from ._422 import _422 as _422
+from ._500 import _500 as _500
+from .api_document import ApiDocument as ApiDocument
+from .nanoid import Nanoid as Nanoid
+from .version import Version as Version
+from .slug import Slug as Slug
+from .namespace import Namespace as Namespace
+from .managed_doc_version import ManagedDocVersion as ManagedDocVersion
+from .method import Method as Method
+from .access_group import AccessGroup as AccessGroup
+from .schema import Schema as Schema
+from .managed_schema_version import ManagedSchemaVersion as ManagedSchemaVersion
+from .timestamp import Timestamp as Timestamp
+from .uid import Uid as Uid
+from .login_portal_email import LoginPortalEmail as LoginPortalEmail
+from .login_portal_page import LoginPortalPage as LoginPortalPage
+from .login_portal import LoginPortal as LoginPortal
+from .rule import Rule as Rule
+from .theme import Theme as Theme
+from .team import Team as Team
+from .team_name import TeamName as TeamName
+from .team_image import TeamImage as TeamImage
+from .github_project import GithubProject as GithubProject
+from .active_deployment import ActiveDeployment as ActiveDeployment
+from .github_project_repository import GithubProjectRepository as GithubProjectRepository
+from .email import Email as Email
+from .team_summary import TeamSummary as TeamSummary
+from .user import User as User
+from .registry_list_all_api_documents_response import RegistryListAllApiDocumentsResponse as RegistryListAllApiDocumentsResponse
+from .registry_list_api_documents_response import RegistryListApiDocumentsResponse as RegistryListApiDocumentsResponse
+from .registry_create_api_document_response import RegistryCreateApiDocumentResponse as RegistryCreateApiDocumentResponse
+from .registry_create_api_document_params import RegistryCreateApiDocumentParams as RegistryCreateApiDocumentParams
+from .registry_update_api_document_response import RegistryUpdateApiDocumentResponse as RegistryUpdateApiDocumentResponse
+from .registry_update_api_document_params import RegistryUpdateApiDocumentParams as RegistryUpdateApiDocumentParams
+from .registry_delete_api_document_response import RegistryDeleteApiDocumentResponse as RegistryDeleteApiDocumentResponse
+from .registry_retrieve_api_document_version_response import RegistryRetrieveApiDocumentVersionResponse as RegistryRetrieveApiDocumentVersionResponse
+from .registry_update_api_document_version_response import RegistryUpdateApiDocumentVersionResponse as RegistryUpdateApiDocumentVersionResponse
+from .registry_update_api_document_version_params import RegistryUpdateApiDocumentVersionParams as RegistryUpdateApiDocumentVersionParams
+from .registry_delete_api_document_version_response import RegistryDeleteApiDocumentVersionResponse as RegistryDeleteApiDocumentVersionResponse
+from .registry_list_api_document_version_metadata_response import RegistryListApiDocumentVersionMetadataResponse as RegistryListApiDocumentVersionMetadataResponse
+from .registry_create_api_document_version_response import RegistryCreateApiDocumentVersionResponse as RegistryCreateApiDocumentVersionResponse
+from .registry_create_api_document_version_params import RegistryCreateApiDocumentVersionParams as RegistryCreateApiDocumentVersionParams
+from .registry_create_api_document_access_group_response import RegistryCreateApiDocumentAccessGroupResponse as RegistryCreateApiDocumentAccessGroupResponse
+from .registry_create_api_document_access_group_params import RegistryCreateApiDocumentAccessGroupParams as RegistryCreateApiDocumentAccessGroupParams
+from .registry_delete_api_document_access_group_response import RegistryDeleteApiDocumentAccessGroupResponse as RegistryDeleteApiDocumentAccessGroupResponse
+from .registry_delete_api_document_access_group_params import RegistryDeleteApiDocumentAccessGroupParams as RegistryDeleteApiDocumentAccessGroupParams
+from .schema_list_response import SchemaListResponse as SchemaListResponse
+from .schema_create_response import SchemaCreateResponse as SchemaCreateResponse
+from .schema_create_params import SchemaCreateParams as SchemaCreateParams
+from .schema_update_response import SchemaUpdateResponse as SchemaUpdateResponse
+from .schema_update_params import SchemaUpdateParams as SchemaUpdateParams
+from .schema_delete_response import SchemaDeleteResponse as SchemaDeleteResponse
+from .login_portal_retrieve_response import LoginPortalRetrieveResponse as LoginPortalRetrieveResponse
+from .login_portal_update_response import LoginPortalUpdateResponse as LoginPortalUpdateResponse
+from .login_portal_update_params import LoginPortalUpdateParams as LoginPortalUpdateParams
+from .login_portal_delete_response import LoginPortalDeleteResponse as LoginPortalDeleteResponse
+from .login_portal_create_response import LoginPortalCreateResponse as LoginPortalCreateResponse
+from .login_portal_create_params import LoginPortalCreateParams as LoginPortalCreateParams
+from .login_portal_list_response import LoginPortalListResponse as LoginPortalListResponse
+from .rule_list_rulesets_response import RuleListRulesetsResponse as RuleListRulesetsResponse
+from .rule_create_ruleset_response import RuleCreateRulesetResponse as RuleCreateRulesetResponse
+from .rule_create_ruleset_params import RuleCreateRulesetParams as RuleCreateRulesetParams
+from .rule_update_ruleset_response import RuleUpdateRulesetResponse as RuleUpdateRulesetResponse
+from .rule_update_ruleset_params import RuleUpdateRulesetParams as RuleUpdateRulesetParams
+from .rule_delete_ruleset_response import RuleDeleteRulesetResponse as RuleDeleteRulesetResponse
+from .rule_retrieve_ruleset_document_response import RuleRetrieveRulesetDocumentResponse as RuleRetrieveRulesetDocumentResponse
+from .rule_create_ruleset_access_group_response import RuleCreateRulesetAccessGroupResponse as RuleCreateRulesetAccessGroupResponse
+from .rule_create_ruleset_access_group_params import RuleCreateRulesetAccessGroupParams as RuleCreateRulesetAccessGroupParams
+from .rule_delete_ruleset_access_group_response import RuleDeleteRulesetAccessGroupResponse as RuleDeleteRulesetAccessGroupResponse
+from .rule_delete_ruleset_access_group_params import RuleDeleteRulesetAccessGroupParams as RuleDeleteRulesetAccessGroupParams
+from .theme_list_response import ThemeListResponse as ThemeListResponse
+from .theme_create_response import ThemeCreateResponse as ThemeCreateResponse
+from .theme_create_params import ThemeCreateParams as ThemeCreateParams
+from .theme_update_response import ThemeUpdateResponse as ThemeUpdateResponse
+from .theme_update_params import ThemeUpdateParams as ThemeUpdateParams
+from .theme_replace_document_response import ThemeReplaceDocumentResponse as ThemeReplaceDocumentResponse
+from .theme_replace_document_params import ThemeReplaceDocumentParams as ThemeReplaceDocumentParams
+from .theme_delete_response import ThemeDeleteResponse as ThemeDeleteResponse
+from .theme_retrieve_response import ThemeRetrieveResponse as ThemeRetrieveResponse
+from .team_list_response import TeamListResponse as TeamListResponse
+from .scalar_doc_list_guides_response import ScalarDocListGuidesResponse as ScalarDocListGuidesResponse
+from .scalar_doc_create_guide_response import ScalarDocCreateGuideResponse as ScalarDocCreateGuideResponse
+from .scalar_doc_create_guide_params import ScalarDocCreateGuideParams as ScalarDocCreateGuideParams
+from .scalar_doc_publish_guide_response import ScalarDocPublishGuideResponse as ScalarDocPublishGuideResponse
+from .namespace_list_response import NamespaceListResponse as NamespaceListResponse
+from .authentication_exchange_personal_token_response import AuthenticationExchangePersonalTokenResponse as AuthenticationExchangePersonalTokenResponse
+from .authentication_exchange_personal_token_params import AuthenticationExchangePersonalTokenParams as AuthenticationExchangePersonalTokenParams
+from .authentication_list_current_user_response import AuthenticationListCurrentUserResponse as AuthenticationListCurrentUserResponse
diff --git a/src/types/access_group.py b/src/types/access_group.py
new file mode 100644
index 0000000..ed3f7dc
--- /dev/null
+++ b/src/types/access_group.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .slug import Slug
+
+__all__ = ["AccessGroup"]
+
+
+class AccessGroup(BaseModel):
+
+ accessGroupSlug: Slug
diff --git a/src/types/active_deployment.py b/src/types/active_deployment.py
new file mode 100644
index 0000000..e01a470
--- /dev/null
+++ b/src/types/active_deployment.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .timestamp import Timestamp
+
+__all__ = ["ActiveDeployment"]
+
+
+class ActiveDeployment(BaseModel):
+
+ uid: str
+
+ domain: str
+
+ publishedAt: Timestamp
diff --git a/src/types/api_document.py b/src/types/api_document.py
new file mode 100644
index 0000000..70de5b2
--- /dev/null
+++ b/src/types/api_document.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import List
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .version import Version
+from .slug import Slug
+from .namespace import Namespace
+from .managed_doc_version import ManagedDocVersion
+
+__all__ = ["ApiDocument"]
+
+
+class ApiDocument(BaseModel):
+
+ uid: Nanoid
+
+ version: Version
+
+ title: str
+
+ slug: Slug
+
+ description: str
+
+ namespace: Namespace
+
+ isPrivate: bool
+
+ tags: str
+
+ versions: List[ManagedDocVersion]
diff --git a/src/types/authentication_exchange_personal_token_params.py b/src/types/authentication_exchange_personal_token_params.py
new file mode 100644
index 0000000..1cb5507
--- /dev/null
+++ b/src/types/authentication_exchange_personal_token_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["AuthenticationExchangePersonalTokenParams"]
+
+
+class AuthenticationExchangePersonalTokenParams(TypedDict, total=False):
+
+ personal_token: Required[Annotated[str, PropertyInfo(alias="personalToken")]]
diff --git a/src/types/authentication_exchange_personal_token_response.py b/src/types/authentication_exchange_personal_token_response.py
new file mode 100644
index 0000000..aa3b416
--- /dev/null
+++ b/src/types/authentication_exchange_personal_token_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["AuthenticationExchangePersonalTokenResponse"]
+
+AuthenticationExchangePersonalTokenResponse: TypeAlias = object
diff --git a/src/types/authentication_list_current_user_response.py b/src/types/authentication_list_current_user_response.py
new file mode 100644
index 0000000..db44af3
--- /dev/null
+++ b/src/types/authentication_list_current_user_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .user import User
+
+__all__ = ["AuthenticationListCurrentUserResponse"]
+
+AuthenticationListCurrentUserResponse: TypeAlias = User
diff --git a/src/types/email.py b/src/types/email.py
new file mode 100644
index 0000000..716d068
--- /dev/null
+++ b/src/types/email.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["Email"]
+
+Email: TypeAlias = str
diff --git a/src/types/github_project.py b/src/types/github_project.py
new file mode 100644
index 0000000..cef63ad
--- /dev/null
+++ b/src/types/github_project.py
@@ -0,0 +1,49 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import Optional, Union
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .timestamp import Timestamp
+from .active_deployment import ActiveDeployment
+from .slug import Slug
+from .github_project_repository import GithubProjectRepository
+
+__all__ = ["GithubProject"]
+
+
+class GithubProject(BaseModel):
+
+ uid: Nanoid
+
+ createdAt: Timestamp
+
+ updatedAt: Timestamp
+
+ name: str
+
+ activeDeployment: Optional[Union[ActiveDeployment, None]] = None
+
+ lastPublished: Optional[Union[Timestamp, None]] = None
+
+ lastPublishedUid: Optional[Union[str, None]] = None
+
+ loginPortalUid: str
+
+ activeThemeId: str
+
+ typesenseId: Optional[float] = None
+
+ isPrivate: bool
+
+ agentEnabled: bool
+
+ accessGroups: str
+
+ slug: Slug
+
+ publishStatus: str
+
+ publishMessage: str
+
+ repository: Optional[Union[GithubProjectRepository, None]] = None
diff --git a/src/types/github_project_repository.py b/src/types/github_project_repository.py
new file mode 100644
index 0000000..be96f6f
--- /dev/null
+++ b/src/types/github_project_repository.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["GithubProjectRepository"]
+
+
+class GithubProjectRepository(BaseModel):
+
+ linkedBy: str
+
+ id: float
+
+ name: str
+
+ configPath: str
+
+ branch: str
+
+ publishOnMerge: bool
+
+ publishPreviews: bool
+
+ prComments: bool
+
+ expired: bool
diff --git a/src/types/login_portal.py b/src/types/login_portal.py
new file mode 100644
index 0000000..997cb1e
--- /dev/null
+++ b/src/types/login_portal.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .slug import Slug
+
+__all__ = ["LoginPortal"]
+
+
+class LoginPortal(BaseModel):
+
+ uid: Nanoid
+
+ title: str
+
+ slug: Slug
diff --git a/src/types/login_portal_create_params.py b/src/types/login_portal_create_params.py
new file mode 100644
index 0000000..e127d5e
--- /dev/null
+++ b/src/types/login_portal_create_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["LoginPortalCreateParams"]
+
+
+class LoginPortalCreateParams(TypedDict, total=False):
+
+ title: Required[str]
+
+ slug: Required[str]
+
+ email: Required[object]
+
+ page: Required[object]
diff --git a/src/types/login_portal_create_response.py b/src/types/login_portal_create_response.py
new file mode 100644
index 0000000..7c2ae74
--- /dev/null
+++ b/src/types/login_portal_create_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .uid import Uid
+
+__all__ = ["LoginPortalCreateResponse"]
+
+LoginPortalCreateResponse: TypeAlias = Uid
diff --git a/src/types/login_portal_delete_response.py b/src/types/login_portal_delete_response.py
new file mode 100644
index 0000000..a7446a7
--- /dev/null
+++ b/src/types/login_portal_delete_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["LoginPortalDeleteResponse"]
+
+LoginPortalDeleteResponse: TypeAlias = None
diff --git a/src/types/login_portal_email.py b/src/types/login_portal_email.py
new file mode 100644
index 0000000..cd89f91
--- /dev/null
+++ b/src/types/login_portal_email.py
@@ -0,0 +1,31 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["LoginPortalEmail"]
+
+
+class LoginPortalEmail(BaseModel):
+
+ logo: str
+
+ logoSize: str
+
+ buttonText: str
+
+ message: str
+
+ title: str
+
+ mainColor: str
+
+ mainBackground: str
+
+ cardColor: str
+
+ cardBackground: str
+
+ buttonColor: str
+
+ buttonBackground: str
diff --git a/src/types/login_portal_list_response.py b/src/types/login_portal_list_response.py
new file mode 100644
index 0000000..b7ed0ca
--- /dev/null
+++ b/src/types/login_portal_list_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .login_portal import LoginPortal
+
+__all__ = ["LoginPortalListResponse"]
+
+LoginPortalListResponse: TypeAlias = List[LoginPortal]
diff --git a/src/types/login_portal_page.py b/src/types/login_portal_page.py
new file mode 100644
index 0000000..803f48e
--- /dev/null
+++ b/src/types/login_portal_page.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+
+__all__ = ["LoginPortalPage"]
+
+
+class LoginPortalPage(BaseModel):
+
+ title: str
+
+ description: str
+
+ head: str
+
+ script: str
+
+ theme: str
+
+ companyName: str
+
+ logo: str
+
+ logoURL: str
+
+ favicon: str
+
+ termsLink: str
+
+ privacyLink: str
+
+ formTitle: str
+
+ formDescription: str
+
+ formImage: str
diff --git a/src/types/login_portal_retrieve_response.py b/src/types/login_portal_retrieve_response.py
new file mode 100644
index 0000000..9c35326
--- /dev/null
+++ b/src/types/login_portal_retrieve_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["LoginPortalRetrieveResponse"]
+
+LoginPortalRetrieveResponse: TypeAlias = object
diff --git a/src/types/login_portal_update_params.py b/src/types/login_portal_update_params.py
new file mode 100644
index 0000000..8832ac2
--- /dev/null
+++ b/src/types/login_portal_update_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["LoginPortalUpdateParams"]
+
+
+class LoginPortalUpdateParams(TypedDict, total=False):
+
+ title: str
diff --git a/src/types/login_portal_update_response.py b/src/types/login_portal_update_response.py
new file mode 100644
index 0000000..7a5b913
--- /dev/null
+++ b/src/types/login_portal_update_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["LoginPortalUpdateResponse"]
+
+LoginPortalUpdateResponse: TypeAlias = None
diff --git a/src/types/managed_doc_version.py b/src/types/managed_doc_version.py
new file mode 100644
index 0000000..0bb4345
--- /dev/null
+++ b/src/types/managed_doc_version.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import List, Optional, Union
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .version import Version
+
+__all__ = ["ManagedDocVersion"]
+
+
+class ManagedDocVersion(BaseModel):
+
+ uid: Nanoid
+
+ createdAt: float
+
+ version: Version
+
+ upgraded: bool
+
+ embedStatus: Optional[Union[Literal["complete", "failed"], None]] = None
+
+ tags: List[str]
+
+ tools: Optional[List[object]] = None
+
+ yamlSha: Optional[str] = None
+
+ jsonSha: Optional[str] = None
+
+ versionSha: Optional[str] = None
diff --git a/src/types/managed_schema_version.py b/src/types/managed_schema_version.py
new file mode 100644
index 0000000..45cf82f
--- /dev/null
+++ b/src/types/managed_schema_version.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .timestamp import Timestamp
+from .version import Version
+
+__all__ = ["ManagedSchemaVersion"]
+
+
+class ManagedSchemaVersion(BaseModel):
+
+ uid: Nanoid
+
+ createdAt: Timestamp
+
+ updatedAt: Timestamp
+
+ version: Version
diff --git a/src/types/method.py b/src/types/method.py
new file mode 100644
index 0000000..bbfeba4
--- /dev/null
+++ b/src/types/method.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["Method"]
+
+Method: TypeAlias = Literal["delete", "get", "head", "options", "patch", "post", "put", "trace"]
diff --git a/src/types/namespace.py b/src/types/namespace.py
new file mode 100644
index 0000000..a6b6c79
--- /dev/null
+++ b/src/types/namespace.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["Namespace"]
+
+Namespace: TypeAlias = str
diff --git a/src/types/namespace_list_response.py b/src/types/namespace_list_response.py
new file mode 100644
index 0000000..6b2ca47
--- /dev/null
+++ b/src/types/namespace_list_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+
+__all__ = ["NamespaceListResponse"]
+
+NamespaceListResponse: TypeAlias = List[str]
diff --git a/src/types/nanoid.py b/src/types/nanoid.py
new file mode 100644
index 0000000..73e5bac
--- /dev/null
+++ b/src/types/nanoid.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["Nanoid"]
+
+Nanoid: TypeAlias = str
diff --git a/src/types/registry_create_api_document_access_group_params.py b/src/types/registry_create_api_document_access_group_params.py
new file mode 100644
index 0000000..7be5ced
--- /dev/null
+++ b/src/types/registry_create_api_document_access_group_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RegistryCreateApiDocumentAccessGroupParams"]
+
+
+class RegistryCreateApiDocumentAccessGroupParams(TypedDict, total=False):
+
+ access_group_slug: Required[Annotated[str, PropertyInfo(alias="accessGroupSlug")]]
diff --git a/src/types/registry_create_api_document_access_group_response.py b/src/types/registry_create_api_document_access_group_response.py
new file mode 100644
index 0000000..7a73e57
--- /dev/null
+++ b/src/types/registry_create_api_document_access_group_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryCreateApiDocumentAccessGroupResponse"]
+
+RegistryCreateApiDocumentAccessGroupResponse: TypeAlias = None
diff --git a/src/types/registry_create_api_document_params.py b/src/types/registry_create_api_document_params.py
new file mode 100644
index 0000000..4dedfa6
--- /dev/null
+++ b/src/types/registry_create_api_document_params.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RegistryCreateApiDocumentParams"]
+
+
+class RegistryCreateApiDocumentParams(TypedDict, total=False):
+
+ title: Required[str]
+
+ description: str
+
+ version: Required[str]
+
+ slug: Required[str]
+
+ ruleset: str
+
+ is_private: Annotated[bool, PropertyInfo(alias="isPrivate")]
+
+ document: Required[str]
diff --git a/src/types/registry_create_api_document_response.py b/src/types/registry_create_api_document_response.py
new file mode 100644
index 0000000..e13c4dc
--- /dev/null
+++ b/src/types/registry_create_api_document_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryCreateApiDocumentResponse"]
+
+RegistryCreateApiDocumentResponse: TypeAlias = object
diff --git a/src/types/registry_create_api_document_version_params.py b/src/types/registry_create_api_document_version_params.py
new file mode 100644
index 0000000..e135774
--- /dev/null
+++ b/src/types/registry_create_api_document_version_params.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RegistryCreateApiDocumentVersionParams"]
+
+
+class RegistryCreateApiDocumentVersionParams(TypedDict, total=False):
+
+ version: Required[str]
+
+ document: Required[str]
+
+ force: bool
+
+ last_known_version_sha: Annotated[str, PropertyInfo(alias="lastKnownVersionSha")]
diff --git a/src/types/registry_create_api_document_version_response.py b/src/types/registry_create_api_document_version_response.py
new file mode 100644
index 0000000..9692d5a
--- /dev/null
+++ b/src/types/registry_create_api_document_version_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .managed_doc_version import ManagedDocVersion
+
+__all__ = ["RegistryCreateApiDocumentVersionResponse"]
+
+RegistryCreateApiDocumentVersionResponse: TypeAlias = ManagedDocVersion
diff --git a/src/types/registry_delete_api_document_access_group_params.py b/src/types/registry_delete_api_document_access_group_params.py
new file mode 100644
index 0000000..719f324
--- /dev/null
+++ b/src/types/registry_delete_api_document_access_group_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RegistryDeleteApiDocumentAccessGroupParams"]
+
+
+class RegistryDeleteApiDocumentAccessGroupParams(TypedDict, total=False):
+
+ access_group_slug: Required[Annotated[str, PropertyInfo(alias="accessGroupSlug")]]
diff --git a/src/types/registry_delete_api_document_access_group_response.py b/src/types/registry_delete_api_document_access_group_response.py
new file mode 100644
index 0000000..ad45c5b
--- /dev/null
+++ b/src/types/registry_delete_api_document_access_group_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryDeleteApiDocumentAccessGroupResponse"]
+
+RegistryDeleteApiDocumentAccessGroupResponse: TypeAlias = None
diff --git a/src/types/registry_delete_api_document_response.py b/src/types/registry_delete_api_document_response.py
new file mode 100644
index 0000000..c3e26b4
--- /dev/null
+++ b/src/types/registry_delete_api_document_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryDeleteApiDocumentResponse"]
+
+RegistryDeleteApiDocumentResponse: TypeAlias = None
diff --git a/src/types/registry_delete_api_document_version_response.py b/src/types/registry_delete_api_document_version_response.py
new file mode 100644
index 0000000..39e1f37
--- /dev/null
+++ b/src/types/registry_delete_api_document_version_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryDeleteApiDocumentVersionResponse"]
+
+RegistryDeleteApiDocumentVersionResponse: TypeAlias = None
diff --git a/src/types/registry_list_all_api_documents_response.py b/src/types/registry_list_all_api_documents_response.py
new file mode 100644
index 0000000..9552301
--- /dev/null
+++ b/src/types/registry_list_all_api_documents_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .api_document import ApiDocument
+
+__all__ = ["RegistryListAllApiDocumentsResponse"]
+
+RegistryListAllApiDocumentsResponse: TypeAlias = List[ApiDocument]
diff --git a/src/types/registry_list_api_document_version_metadata_response.py b/src/types/registry_list_api_document_version_metadata_response.py
new file mode 100644
index 0000000..0ecf442
--- /dev/null
+++ b/src/types/registry_list_api_document_version_metadata_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .managed_doc_version import ManagedDocVersion
+
+__all__ = ["RegistryListApiDocumentVersionMetadataResponse"]
+
+RegistryListApiDocumentVersionMetadataResponse: TypeAlias = ManagedDocVersion
diff --git a/src/types/registry_list_api_documents_response.py b/src/types/registry_list_api_documents_response.py
new file mode 100644
index 0000000..85fbbbf
--- /dev/null
+++ b/src/types/registry_list_api_documents_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .api_document import ApiDocument
+
+__all__ = ["RegistryListApiDocumentsResponse"]
+
+RegistryListApiDocumentsResponse: TypeAlias = List[ApiDocument]
diff --git a/src/types/registry_retrieve_api_document_version_response.py b/src/types/registry_retrieve_api_document_version_response.py
new file mode 100644
index 0000000..5113289
--- /dev/null
+++ b/src/types/registry_retrieve_api_document_version_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryRetrieveApiDocumentVersionResponse"]
+
+RegistryRetrieveApiDocumentVersionResponse: TypeAlias = str
diff --git a/src/types/registry_update_api_document_params.py b/src/types/registry_update_api_document_params.py
new file mode 100644
index 0000000..a48ede5
--- /dev/null
+++ b/src/types/registry_update_api_document_params.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RegistryUpdateApiDocumentParams"]
+
+
+class RegistryUpdateApiDocumentParams(TypedDict, total=False):
+
+ title: str
+
+ description: str
+
+ is_private: Annotated[bool, PropertyInfo(alias="isPrivate")]
+
+ ruleset: str
diff --git a/src/types/registry_update_api_document_response.py b/src/types/registry_update_api_document_response.py
new file mode 100644
index 0000000..5bfd97e
--- /dev/null
+++ b/src/types/registry_update_api_document_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryUpdateApiDocumentResponse"]
+
+RegistryUpdateApiDocumentResponse: TypeAlias = None
diff --git a/src/types/registry_update_api_document_version_params.py b/src/types/registry_update_api_document_version_params.py
new file mode 100644
index 0000000..b8d3307
--- /dev/null
+++ b/src/types/registry_update_api_document_version_params.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RegistryUpdateApiDocumentVersionParams"]
+
+
+class RegistryUpdateApiDocumentVersionParams(TypedDict, total=False):
+
+ document: Required[str]
+
+ last_known_version_sha: Annotated[str, PropertyInfo(alias="lastKnownVersionSha")]
diff --git a/src/types/registry_update_api_document_version_response.py b/src/types/registry_update_api_document_version_response.py
new file mode 100644
index 0000000..1a39b7a
--- /dev/null
+++ b/src/types/registry_update_api_document_version_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RegistryUpdateApiDocumentVersionResponse"]
+
+RegistryUpdateApiDocumentVersionResponse: TypeAlias = object
diff --git a/src/types/rule.py b/src/types/rule.py
new file mode 100644
index 0000000..6f4d2fd
--- /dev/null
+++ b/src/types/rule.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .slug import Slug
+from .namespace import Namespace
+
+__all__ = ["Rule"]
+
+
+class Rule(BaseModel):
+
+ uid: Nanoid
+
+ title: str
+
+ description: str
+
+ slug: Slug
+
+ namespace: Namespace
+
+ isPrivate: bool
diff --git a/src/types/rule_create_ruleset_access_group_params.py b/src/types/rule_create_ruleset_access_group_params.py
new file mode 100644
index 0000000..08d8023
--- /dev/null
+++ b/src/types/rule_create_ruleset_access_group_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RuleCreateRulesetAccessGroupParams"]
+
+
+class RuleCreateRulesetAccessGroupParams(TypedDict, total=False):
+
+ access_group_slug: Required[Annotated[str, PropertyInfo(alias="accessGroupSlug")]]
diff --git a/src/types/rule_create_ruleset_access_group_response.py b/src/types/rule_create_ruleset_access_group_response.py
new file mode 100644
index 0000000..2a60e6f
--- /dev/null
+++ b/src/types/rule_create_ruleset_access_group_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RuleCreateRulesetAccessGroupResponse"]
+
+RuleCreateRulesetAccessGroupResponse: TypeAlias = None
diff --git a/src/types/rule_create_ruleset_params.py b/src/types/rule_create_ruleset_params.py
new file mode 100644
index 0000000..7e70c5a
--- /dev/null
+++ b/src/types/rule_create_ruleset_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RuleCreateRulesetParams"]
+
+
+class RuleCreateRulesetParams(TypedDict, total=False):
+
+ title: Required[str]
+
+ description: str
+
+ slug: Required[str]
+
+ is_private: Annotated[bool, PropertyInfo(alias="isPrivate")]
+
+ document: Required[str]
diff --git a/src/types/rule_create_ruleset_response.py b/src/types/rule_create_ruleset_response.py
new file mode 100644
index 0000000..d829ec3
--- /dev/null
+++ b/src/types/rule_create_ruleset_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .uid import Uid
+
+__all__ = ["RuleCreateRulesetResponse"]
+
+RuleCreateRulesetResponse: TypeAlias = Uid
diff --git a/src/types/rule_delete_ruleset_access_group_params.py b/src/types/rule_delete_ruleset_access_group_params.py
new file mode 100644
index 0000000..502f63c
--- /dev/null
+++ b/src/types/rule_delete_ruleset_access_group_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RuleDeleteRulesetAccessGroupParams"]
+
+
+class RuleDeleteRulesetAccessGroupParams(TypedDict, total=False):
+
+ access_group_slug: Required[Annotated[str, PropertyInfo(alias="accessGroupSlug")]]
diff --git a/src/types/rule_delete_ruleset_access_group_response.py b/src/types/rule_delete_ruleset_access_group_response.py
new file mode 100644
index 0000000..8e6814f
--- /dev/null
+++ b/src/types/rule_delete_ruleset_access_group_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RuleDeleteRulesetAccessGroupResponse"]
+
+RuleDeleteRulesetAccessGroupResponse: TypeAlias = None
diff --git a/src/types/rule_delete_ruleset_response.py b/src/types/rule_delete_ruleset_response.py
new file mode 100644
index 0000000..0f7eacd
--- /dev/null
+++ b/src/types/rule_delete_ruleset_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RuleDeleteRulesetResponse"]
+
+RuleDeleteRulesetResponse: TypeAlias = None
diff --git a/src/types/rule_list_rulesets_response.py b/src/types/rule_list_rulesets_response.py
new file mode 100644
index 0000000..0ab5bac
--- /dev/null
+++ b/src/types/rule_list_rulesets_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .rule import Rule
+
+__all__ = ["RuleListRulesetsResponse"]
+
+RuleListRulesetsResponse: TypeAlias = List[Rule]
diff --git a/src/types/rule_retrieve_ruleset_document_response.py b/src/types/rule_retrieve_ruleset_document_response.py
new file mode 100644
index 0000000..14fa017
--- /dev/null
+++ b/src/types/rule_retrieve_ruleset_document_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RuleRetrieveRulesetDocumentResponse"]
+
+RuleRetrieveRulesetDocumentResponse: TypeAlias = str
diff --git a/src/types/rule_update_ruleset_params.py b/src/types/rule_update_ruleset_params.py
new file mode 100644
index 0000000..41b3811
--- /dev/null
+++ b/src/types/rule_update_ruleset_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["RuleUpdateRulesetParams"]
+
+
+class RuleUpdateRulesetParams(TypedDict, total=False):
+
+ namespace: str
+
+ slug: str
+
+ title: str
+
+ description: str
+
+ is_private: Annotated[bool, PropertyInfo(alias="isPrivate")]
diff --git a/src/types/rule_update_ruleset_response.py b/src/types/rule_update_ruleset_response.py
new file mode 100644
index 0000000..1b2a74d
--- /dev/null
+++ b/src/types/rule_update_ruleset_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["RuleUpdateRulesetResponse"]
+
+RuleUpdateRulesetResponse: TypeAlias = None
diff --git a/src/types/scalar_doc_create_guide_params.py b/src/types/scalar_doc_create_guide_params.py
new file mode 100644
index 0000000..38ca7e5
--- /dev/null
+++ b/src/types/scalar_doc_create_guide_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated, List
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["ScalarDocCreateGuideParams"]
+
+
+class ScalarDocCreateGuideParams(TypedDict, total=False):
+
+ name: Required[str]
+
+ slug: str
+
+ is_private: Required[Annotated[bool, PropertyInfo(alias="isPrivate")]]
+
+ allowed_users: Required[Annotated[List[str], PropertyInfo(alias="allowedUsers")]]
+
+ allowed_domains: Required[Annotated[List[str], PropertyInfo(alias="allowedDomains")]]
diff --git a/src/types/scalar_doc_create_guide_response.py b/src/types/scalar_doc_create_guide_response.py
new file mode 100644
index 0000000..4899376
--- /dev/null
+++ b/src/types/scalar_doc_create_guide_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["ScalarDocCreateGuideResponse"]
+
+ScalarDocCreateGuideResponse: TypeAlias = object
diff --git a/src/types/scalar_doc_list_guides_response.py b/src/types/scalar_doc_list_guides_response.py
new file mode 100644
index 0000000..82e4197
--- /dev/null
+++ b/src/types/scalar_doc_list_guides_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .github_project import GithubProject
+
+__all__ = ["ScalarDocListGuidesResponse"]
+
+ScalarDocListGuidesResponse: TypeAlias = List[GithubProject]
diff --git a/src/types/scalar_doc_publish_guide_response.py b/src/types/scalar_doc_publish_guide_response.py
new file mode 100644
index 0000000..1befb57
--- /dev/null
+++ b/src/types/scalar_doc_publish_guide_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["ScalarDocPublishGuideResponse"]
+
+ScalarDocPublishGuideResponse: TypeAlias = object
diff --git a/src/types/schema.py b/src/types/schema.py
new file mode 100644
index 0000000..fc9ca8e
--- /dev/null
+++ b/src/types/schema.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import List
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .slug import Slug
+from .namespace import Namespace
+from .managed_schema_version import ManagedSchemaVersion
+
+__all__ = ["Schema"]
+
+
+class Schema(BaseModel):
+
+ uid: Nanoid
+
+ title: str
+
+ description: str
+
+ slug: Slug
+
+ namespace: Namespace
+
+ isPrivate: bool
+
+ versions: List[ManagedSchemaVersion]
diff --git a/src/types/schema_create_params.py b/src/types/schema_create_params.py
new file mode 100644
index 0000000..dc95811
--- /dev/null
+++ b/src/types/schema_create_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["SchemaCreateParams"]
+
+
+class SchemaCreateParams(TypedDict, total=False):
+
+ title: Required[str]
+
+ description: str
+
+ version: Required[str]
+
+ slug: Required[str]
+
+ is_private: Annotated[bool, PropertyInfo(alias="isPrivate")]
+
+ document: Required[str]
diff --git a/src/types/schema_create_response.py b/src/types/schema_create_response.py
new file mode 100644
index 0000000..8e7792a
--- /dev/null
+++ b/src/types/schema_create_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .uid import Uid
+
+__all__ = ["SchemaCreateResponse"]
+
+SchemaCreateResponse: TypeAlias = Uid
diff --git a/src/types/schema_delete_response.py b/src/types/schema_delete_response.py
new file mode 100644
index 0000000..d1b662b
--- /dev/null
+++ b/src/types/schema_delete_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["SchemaDeleteResponse"]
+
+SchemaDeleteResponse: TypeAlias = None
diff --git a/src/types/schema_list_response.py b/src/types/schema_list_response.py
new file mode 100644
index 0000000..93ca662
--- /dev/null
+++ b/src/types/schema_list_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .schema import Schema
+
+__all__ = ["SchemaListResponse"]
+
+SchemaListResponse: TypeAlias = List[Schema]
diff --git a/src/types/schema_update_params.py b/src/types/schema_update_params.py
new file mode 100644
index 0000000..e4bac0f
--- /dev/null
+++ b/src/types/schema_update_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import TypedDict
+from .._utils import PropertyInfo
+
+__all__ = ["SchemaUpdateParams"]
+
+
+class SchemaUpdateParams(TypedDict, total=False):
+
+ title: str
+
+ description: str
+
+ is_private: Annotated[bool, PropertyInfo(alias="isPrivate")]
diff --git a/src/types/schema_update_response.py b/src/types/schema_update_response.py
new file mode 100644
index 0000000..8d20eeb
--- /dev/null
+++ b/src/types/schema_update_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["SchemaUpdateResponse"]
+
+SchemaUpdateResponse: TypeAlias = None
diff --git a/src/types/schemas/__init__.py b/src/types/schemas/__init__.py
new file mode 100644
index 0000000..640f96a
--- /dev/null
+++ b/src/types/schemas/__init__.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from .version_retrieve_schema_response import VersionRetrieveSchemaResponse as VersionRetrieveSchemaResponse
+from .version_delete_schema_response import VersionDeleteSchemaResponse as VersionDeleteSchemaResponse
+from .version_create_schema_response import VersionCreateSchemaResponse as VersionCreateSchemaResponse
+from .version_create_schema_params import VersionCreateSchemaParams as VersionCreateSchemaParams
+from .access_group_create_schema_response import AccessGroupCreateSchemaResponse as AccessGroupCreateSchemaResponse
+from .access_group_create_schema_params import AccessGroupCreateSchemaParams as AccessGroupCreateSchemaParams
+from .access_group_delete_schema_response import AccessGroupDeleteSchemaResponse as AccessGroupDeleteSchemaResponse
+from .access_group_delete_schema_params import AccessGroupDeleteSchemaParams as AccessGroupDeleteSchemaParams
diff --git a/src/types/schemas/access_group_create_schema_params.py b/src/types/schemas/access_group_create_schema_params.py
new file mode 100644
index 0000000..034b841
--- /dev/null
+++ b/src/types/schemas/access_group_create_schema_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from ..._utils import PropertyInfo
+
+__all__ = ["AccessGroupCreateSchemaParams"]
+
+
+class AccessGroupCreateSchemaParams(TypedDict, total=False):
+
+ access_group_slug: Required[Annotated[str, PropertyInfo(alias="accessGroupSlug")]]
diff --git a/src/types/schemas/access_group_create_schema_response.py b/src/types/schemas/access_group_create_schema_response.py
new file mode 100644
index 0000000..4a7bbc5
--- /dev/null
+++ b/src/types/schemas/access_group_create_schema_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["AccessGroupCreateSchemaResponse"]
+
+AccessGroupCreateSchemaResponse: TypeAlias = None
diff --git a/src/types/schemas/access_group_delete_schema_params.py b/src/types/schemas/access_group_delete_schema_params.py
new file mode 100644
index 0000000..c17eb49
--- /dev/null
+++ b/src/types/schemas/access_group_delete_schema_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import Annotated
+from typing_extensions import Required, TypedDict
+from ..._utils import PropertyInfo
+
+__all__ = ["AccessGroupDeleteSchemaParams"]
+
+
+class AccessGroupDeleteSchemaParams(TypedDict, total=False):
+
+ access_group_slug: Required[Annotated[str, PropertyInfo(alias="accessGroupSlug")]]
diff --git a/src/types/schemas/access_group_delete_schema_response.py b/src/types/schemas/access_group_delete_schema_response.py
new file mode 100644
index 0000000..2f95a9f
--- /dev/null
+++ b/src/types/schemas/access_group_delete_schema_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["AccessGroupDeleteSchemaResponse"]
+
+AccessGroupDeleteSchemaResponse: TypeAlias = None
diff --git a/src/types/schemas/version_create_schema_params.py b/src/types/schemas/version_create_schema_params.py
new file mode 100644
index 0000000..95a659e
--- /dev/null
+++ b/src/types/schemas/version_create_schema_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["VersionCreateSchemaParams"]
+
+
+class VersionCreateSchemaParams(TypedDict, total=False):
+
+ version: Required[str]
+
+ document: Required[str]
diff --git a/src/types/schemas/version_create_schema_response.py b/src/types/schemas/version_create_schema_response.py
new file mode 100644
index 0000000..88e7d40
--- /dev/null
+++ b/src/types/schemas/version_create_schema_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from ..uid import Uid
+
+__all__ = ["VersionCreateSchemaResponse"]
+
+VersionCreateSchemaResponse: TypeAlias = Uid
diff --git a/src/types/schemas/version_delete_schema_response.py b/src/types/schemas/version_delete_schema_response.py
new file mode 100644
index 0000000..25078d4
--- /dev/null
+++ b/src/types/schemas/version_delete_schema_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["VersionDeleteSchemaResponse"]
+
+VersionDeleteSchemaResponse: TypeAlias = None
diff --git a/src/types/schemas/version_retrieve_schema_response.py b/src/types/schemas/version_retrieve_schema_response.py
new file mode 100644
index 0000000..154cea5
--- /dev/null
+++ b/src/types/schemas/version_retrieve_schema_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["VersionRetrieveSchemaResponse"]
+
+VersionRetrieveSchemaResponse: TypeAlias = str
diff --git a/src/types/slug.py b/src/types/slug.py
new file mode 100644
index 0000000..3925e4d
--- /dev/null
+++ b/src/types/slug.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["Slug"]
+
+Slug: TypeAlias = str
diff --git a/src/types/team.py b/src/types/team.py
new file mode 100644
index 0000000..cd07803
--- /dev/null
+++ b/src/types/team.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .team_name import TeamName
+from .team_image import TeamImage
+from .slug import Slug
+
+__all__ = ["Team"]
+
+
+class Team(BaseModel):
+
+ uid: Nanoid
+
+ name: TeamName
+
+ imageUri: Optional[TeamImage] = None
+
+ slug: Slug
+
+ theme: str
diff --git a/src/types/team_image.py b/src/types/team_image.py
new file mode 100644
index 0000000..5d2e625
--- /dev/null
+++ b/src/types/team_image.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["TeamImage"]
+
+TeamImage: TypeAlias = str
diff --git a/src/types/team_list_response.py b/src/types/team_list_response.py
new file mode 100644
index 0000000..39698a7
--- /dev/null
+++ b/src/types/team_list_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .team import Team
+
+__all__ = ["TeamListResponse"]
+
+TeamListResponse: TypeAlias = List[Team]
diff --git a/src/types/team_name.py b/src/types/team_name.py
new file mode 100644
index 0000000..2bf4ed8
--- /dev/null
+++ b/src/types/team_name.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["TeamName"]
+
+TeamName: TypeAlias = str
diff --git a/src/types/team_summary.py b/src/types/team_summary.py
new file mode 100644
index 0000000..bc4d716
--- /dev/null
+++ b/src/types/team_summary.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .team_name import TeamName
+from .team_image import TeamImage
+
+__all__ = ["TeamSummary"]
+
+
+class TeamSummary(BaseModel):
+
+ uid: Nanoid
+
+ name: TeamName
+
+ imageUri: Optional[TeamImage] = None
diff --git a/src/types/theme.py b/src/types/theme.py
new file mode 100644
index 0000000..24ba21d
--- /dev/null
+++ b/src/types/theme.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .slug import Slug
+
+__all__ = ["Theme"]
+
+
+class Theme(BaseModel):
+
+ uid: Nanoid
+
+ name: str
+
+ description: str
+
+ slug: Slug
diff --git a/src/types/theme_create_params.py b/src/types/theme_create_params.py
new file mode 100644
index 0000000..9e1c513
--- /dev/null
+++ b/src/types/theme_create_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ThemeCreateParams"]
+
+
+class ThemeCreateParams(TypedDict, total=False):
+
+ name: Required[str]
+
+ description: str
+
+ slug: Required[str]
+
+ document: Required[str]
diff --git a/src/types/theme_create_response.py b/src/types/theme_create_response.py
new file mode 100644
index 0000000..fd27bad
--- /dev/null
+++ b/src/types/theme_create_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+from .uid import Uid
+
+__all__ = ["ThemeCreateResponse"]
+
+ThemeCreateResponse: TypeAlias = Uid
diff --git a/src/types/theme_delete_response.py b/src/types/theme_delete_response.py
new file mode 100644
index 0000000..87e53d2
--- /dev/null
+++ b/src/types/theme_delete_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["ThemeDeleteResponse"]
+
+ThemeDeleteResponse: TypeAlias = None
diff --git a/src/types/theme_list_response.py b/src/types/theme_list_response.py
new file mode 100644
index 0000000..7f5b941
--- /dev/null
+++ b/src/types/theme_list_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import TypeAlias
+from .theme import Theme
+
+__all__ = ["ThemeListResponse"]
+
+ThemeListResponse: TypeAlias = List[Theme]
diff --git a/src/types/theme_replace_document_params.py b/src/types/theme_replace_document_params.py
new file mode 100644
index 0000000..8f41750
--- /dev/null
+++ b/src/types/theme_replace_document_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ThemeReplaceDocumentParams"]
+
+
+class ThemeReplaceDocumentParams(TypedDict, total=False):
+
+ document: Required[str]
diff --git a/src/types/theme_replace_document_response.py b/src/types/theme_replace_document_response.py
new file mode 100644
index 0000000..26395b2
--- /dev/null
+++ b/src/types/theme_replace_document_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["ThemeReplaceDocumentResponse"]
+
+ThemeReplaceDocumentResponse: TypeAlias = None
diff --git a/src/types/theme_retrieve_response.py b/src/types/theme_retrieve_response.py
new file mode 100644
index 0000000..c4af558
--- /dev/null
+++ b/src/types/theme_retrieve_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["ThemeRetrieveResponse"]
+
+ThemeRetrieveResponse: TypeAlias = str
diff --git a/src/types/theme_update_params.py b/src/types/theme_update_params.py
new file mode 100644
index 0000000..d7b438b
--- /dev/null
+++ b/src/types/theme_update_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ThemeUpdateParams"]
+
+
+class ThemeUpdateParams(TypedDict, total=False):
+
+ name: str
+
+ description: str
diff --git a/src/types/theme_update_response.py b/src/types/theme_update_response.py
new file mode 100644
index 0000000..bde2d8e
--- /dev/null
+++ b/src/types/theme_update_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["ThemeUpdateResponse"]
+
+ThemeUpdateResponse: TypeAlias = None
diff --git a/src/types/timestamp.py b/src/types/timestamp.py
new file mode 100644
index 0000000..1185561
--- /dev/null
+++ b/src/types/timestamp.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["Timestamp"]
+
+Timestamp: TypeAlias = int
diff --git a/src/types/uid.py b/src/types/uid.py
new file mode 100644
index 0000000..2be173b
--- /dev/null
+++ b/src/types/uid.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+
+__all__ = ["Uid"]
+
+
+class Uid(BaseModel):
+
+ uid: Nanoid
diff --git a/src/types/user.py b/src/types/user.py
new file mode 100644
index 0000000..ab9c228
--- /dev/null
+++ b/src/types/user.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from typing import List, Optional, Union
+
+from .._models import BaseModel
+from .nanoid import Nanoid
+from .timestamp import Timestamp
+from .email import Email
+from .team_summary import TeamSummary
+
+__all__ = ["User"]
+
+
+class User(BaseModel):
+
+ uid: Nanoid
+
+ createdAt: Timestamp
+
+ updatedAt: Timestamp
+
+ email: Email
+
+ theme: Optional[str] = None
+
+ activeTeamId: Optional[Union[str, None]] = None
+
+ hasGithub: bool
+
+ teams: List[TeamSummary]
diff --git a/src/types/version.py b/src/types/version.py
new file mode 100644
index 0000000..d8c8fff
--- /dev/null
+++ b/src/types/version.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["Version"]
+
+Version: TypeAlias = str
diff --git a/tests/smoke-test.py b/tests/smoke-test.py
new file mode 100644
index 0000000..13c74d1
--- /dev/null
+++ b/tests/smoke-test.py
@@ -0,0 +1,732 @@
+# File generated from our OpenAPI spec by Scalar. See README.md for details.
+
+# Smoke test: calls every generated operation once to confirm the SDK can reach each endpoint.
+# Run it from this repo with `python tests/smoke-test.py`. The generator also runs this file
+# against a mock server and reads the JSON report produced via SCALAR_SMOKE_REPORT.
+from __future__ import annotations
+
+import json
+import os
+import sys
+import time
+import traceback
+from concurrent.futures import ThreadPoolExecutor
+from pathlib import Path
+from typing import Any, Callable, TypedDict
+
+from scalar_api import ScalarApi
+
+# The shared smoke-test runner injects base URL and credentials through the same
+# environment variables the generated client reads in normal use.
+client = ScalarApi(max_retries=0, timeout=30)
+
+
+class SmokeResult(TypedDict, total=False):
+ operation: str
+ method: str
+ path: str
+ status: str
+ durationMs: int
+ error: str
+
+
+class SmokeCase(TypedDict):
+ operation: str
+ method: str
+ path: str
+ run: Callable[[], Any]
+
+
+def _smoke_case_0() -> None:
+ registry = client.registry.list_all_api_documents()
+
+def _smoke_case_1() -> None:
+ registry = client.registry.list_api_documents(
+ namespace="namespace",
+ )
+
+def _smoke_case_2() -> None:
+ registry = client.registry.create_api_document(
+ namespace="namespace",
+ title="",
+ version="",
+ slug="",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_3() -> None:
+ registry = client.registry.update_api_document(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_4() -> None:
+ registry = client.registry.delete_api_document(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_5() -> None:
+ registry = client.registry.retrieve_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ )
+
+def _smoke_case_6() -> None:
+ registry = client.registry.update_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_7() -> None:
+ registry = client.registry.delete_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ idempotency_key="",
+ )
+
+def _smoke_case_8() -> None:
+ registry = client.registry.list_api_document_version_metadata(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ )
+
+def _smoke_case_9() -> None:
+ registry = client.registry.create_api_document_version(
+ namespace="namespace",
+ slug="slug",
+ version="",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_10() -> None:
+ registry = client.registry.create_api_document_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+ )
+
+def _smoke_case_11() -> None:
+ registry = client.registry.delete_api_document_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+ )
+
+def _smoke_case_12() -> None:
+ schema = client.schemas.list(
+ namespace="namespace",
+ )
+
+def _smoke_case_13() -> None:
+ schema = client.schemas.create(
+ namespace="namespace",
+ title="",
+ version="",
+ slug="",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_14() -> None:
+ schema = client.schemas.update(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_15() -> None:
+ schema = client.schemas.delete(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_16() -> None:
+ version = client.schemas.version.retrieve_schema(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ )
+
+def _smoke_case_17() -> None:
+ version = client.schemas.version.delete_schema(
+ namespace="namespace",
+ slug="slug",
+ semver="semver",
+ idempotency_key="",
+ )
+
+def _smoke_case_18() -> None:
+ version = client.schemas.version.create_schema(
+ namespace="namespace",
+ slug="slug",
+ version="",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_19() -> None:
+ access_group = client.schemas.access_group.create_schema(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+ )
+
+def _smoke_case_20() -> None:
+ access_group = client.schemas.access_group.delete_schema(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+ )
+
+def _smoke_case_21() -> None:
+ login_portal = client.login_portals.retrieve(
+ slug="slug",
+ )
+
+def _smoke_case_22() -> None:
+ login_portal = client.login_portals.update(
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_23() -> None:
+ login_portal = client.login_portals.delete(
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_24() -> None:
+ login_portal = client.login_portals.create(
+ title="",
+ slug="",
+ email={"logo": "", "logo_size": "100", "button_text": "Login", "message": "Click to access private documentation hosted by scalar.com", "title": "Private Docs", "main_color": "#2a2f45", "main_background": "#f6f6f6", "card_color": "2a2f45", "card_background": "#fff", "button_color": "#fff", "button_background": "#0f0f0f"},
+ page={"title": "Scalar Private Docs", "description": "Login to access your documentation", "head": "", "script": "", "theme": "", "company_name": "", "logo": "", "logo_url": "", "favicon": "", "terms_link": "", "privacy_link": "", "form_title": "Scalar Private Docs", "form_description": "Login to access your documentation", "form_image": ""},
+ idempotency_key="",
+ )
+
+def _smoke_case_25() -> None:
+ login_portal = client.login_portals.list()
+
+def _smoke_case_26() -> None:
+ rule = client.rules.list_rulesets(
+ namespace="namespace",
+ )
+
+def _smoke_case_27() -> None:
+ rule = client.rules.create_ruleset(
+ namespace="namespace",
+ title="",
+ slug="",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_28() -> None:
+ rule = client.rules.update_ruleset(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_29() -> None:
+ rule = client.rules.delete_ruleset(
+ namespace="namespace",
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_30() -> None:
+ rule = client.rules.retrieve_ruleset_document(
+ namespace="namespace",
+ slug="slug",
+ )
+
+def _smoke_case_31() -> None:
+ rule = client.rules.create_ruleset_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+ )
+
+def _smoke_case_32() -> None:
+ rule = client.rules.delete_ruleset_access_group(
+ namespace="namespace",
+ slug="slug",
+ access_group_slug="",
+ idempotency_key="",
+ )
+
+def _smoke_case_33() -> None:
+ theme = client.themes.list()
+
+def _smoke_case_34() -> None:
+ theme = client.themes.create(
+ name="",
+ slug="",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_35() -> None:
+ theme = client.themes.update(
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_36() -> None:
+ theme = client.themes.replace_document(
+ slug="slug",
+ document="",
+ idempotency_key="",
+ )
+
+def _smoke_case_37() -> None:
+ theme = client.themes.delete(
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_38() -> None:
+ theme = client.themes.retrieve(
+ slug="slug",
+ )
+
+def _smoke_case_39() -> None:
+ team = client.teams.list()
+
+def _smoke_case_40() -> None:
+ scalar_doc = client.scalar_docs.list_guides()
+
+def _smoke_case_41() -> None:
+ scalar_doc = client.scalar_docs.create_guide(
+ name="",
+ is_private=False,
+ allowed_users=[],
+ allowed_domains=[],
+ idempotency_key="",
+ )
+
+def _smoke_case_42() -> None:
+ scalar_doc = client.scalar_docs.publish_guide(
+ slug="slug",
+ idempotency_key="",
+ )
+
+def _smoke_case_43() -> None:
+ namespace = client.namespaces.list()
+
+def _smoke_case_44() -> None:
+ authentication = client.authentication.exchange_personal_token(
+ personal_token="",
+ idempotency_key="",
+ )
+
+def _smoke_case_45() -> None:
+ authentication = client.authentication.list_current_user()
+
+
+cases: list[SmokeCase] = [
+ {
+ "operation": "listAllApiDocuments",
+ "method": "GET",
+ "path": "/v1/apis",
+ "run": _smoke_case_0,
+ },
+
+ {
+ "operation": "listApiDocuments",
+ "method": "GET",
+ "path": "/v1/apis/{namespace}",
+ "run": _smoke_case_1,
+ },
+
+ {
+ "operation": "createApiDocument",
+ "method": "POST",
+ "path": "/v1/apis/{namespace}",
+ "run": _smoke_case_2,
+ },
+
+ {
+ "operation": "updateApiDocument",
+ "method": "PATCH",
+ "path": "/v1/apis/{namespace}/{slug}",
+ "run": _smoke_case_3,
+ },
+
+ {
+ "operation": "deleteApiDocument",
+ "method": "DELETE",
+ "path": "/v1/apis/{namespace}/{slug}",
+ "run": _smoke_case_4,
+ },
+
+ {
+ "operation": "retrieveApiDocumentVersion",
+ "method": "GET",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}",
+ "run": _smoke_case_5,
+ },
+
+ {
+ "operation": "updateApiDocumentVersion",
+ "method": "PATCH",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}",
+ "run": _smoke_case_6,
+ },
+
+ {
+ "operation": "deleteApiDocumentVersion",
+ "method": "DELETE",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}",
+ "run": _smoke_case_7,
+ },
+
+ {
+ "operation": "listApiDocumentVersionMetadata",
+ "method": "GET",
+ "path": "/v1/apis/{namespace}/{slug}/version/{semver}/metadata",
+ "run": _smoke_case_8,
+ },
+
+ {
+ "operation": "createApiDocumentVersion",
+ "method": "POST",
+ "path": "/v1/apis/{namespace}/{slug}/version",
+ "run": _smoke_case_9,
+ },
+
+ {
+ "operation": "createApiDocumentAccessGroup",
+ "method": "POST",
+ "path": "/v1/apis/{namespace}/{slug}/access-group",
+ "run": _smoke_case_10,
+ },
+
+ {
+ "operation": "deleteApiDocumentAccessGroup",
+ "method": "DELETE",
+ "path": "/v1/apis/{namespace}/{slug}/access-group",
+ "run": _smoke_case_11,
+ },
+
+ {
+ "operation": "list",
+ "method": "GET",
+ "path": "/v1/schemas/{namespace}",
+ "run": _smoke_case_12,
+ },
+
+ {
+ "operation": "create",
+ "method": "POST",
+ "path": "/v1/schemas/{namespace}",
+ "run": _smoke_case_13,
+ },
+
+ {
+ "operation": "update",
+ "method": "PATCH",
+ "path": "/v1/schemas/{namespace}/{slug}",
+ "run": _smoke_case_14,
+ },
+
+ {
+ "operation": "delete",
+ "method": "DELETE",
+ "path": "/v1/schemas/{namespace}/{slug}",
+ "run": _smoke_case_15,
+ },
+
+ {
+ "operation": "retrieveSchema",
+ "method": "GET",
+ "path": "/v1/schemas/{namespace}/{slug}/version/{semver}",
+ "run": _smoke_case_16,
+ },
+
+ {
+ "operation": "deleteSchema",
+ "method": "DELETE",
+ "path": "/v1/schemas/{namespace}/{slug}/version/{semver}",
+ "run": _smoke_case_17,
+ },
+
+ {
+ "operation": "createSchema",
+ "method": "POST",
+ "path": "/v1/schemas/{namespace}/{slug}/version",
+ "run": _smoke_case_18,
+ },
+
+ {
+ "operation": "createSchema",
+ "method": "POST",
+ "path": "/v1/schemas/{namespace}/{slug}/access-group",
+ "run": _smoke_case_19,
+ },
+
+ {
+ "operation": "deleteSchema",
+ "method": "DELETE",
+ "path": "/v1/schemas/{namespace}/{slug}/access-group",
+ "run": _smoke_case_20,
+ },
+
+ {
+ "operation": "retrieve",
+ "method": "GET",
+ "path": "/v1/login-portals/{slug}",
+ "run": _smoke_case_21,
+ },
+
+ {
+ "operation": "update",
+ "method": "PATCH",
+ "path": "/v1/login-portals/{slug}",
+ "run": _smoke_case_22,
+ },
+
+ {
+ "operation": "delete",
+ "method": "DELETE",
+ "path": "/v1/login-portals/{slug}",
+ "run": _smoke_case_23,
+ },
+
+ {
+ "operation": "create",
+ "method": "POST",
+ "path": "/v1/login-portals",
+ "run": _smoke_case_24,
+ },
+
+ {
+ "operation": "list",
+ "method": "GET",
+ "path": "/v1/login-portals",
+ "run": _smoke_case_25,
+ },
+
+ {
+ "operation": "listRulesets",
+ "method": "GET",
+ "path": "/v1/rulesets/{namespace}",
+ "run": _smoke_case_26,
+ },
+
+ {
+ "operation": "createRuleset",
+ "method": "POST",
+ "path": "/v1/rulesets/{namespace}",
+ "run": _smoke_case_27,
+ },
+
+ {
+ "operation": "updateRuleset",
+ "method": "PATCH",
+ "path": "/v1/rulesets/{namespace}/{slug}",
+ "run": _smoke_case_28,
+ },
+
+ {
+ "operation": "deleteRuleset",
+ "method": "DELETE",
+ "path": "/v1/rulesets/{namespace}/{slug}",
+ "run": _smoke_case_29,
+ },
+
+ {
+ "operation": "retrieveRulesetDocument",
+ "method": "GET",
+ "path": "/v1/rulesets/{namespace}/{slug}",
+ "run": _smoke_case_30,
+ },
+
+ {
+ "operation": "createRulesetAccessGroup",
+ "method": "POST",
+ "path": "/v1/rulesets/{namespace}/{slug}/access-group",
+ "run": _smoke_case_31,
+ },
+
+ {
+ "operation": "deleteRulesetAccessGroup",
+ "method": "DELETE",
+ "path": "/v1/rulesets/{namespace}/{slug}/access-group",
+ "run": _smoke_case_32,
+ },
+
+ {
+ "operation": "list",
+ "method": "GET",
+ "path": "/v1/themes",
+ "run": _smoke_case_33,
+ },
+
+ {
+ "operation": "create",
+ "method": "POST",
+ "path": "/v1/themes",
+ "run": _smoke_case_34,
+ },
+
+ {
+ "operation": "update",
+ "method": "PATCH",
+ "path": "/v1/themes/{slug}",
+ "run": _smoke_case_35,
+ },
+
+ {
+ "operation": "replaceDocument",
+ "method": "PUT",
+ "path": "/v1/themes/{slug}",
+ "run": _smoke_case_36,
+ },
+
+ {
+ "operation": "delete",
+ "method": "DELETE",
+ "path": "/v1/themes/{slug}",
+ "run": _smoke_case_37,
+ },
+
+ {
+ "operation": "retrieve",
+ "method": "GET",
+ "path": "/v1/themes/{slug}",
+ "run": _smoke_case_38,
+ },
+
+ {
+ "operation": "list",
+ "method": "GET",
+ "path": "/v1/teams",
+ "run": _smoke_case_39,
+ },
+
+ {
+ "operation": "listGuides",
+ "method": "GET",
+ "path": "/v1/guides",
+ "run": _smoke_case_40,
+ },
+
+ {
+ "operation": "createGuide",
+ "method": "POST",
+ "path": "/v1/guides",
+ "run": _smoke_case_41,
+ },
+
+ {
+ "operation": "publishGuide",
+ "method": "POST",
+ "path": "/v1/guides/{slug}/publish",
+ "run": _smoke_case_42,
+ },
+
+ {
+ "operation": "list",
+ "method": "GET",
+ "path": "/v1/namespaces",
+ "run": _smoke_case_43,
+ },
+
+ {
+ "operation": "exchangePersonalToken",
+ "method": "POST",
+ "path": "/v1/auth/exchange",
+ "run": _smoke_case_44,
+ },
+
+ {
+ "operation": "listCurrentUser",
+ "method": "GET",
+ "path": "/v1/auth/me",
+ "run": _smoke_case_45,
+ },
+
+]
+
+def _selected_cases() -> list[SmokeCase]:
+ filter_value = os.environ.get("SCALAR_SMOKE_FILTER")
+ needles = [needle.strip() for needle in filter_value.split(",") if needle.strip()] if filter_value else []
+ if not needles:
+ return cases
+ return [
+ case
+ for case in cases
+ if any(needle in case["operation"] or needle in case["path"] for needle in needles)
+ ]
+
+
+def _run_case(case: SmokeCase) -> SmokeResult:
+ started_at = time.monotonic()
+ try:
+ case["run"]()
+ return {
+ "operation": case["operation"],
+ "method": case["method"],
+ "path": case["path"],
+ "status": "passed",
+ "durationMs": int((time.monotonic() - started_at) * 1000),
+ }
+ except Exception:
+ return {
+ "operation": case["operation"],
+ "method": case["method"],
+ "path": case["path"],
+ "status": "failed",
+ "durationMs": int((time.monotonic() - started_at) * 1000),
+ "error": traceback.format_exc(),
+ }
+
+
+def main() -> None:
+ selected = _selected_cases()
+ if selected:
+ with ThreadPoolExecutor(max_workers=len(selected)) as executor:
+ results = list(executor.map(_run_case, selected))
+ else:
+ results = []
+ failed = [result for result in results if result["status"] == "failed"]
+
+ report_path = os.environ.get("SCALAR_SMOKE_REPORT")
+ if report_path:
+ Path(report_path).write_text(json.dumps({"total": len(results), "failed": len(failed), "results": results}), encoding="utf-8")
+ else:
+ for result in results:
+ if result["status"] == "passed":
+ print(f"PASS {result['operation']} ({result['method']} {result['path']}) {result['durationMs']}ms")
+ else:
+ print(f"FAIL {result['operation']} ({result['method']} {result['path']})\n{result.get('error', '')}", file=sys.stderr)
+ if not results:
+ print("No code samples ran (empty SDK or a SCALAR_SMOKE_FILTER that matched nothing).", file=sys.stderr)
+ else:
+ print(f"\n{len(results) - len(failed)}/{len(results)} samples passed")
+
+ if failed or not results:
+ sys.exit(1)
+
+
+if __name__ == "__main__":
+ main()