Getting Started¶
Installation¶
Quick example¶
import asyncio
import httpx
from longwei import APClient
async def main():
async with httpx.AsyncClient() as client:
ap = await APClient.create(
instance="mastodon.social",
client=client,
access_token="your_access_token",
)
status = await ap.post_status("Hello, fediverse!")
print(f"Posted: {status.url}")
asyncio.run(main())
Creating an APClient¶
Recommended: async factory¶
APClient.create() is the recommended entry point. It calls determine_instance_type()
automatically, configuring server-specific parameters (status length limit, attachment limits,
supported MIME types) before any API call is made.
async with httpx.AsyncClient() as client:
ap = await APClient.create(
instance="mastodon.social", # domain or full URL; trailing slash is stripped
client=client, # httpx AsyncClient
access_token="your_token", # optional — omit for public endpoints
timeout=30, # optional — seconds; defaults to 120
)
Direct instantiation¶
You can also instantiate directly. The instance type defaults to INSTANCE_TYPE_MASTODON until
determine_instance_type() is called manually.
ap = APClient(
instance="mastodon.social",
client=client,
access_token="your_token",
)
await ap.determine_instance_type() # optional — only needed for accurate limits
Authentication¶
To authenticate, you need an access token. See the Authentication guide for how to obtain one using the password grant or the OAuth authorization code flow.
If you are building a tool that only reads public data (public timelines, public statuses),
you can omit the access_token parameter.
Basic operations¶
Read the home timeline¶
statuses = await ap.get_home_timeline(limit=20)
for status in statuses:
author = status.account.username if status.account else "?"
print(f"@{author}: {(status.content or '')[:80]}")
Post a status¶
from longwei import Visibility
status = await ap.post_status(
"Hello, fediverse!",
visibility=Visibility.PUBLIC, # default; see Enums for all options
)
print(f"Posted: {status.url}")
Delete a status¶
Search¶
from longwei import SearchType
results = await ap.search(query="python", query_type=SearchType.HASHTAGS)
for tag in results.get("hashtags", []):
print(tag["name"])
Pagination¶
Timeline methods that support pagination store the next/previous page cursors on the client instance after each call:
first_page = await ap.get_public_timeline(limit=20)
# Fetch the next page using max_id from the stored pagination state
next_max_id = ap.pagination["next"]["max_id"]
if next_max_id:
second_page = await ap.get_public_timeline(limit=20, max_id=next_max_id)
ap.pagination structure:
Values are None when there is no further page in that direction.
Rate limits¶
After each successful response the client tracks the server's rate limit headers:
| Attribute | Type | Description |
|---|---|---|
ap.ratelimit_limit |
int |
Total requests allowed per window (default 300) |
ap.ratelimit_remaining |
int |
Requests remaining in the current window |
ap.ratelimit_reset |
datetime |
When the window resets |
Pleroma instances do not return rate limit headers; for those,
ratelimit_reset is set to a synthetic 5-minute window.
When the limit is exhausted, the next API call raises RatelimitError before contacting the
server. See Error Handling for how to handle it.
Context manager pattern¶
httpx.AsyncClient works as a context manager. The recommended pattern is:
async with httpx.AsyncClient() as client:
ap = await APClient.create(instance="mastodon.social", client=client, access_token="token")
# all API calls inside this block
statuses = await ap.get_home_timeline()
The client is closed automatically when the async with block exits.
Instance type detection¶
After APClient.create() (or after calling determine_instance_type() manually), the
following attributes are populated from the server's /api/v1/instance response:
| Attribute | Type | Description |
|---|---|---|
ap.instance_type |
str |
"Mastodon" or "Pleroma" |
ap.max_status_len |
int |
Maximum status length in characters |
ap.max_attachments |
int |
Maximum number of media attachments per status |
ap.max_att_size |
int |
Maximum attachment size in bytes |
ap.supported_mime_types |
list[str] |
MIME types accepted for media uploads |