Python
The Python SDK publishes to PyPI with two clients over one surface: Acme, whose methods block, and AsyncAcme, whose methods are coroutines. It needs Python 3.10 or later and uses httpx for both.
Install
pip install your-org-api-clientOptions
Set these for Python in SDK Studio. Each one names its key for octri sdk settings set. Every option, for every language, is in the settings reference.
Data Model Frameworkchoicepydantic, dataclass or typeddict. See data model.
style.python
Synchronous companionschoiceinclude adds a blocking client beside the async one. See sync methods.
syncMethods
Client stylechoiceclass gives callers a client to create. functions gives free functions to import. See client style.
clientStyleByLang.python
NamespacechoiceGroups operations by tags, by URL path, or not at all with none.
namespaceByLang.python
Method namingchoiceshort drops the group's word from the method name, and full keeps the operation ID. Set for every language at once.
methodNaming
Argument stylechoiceobject takes one parameters object, and positional takes arguments in order. See argument style.
outputByLang.python.argumentStyle
Doc commentschoicefull or minimal.
outputByLang.python.docComments
Usage examplechoicefull or concise.
outputByLang.python.usageExample
File headerchoiceinclude or omit. Omitting it needs the Enterprise plan. Set for every language at once.
fileHeader
Data model
How response models are represented. This is the choice your users feel most.
@dataclass
class User:
id: strStandard library, no dependencies, no runtime validation.
Runtime validation catches spec drift at the boundary, where the error names the field that broke, which is why it's the default. But it's a dependency and a performance cost your users didn't choose. If your consumers are FastAPI shops, that cost is already paid. If you're shipping to people who keep their dependency trees short, switch to dataclass before the first release.
Sync methods
include, the default, gives every operation a blocking twin and exports both clients. Scripts, notebooks and Django views use Acme; asyncio code uses AsyncAcme. The namespaces and method names are the same on both.
acme = Acme(config)
users = acme.users.list(limit=10)
async_acme = AsyncAcme(config)
users = await async_acme.users.list(limit=10)omit ships AsyncAcme alone, for a package that is asyncio-only. With the functions client style, the coroutine keeps the plain name (list_users) and the blocking twin carries a _sync suffix (list_users_sync).
Package name
PyPI names are global and normalised: underscores and hyphens are treated the same, case is ignored. Acme_API and acme-api are the same project.
acme-api distribution name (pip install acme-api)
acme_api import name (import acme_api)Deleting a release does not free its version number. 1.0.0 published once is 1.0.0 forever. See Publishing.
What callers write
import os
from acme_api import Acme, AsyncAcme, ClientAuthConfig, ClientConfig
config = ClientConfig(
base_url="https://api.acme.com/v1",
auth=ClientAuthConfig(bearer=os.environ["ACME_TOKEN"]),
)
# Blocking: list_paginated is an iterator that fetches pages as you loop.
acme = Acme(config)
for user in acme.users.list_paginated(limit=100):
print(user.id)
# asyncio: the same call is an async iterator.
async_acme = AsyncAcme(config)
async for user in async_acme.users.list_paginated(limit=100):
print(user.id)Failures raise a subclass of SdkHttpError per common status (SdkNotFoundError, SdkRateLimitError and so on, importable from acme_api.errors), each carrying status_code and request_id.
Runtime
| Requires | Python 3.10 or newer |
| HTTP | httpx |
| Timeout | 30 seconds per attempt |
| Retries | Up to 3 attempts, with backoff from 500 ms to 8 seconds |
| Idempotency keys | POST and PATCH |
Those are the defaults. See every setting and retries and timeouts to change them.
Streaming
For an operation that streams:
for event in client.events.stream():
print(event.id)On AsyncAcme, write async for. Stop iterating as soon as you're done, so the connection can close. See streaming.
Handling errors
from acme_api.errors import SdkHttpError, SdkNotFoundError
try:
client.users.get(id="usr_1")
except SdkNotFoundError:
return None
except SdkHttpError as error:
print(error.status_code, error.request_id)
raiseEach common status has its own subclass of SdkHttpError. error.data holds the decoded model, which you can narrow with isinstance. See what's in the package.