Authentication¶
To call most API methods you need an access token from the fediverse instance you are connecting to. longwei provides two flows:
- Password grant — provide username and password directly; simpler but requires storing credentials.
- Authorization code (OAuth) — redirect the user to the instance's login page; the standard browser-based OAuth flow.
All authentication methods are static methods on APClient — they do not require an
existing authenticated instance.
Password grant¶
Deprecated — security risk
get_auth_token() uses the OAuth 2.0 Resource Owner Password Credentials (ROPC) grant,
which is deprecated in OAuth 2.1
with a recommendation to remove it entirely.
Why this matters:
- Your application must directly receive and transmit the user's plaintext password.
- Most Mastodon instances block this flow by default; it may appear to work on Pleroma or GotoSocial but fail silently elsewhere.
- Calling this method emits a
DeprecationWarningat runtime.
Use the authorization code flow instead — it never exposes the user's password to your application.
The simplest option for non-Mastodon instances that support the password grant.
APClient.get_auth_token() creates an app, exchanges credentials for a token, and returns
it in a single call.
import warnings
import httpx
from longwei import APClient
async with httpx.AsyncClient() as client:
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
token = await APClient.get_auth_token(
instance_url="mastodon.social",
username="you@mastodon.social",
password="your_password",
client=client,
)
ap = await APClient.create(
instance="mastodon.social",
client=client,
access_token=token,
)
Signature¶
@staticmethod
async def get_auth_token(
instance_url: str,
username: str,
password: str,
client: AsyncClient,
user_agent: str = USER_AGENT,
client_website: str = "https://pypi.org/project/longwei/",
) -> str
| Parameter | Description |
|---|---|
instance_url |
Domain or URL of the instance (e.g. "mastodon.social"). Bare hostnames are normalised to https://. Plain http://, private/loopback IPs, and blocked hostnames raise ClientError. |
username |
Account username or email |
password |
Account password |
client |
httpx.AsyncClient |
user_agent |
User-agent string sent to the instance; defaults to USER_AGENT |
client_website |
Website URL registered with the app; defaults to the longwei PyPI page |
Returns the access token as a string.
OAuth authorization code flow¶
Use this flow when you cannot or do not want to handle credentials directly — for example, in a web application where users log in via the instance's own login page.
Step 1 — Create an app¶
import httpx
from longwei import APClient
async with httpx.AsyncClient() as client:
client_id, client_secret = await APClient.create_app(
instance_url="mastodon.social",
client=client,
)
# Store client_id and client_secret securely
Step 2 — Generate the authorization URL¶
auth_url = await APClient.generate_authorization_url(
instance_url="mastodon.social",
client_id=client_id,
)
print(f"Visit this URL to authorize: {auth_url}")
# Direct the user to auth_url in their browser
Step 3 — Exchange the authorization code for a token¶
After the user authorizes the app, the instance redirects to
urn:ietf:wg:oauth:2.0:oob with a code query parameter.
Exchange that code for an access token:
authorization_code = input("Paste the authorization code: ")
token = await APClient.validate_authorization_code(
client=client,
instance_url="mastodon.social",
authorization_code=authorization_code,
client_id=client_id,
client_secret=client_secret,
)
# token is now ready to use
ap = await APClient.create(
instance="mastodon.social",
client=client,
access_token=token,
)
Method reference¶
Instance URL validation: All methods that accept
instance_urlvalidate it before making any HTTP request. Bare hostnames are normalised tohttps://. Plainhttp://, private/loopback/link-local IP ranges, and reserved hostnames (localhost,metadata.google.internal,metadata.internal) raiseClientErrorimmediately.
APClient.create_app()¶
Creates an OAuth application on the instance and returns (client_id, client_secret).
@staticmethod
async def create_app(
instance_url: str,
client: AsyncClient,
user_agent: str = USER_AGENT,
client_website: str = "https://pypi.org/project/longwei/",
) -> tuple[str, str]
APClient.generate_authorization_url()¶
Builds the URL the user should visit to authorize the app. Returns the URL as a string.
@staticmethod
async def generate_authorization_url(
instance_url: str,
client_id: str,
user_agent: str = USER_AGENT,
) -> str
APClient.validate_authorization_code()¶
Exchanges an authorization code for an access token. Returns the token as a string.
@staticmethod
async def validate_authorization_code(
client: AsyncClient,
instance_url: str,
authorization_code: str,
client_id: str,
client_secret: str,
) -> str
APClient.get_auth_token() (deprecated)¶
Deprecated
Emits DeprecationWarning. Use the authorization code flow instead.
Convenience method that combines create_app() and a password-grant token exchange into a
single call. Returns the access token as a string.
@staticmethod
async def get_auth_token(
instance_url: str,
username: str,
password: str,
client: AsyncClient,
user_agent: str = USER_AGENT,
client_website: str = "https://pypi.org/project/longwei/",
) -> str
USER_AGENT¶
USER_AGENT is a pre-built user-agent string that includes the library name and version.
It is the default for all methods that accept a user_agent parameter.
You can pass a custom string if you want the instance to identify your application differently.