diff --git a/content/docs/(sdks)/python.mdx b/content/docs/(sdks)/python.mdx index a04b45f..de5176b 100644 --- a/content/docs/(sdks)/python.mdx +++ b/content/docs/(sdks)/python.mdx @@ -1,17 +1,206 @@ --- title: Python preferred_title: VRChat.py -description: VRChat.py is a Python SDK for interacting with the VRChat API, allowing developers to create applications that can access and manipulate VRChat data. +description: A full-featured Python SDK for the VRChat API, with generated endpoint clients, model types, and authentication helpers. icon: Python github: vrchatapi/vrchatapi-python links: - href: https://pypi.org/project/vrchatapi --- - +## Install -## Installation - -```bash +```package-install pip install vrchatapi ``` + +## Usage + +You can import the VRChat Python SDK, build a `Configuration`, create an `ApiClient`, and then use endpoint-specific API classes. + +```python +import vrchatapi +from vrchatapi.api import authentication_api + +configuration = vrchatapi.Configuration( + username="your_username_or_email", + password="your_password", +) + +# Build an ApiClient from the configuration (credentials + HTTP session state). +with vrchatapi.ApiClient(configuration) as api_client: + # VRChat requires app name + version + contact info in User-Agent. + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" + + # Create the AuthenticationApi endpoint client using this shared ApiClient. + # You can do this for other endpoint clients similarly. + auth_api = authentication_api.AuthenticationApi(api_client) +``` + +### Authentication + +To use authenticated endpoints, you must log in explicitly or use cookies. + +You need: + +- credentials in `Configuration` (username + password), or +- a valid existing session (cookies), such as one restored from disk (see [Reusing sessions](#reusing-sessions)) + +Then call `get_current_user()` to perform login. + +If the account requires 2FA, handle the `UnauthorizedException` and verify before retrying. + +#### Logging in (with 2FA) + +```python +import vrchatapi +from vrchatapi.api import authentication_api +from vrchatapi.exceptions import UnauthorizedException +from vrchatapi.models.two_factor_auth_code import TwoFactorAuthCode +from vrchatapi.models.two_factor_email_code import TwoFactorEmailCode + +configuration = vrchatapi.Configuration( + username="your_username_or_email", + password="your_password", +) + +with vrchatapi.ApiClient(configuration) as api_client: + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" + auth_api = authentication_api.AuthenticationApi(api_client) + + try: + # Calling get_current_user logs you in if you are not already authenticated. + current_user = auth_api.get_current_user() + except UnauthorizedException as e: + if e.status == 200: + if "Email 2 Factor Authentication" in e.reason: + auth_api.verify2_fa_email_code( + two_factor_email_code=TwoFactorEmailCode(input("Email 2FA Code: ")) + ) + elif "2 Factor Authentication" in e.reason: + auth_api.verify2_fa( + two_factor_auth_code=TwoFactorAuthCode(input("2FA Code: ")) + ) + current_user = auth_api.get_current_user() + else: + raise + except vrchatapi.ApiException as e: + print("Exception when calling API:", e) + + print("Logged in as:", current_user.display_name) +``` + +### Reusing sessions + +The Python SDK uses cookies behind the scenes in its API client. If you keep the same running process and API client alive, authenticated calls can reuse the existing session. +If your app restarts, you usually need to authenticate again unless you implement your own persistent cookie/session storage around the client. + +In order to accomplish this, we persist the HTTP cookie jar to disk and reload it on startup. + +This lets your script reuse existing auth cookies between runs via `pickle` + +```python +import os +import pickle # PICKLE + +import vrchatapi +from vrchatapi.api import authentication_api + +COOKIE_FILE = "vrchat_cookies.pkl" + +configuration = vrchatapi.Configuration( + username="your_username_or_email", + password="your_password", +) + +with vrchatapi.ApiClient(configuration) as api_client: + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" + + # If a saved cookie file exists, load it before making requests. + if os.path.exists(COOKIE_FILE): + with open(COOKIE_FILE, "rb") as fh: + api_client.rest_client.pool_manager.cookiejar = pickle.load(fh) + + auth_api = authentication_api.AuthenticationApi(api_client) + user = auth_api.get_current_user() + print(f"Logged in as {user.display_name}") + + # Save updated cookies after successful login/use. + with open(COOKIE_FILE, "wb") as fh: + pickle.dump(api_client.rest_client.pool_manager.cookiejar, fh) +``` + +## Frequently Asked Questions + +### Error: please identify yourself with a properly formatted user-agent... + +This happens when the request does not include a VRChat-compliant `User-Agent` header. +Set it explicitly on the API client before making requests: + +```python +import vrchatapi + +configuration = vrchatapi.Configuration( + username="your_username_or_email", + password="your_password", +) + +with vrchatapi.ApiClient(configuration) as api_client: + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" + # Continue with API calls... +``` + +### How do I auto-generate 2FA codes instead of typing them manually? + +Use `pyotp` to generate authenticator (TOTP) codes from your account's secret key. +Obtain this during 2FA setup on the vrchat website by pressing "Copy" on the link displayed when scanning the 2FA QR code. +It will look like this: `otpauth://totp/VRChat:your_email_here?secret=COPY_THIS_SECRET&issuer=VRChat` + +Install it: + +```package-install +pip install pyotp +``` + +Minimal code generation example: + +```python +import pyotp + +TOTP_SECRET = "YOUR_BASE32_SECRET_FROM_QR_SETUP" +code = pyotp.TOTP(TOTP_SECRET).now() +print(code) # Example: 123456 +``` + +Use it in the VRChat login flow: + +```python +import pyotp +import vrchatapi +from vrchatapi.api import authentication_api +from vrchatapi.exceptions import UnauthorizedException +from vrchatapi.models.two_factor_auth_code import TwoFactorAuthCode + +TOTP_SECRET = "YOUR_BASE32_SECRET_FROM_QR_SETUP" + +configuration = vrchatapi.Configuration( + username="your_username_or_email", + password="your_password", +) + +with vrchatapi.ApiClient(configuration) as api_client: + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" + auth_api = authentication_api.AuthenticationApi(api_client) + + try: + current_user = auth_api.get_current_user() + except UnauthorizedException as e: + if e.status == 200 and "2 Factor Authentication" in e.reason: + code = pyotp.TOTP(TOTP_SECRET).now() + auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(code)) + current_user = auth_api.get_current_user() + else: + raise + + print("Logged in as:", current_user.display_name) +```