Appearance
Async Client
Gazu provides an async HTTP module built on aiohttp for use in async applications. Install it with the async extra:
bash
pip install gazu[async]Why async?
The async client lets you run multiple API calls concurrently. This is useful when you need to fetch or update many entities at once — instead of waiting for each request to complete before starting the next, they all run in parallel.
Quick start
python
import asyncio
import gazu.aio
async def main():
async with gazu.aio.create_session(
"https://kitsu.mystudio.com/api",
"user@example.com",
"password",
) as client:
# Fetch projects, task types, and task statuses concurrently
projects, task_types, task_statuses = await asyncio.gather(
gazu.aio.fetch_all("projects/open", client=client),
gazu.aio.fetch_all("task-types", client=client),
gazu.aio.fetch_all("task-status", client=client),
)
print(f"{len(projects)} projects, {len(task_types)} task types")
asyncio.run(main())Making requests
The async module mirrors the sync client's HTTP helpers. Each call needs to be await-ed:
python
# GET
data = await gazu.aio.get("data/projects", client=client)
# POST
result = await gazu.aio.post("data/tasks/from-path", {
"project_id": project["id"],
"file_path": "/simple/SE01/S01/animation",
"type": "shot",
}, client=client)
# PUT
await gazu.aio.put(f"data/tasks/{task_id}", {"priority": 1}, client=client)
# DELETE
await gazu.aio.delete(f"data/tasks/{task_id}", client=client)Higher-level helpers are available too:
python
# Fetch all entries for a model
assets = await gazu.aio.fetch_all("projects/{id}/assets", client=client)
# Fetch a single entry
asset = await gazu.aio.fetch_one("assets", asset_id, client=client)Running calls concurrently
The main benefit of async is running independent calls in parallel with asyncio.gather:
Fetching data for many entities at once
python
async def get_all_shots_with_tasks(client):
projects = await gazu.aio.fetch_all("projects/open", client=client)
# Fetch all shots for every project concurrently
shot_lists = await asyncio.gather(*[
gazu.aio.fetch_all(
f"projects/{project['id']}/shots", client=client
)
for project in projects
])
all_shots = [shot for shots in shot_lists for shot in shots]
# Fetch full task data for every shot concurrently
task_lists = await asyncio.gather(*[
gazu.aio.get(
f"data/shots/{shot['id']}/tasks", client=client
)
for shot in all_shots
])
for shot, tasks in zip(all_shots, task_lists):
shot["tasks"] = tasks
return all_shotsWith the sync client this would be N+1 sequential HTTP calls. With async they all run at the same time.
Batch updates
Update many entities in parallel:
python
async def set_all_shots_to_active(project, client):
shots = await gazu.aio.fetch_all(
f"projects/{project['id']}/shots", client=client
)
await asyncio.gather(*[
gazu.aio.put(
f"data/shots/{shot['id']}",
{"status": "active"},
client=client,
)
for shot in shots
])Concurrent file downloads
python
async def download_all_previews(preview_files, client):
await asyncio.gather(*[
gazu.aio.download(
f"movies/originals/preview-files/{pf['id']}.mp4",
f"/tmp/{pf['id']}.mp4",
client=client,
)
for pf in preview_files
])File uploads and downloads
Single file operations work the same way as the sync client:
python
# Upload
await gazu.aio.upload(
"pictures/thumbnails/projects/project-id",
"/path/to/thumbnail.png",
client=client,
)
# Download
await gazu.aio.download(
"movies/originals/preview-files/preview-id.mp4",
"/tmp/output.mp4",
client=client,
)Authentication
Use create_session for automatic login and cleanup:
python
async with gazu.aio.create_session(host, email, password) as client:
# client is logged in and ready
...
# automatic logout + session closeOr manage the client manually:
python
client = gazu.aio.AsyncKitsuClient("https://kitsu.mystudio.com/api")
tokens = await gazu.aio.log_in("user@example.com", "password", client=client)
# ... do work ...
await gazu.aio.log_out(client=client)Key differences from the sync client
- No global
default_client— always passclient=explicitly - Uses
aiohttp.ClientSessioninstead ofrequests.Session - Use
asyncio.gatherto run calls concurrently - Use
async withinstead ofwithfor context managers
