makimoto-kawa
Official Python SDK for Kawa's transcription API. makimoto is the shared namespace this SDK lives under, kawa is the specific product it talks to, more Makimoto products may get their own subpackage here later.
This is the maintained, typed client, with pydantic response models, structured exceptions, and a tested, versioned release process, built on top of the same API as the reference client in the main kawa repo. For the interactive playground, full API docs, and the OpenAPI spec, see the main kawa repo. Prefer a zero-dependency, copy-paste client instead of a pip package? See kawa_client.py there.
Install
Requires Python 3.10+.
pip install makimoto-kawa
Authentication
Create an API key from the Makimoto dashboard: https://www.makimoto.ai/login. This is a static key, not the short-lived JWT your browser session uses, it doesn't expire on its own, and it's the only credential this SDK accepts, the transcription endpoints reject a dashboard login JWT outright.
client = kawa.KawaClient(api_key="<your api key>")
or set it once as an environment variable and omit the argument entirely:
export MAKIMOTO_API_KEY="<your api key>"
An explicit api_key argument always wins over the environment variable if both are set.
Usage
from makimoto import kawa
client = kawa.KawaClient(api_key="<your api key>") # or set MAKIMOTO_API_KEY instead
job = client.transcribe("call.mp3", language="en")
if job.status == "succeeded":
print(job.result.full_text)
else:
print(job.error)
See examples/quickstart.py for a complete, runnable script, it ships with a small sample audio file, so python examples/quickstart.py works out of the box once MAKIMOTO_API_KEY is set.
transcribe() submits the recording and polls until it's done in one call, raising TimeoutError if it never finishes. For manual control, e.g. streaming live status updates to a UI, the lower-level primitives are still there:
job = client.create_transcription("call.mp3", language="en")
for update in client.poll(job.job_id):
print(update.status)
Once a transcription has succeeded, summarise or tag it by its job_id. Both return a new job, fetched or polled the same way as a transcription, through its own job_id, not the source transcription's:
summary_job = client.create_summary(job.job_id)
for update in client.poll(summary_job.job_id):
print(update.status)
print(update.result.topic, update.result.summary)
tags_job = client.create_tags(job.job_id)
for update in client.poll(tags_job.job_id):
print(update.status)
print(update.result.tags)
Or skip the transcription entirely and summarise/tag a transcript you already have, with transcript_text instead of a job id (exactly one of the two must be given):
summary_job = client.create_summary(
transcript_text="the customer called about a billing issue..."
)
Fetch or delete any job (transcription, summary, or tags) by its job_id:
job = client.get_job(job.job_id)
client.delete_job(job.job_id)
List past jobs, one page at a time, with optional filters (status, job_type, language, created_after, job_id). With no job_type, every job type (transcription, summary, and tags) is returned:
page = client.list_jobs(job_type="summary", status="succeeded", limit=25)
for job in page.transcriptions:
print(job.job_id, job.status)
if page.next_cursor:
next_page = client.list_jobs(cursor=page.next_cursor)
Or walk every matching job across all pages automatically:
for job in client.iter_jobs(status="succeeded"):
print(job.job_id)
Release the client's connections when you're done with it, or use it as a context manager:
with kawa.KawaClient(api_key="<your api key>") as client:
...
Errors
Every call raises kawa.KawaError on an API-level failure (bad status code, or a response that doesn't match the expected shape), and kawa.TimeoutError-compatible TimeoutError from transcribe() if a job never finishes in time. A failed transcription job (status == "failed") is not an exception, it's a normal result, check .status/.error as shown above.
try:
job = client.transcribe("call.mp3")
except kawa.KawaError as exc:
print(exc.status_code, exc.body)
Logging
Quiet by default. To see what the SDK is doing (credential source, a poll that gave up), or the raw HTTP traffic underneath it:
import logging
logging.basicConfig() # attaches a handler so the lines below actually print somewhere
logging.getLogger("makimoto.kawa.client").setLevel(
logging.DEBUG
) # this SDK's own events
logging.getLogger("httpx2").setLevel(logging.DEBUG) # every request/response
Development
See CONTRIBUTING.md.
Licence
Metadata
Release files for makimoto-kawa 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| makimoto_kawa-0.2.0.tar.gz | 23.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| makimoto_kawa-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.5 kB
Release files / makimoto_kawa-0.2.0.tar.gz
| Download URL | makimoto_kawa-0.2.0.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc7fef3956ff021d9376654e1b2289bb0d9a3ac25a75d4795731c8f9e2742d34
|
|
BLAKE2b-256 checksum How to use checksums |
945242cb3c56ae3c1e4d19b37a8fd4afa5295ee91a6e1ad7dfb585ce60e198da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.
Transparency logRelease files / makimoto_kawa-0.2.0-py3-none-any.whl
| Download URL | makimoto_kawa-0.2.0-py3-none-any.whl |
|---|---|
| Size | 17.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
850d2f252e598b61e2860570237c1d84051aedc9c7e457c0d750d6e6092805fb
|
|
BLAKE2b-256 checksum How to use checksums |
002a9c2bc9807d4a8999cd375d49c44762ab0c8f0e18a64668697216bf8a97de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.
Transparency log