Clients¶
A client is the object you subclass to describe an API. It holds three things: the
base_url, the transport engine, and an optional auth strategy. Asas provides two
ready-made base classes.
| Class | Mode | Default engine |
|---|---|---|
AsasClient |
synchronous | HTTPXSyncEngine |
AsasAsyncClient |
asynchronous | HTTPXAsyncEngine |
Defining a client¶
Subclass the base that matches your code style and add decorated methods:
from asas import AsasAsyncClient, get, Response
class GitHubClient(AsasAsyncClient):
@get("/users/{username}")
async def get_user(self, response: Response, username: str):
return response.json()
async def main():
client = GitHubClient(base_url="https://api.github.com")
user = await client.get_user(username="torvalds")
await client.engine.aclose()
Constructor arguments¶
Both clients share the same signature:
base_url— prefix joined with each decorated path. A trailing slash is stripped, sohttps://api.example.comandhttps://api.example.com/behave identically.engine— a transport implementing the engine protocol. Defaults to the bundledhttpxengine. See Engines & Transports.auth— an optional authentication strategy. See Authentication.**kwargs— any extra keyword arguments are forwarded to the underlyinghttpxclient constructor (when the default engine is used).
# Extra kwargs flow straight through to httpx.Client / httpx.AsyncClient
client = GitHubClient(
base_url="https://api.github.com",
timeout=10.0,
headers={"Accept": "application/vnd.github+json"},
)
Custom engines ignore **kwargs
The **kwargs passthrough only applies when Asas creates the default httpx engine.
If you pass your own engine=, configure that engine directly instead.
Swapping auth at runtime¶
auth is a settable property, so you can change credentials after construction — for
example, right after a login call returns a token:
from asas import AsasClient, BearerAuth, post, Response
from pydantic import BaseModel
class Credentials(BaseModel):
username: str
password: str
class ApiClient(AsasClient):
@post("/auth/login", use_auth=False)
def login(self, response: Response, credentials: Credentials):
return response.json()
client = ApiClient(base_url="https://api.example.com")
# 1. Authenticate without any auth header...
data = client.login(credentials=Credentials(username="ada", password="secret"))
# 2. ...then attach the returned token for every subsequent call.
client.auth = BearerAuth(data["token"])
Setting client.auth = None removes authentication entirely.
Closing the client¶
The transport keeps a connection pool open. Close it when you are done — especially for the async client, which must be awaited: