|
1 | 1 | --- |
2 | 2 | title: Python |
3 | 3 | preferred_title: VRChat.py |
4 | | -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. |
| 4 | +description: A full-featured Python SDK for the VRChat API, with generated endpoint clients, model types, and authentication helpers. |
5 | 5 | icon: Python |
6 | 6 | github: vrchatapi/vrchatapi-python |
7 | 7 | links: |
8 | 8 | - href: https://pypi.org/project/vrchatapi |
9 | 9 | --- |
10 | 10 |
|
11 | | -<TooShort /> |
| 11 | +## Install |
12 | 12 |
|
13 | | -## Installation |
14 | | - |
15 | | -```bash |
| 13 | +```package-install |
16 | 14 | pip install vrchatapi |
17 | 15 | ``` |
| 16 | + |
| 17 | +## Usage |
| 18 | + |
| 19 | +You can import the VRChat Python SDK, build a `Configuration`, create an `ApiClient`, and then use endpoint-specific API classes. |
| 20 | + |
| 21 | +```python |
| 22 | +import vrchatapi |
| 23 | +from vrchatapi.api import authentication_api |
| 24 | + |
| 25 | +configuration = vrchatapi.Configuration( |
| 26 | + username="your_username_or_email", |
| 27 | + password="your_password", |
| 28 | +) |
| 29 | + |
| 30 | +# Build an ApiClient from the configuration (credentials + HTTP session state). |
| 31 | +with vrchatapi.ApiClient(configuration) as api_client: |
| 32 | + # VRChat requires app name + version + contact info in User-Agent. |
| 33 | + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" |
| 34 | + |
| 35 | + # Create the AuthenticationApi endpoint client using this shared ApiClient. |
| 36 | + # You can do this for other endpoint clients similarly. |
| 37 | + auth_api = authentication_api.AuthenticationApi(api_client) |
| 38 | +``` |
| 39 | + |
| 40 | +### Authentication |
| 41 | + |
| 42 | +To use authenticated endpoints, you must log in explicitly or use cookies. |
| 43 | + |
| 44 | +You need: |
| 45 | + |
| 46 | +- credentials in `Configuration` (username + password), or |
| 47 | +- a valid existing session (cookies), such as one restored from disk (see [Reusing sessions](#reusing-sessions)) |
| 48 | + |
| 49 | +Then call `get_current_user()` to perform login. |
| 50 | + |
| 51 | +If the account requires 2FA, handle the `UnauthorizedException` and verify before retrying. |
| 52 | + |
| 53 | +#### Logging in (with 2FA) |
| 54 | + |
| 55 | +```python |
| 56 | +import vrchatapi |
| 57 | +from vrchatapi.api import authentication_api |
| 58 | +from vrchatapi.exceptions import UnauthorizedException |
| 59 | +from vrchatapi.models.two_factor_auth_code import TwoFactorAuthCode |
| 60 | +from vrchatapi.models.two_factor_email_code import TwoFactorEmailCode |
| 61 | + |
| 62 | +configuration = vrchatapi.Configuration( |
| 63 | + username="your_username_or_email", |
| 64 | + password="your_password", |
| 65 | +) |
| 66 | + |
| 67 | +with vrchatapi.ApiClient(configuration) as api_client: |
| 68 | + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" |
| 69 | + auth_api = authentication_api.AuthenticationApi(api_client) |
| 70 | + |
| 71 | + try: |
| 72 | + # Calling get_current_user logs you in if you are not already authenticated. |
| 73 | + current_user = auth_api.get_current_user() |
| 74 | + except UnauthorizedException as e: |
| 75 | + if e.status == 200: |
| 76 | + if "Email 2 Factor Authentication" in e.reason: |
| 77 | + auth_api.verify2_fa_email_code( |
| 78 | + two_factor_email_code=TwoFactorEmailCode(input("Email 2FA Code: ")) |
| 79 | + ) |
| 80 | + elif "2 Factor Authentication" in e.reason: |
| 81 | + auth_api.verify2_fa( |
| 82 | + two_factor_auth_code=TwoFactorAuthCode(input("2FA Code: ")) |
| 83 | + ) |
| 84 | + current_user = auth_api.get_current_user() |
| 85 | + else: |
| 86 | + raise |
| 87 | + except vrchatapi.ApiException as e: |
| 88 | + print("Exception when calling API:", e) |
| 89 | + |
| 90 | + print("Logged in as:", current_user.display_name) |
| 91 | +``` |
| 92 | + |
| 93 | +### Reusing sessions |
| 94 | + |
| 95 | +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. |
| 96 | +If your app restarts, you usually need to authenticate again unless you implement your own persistent cookie/session storage around the client. |
| 97 | + |
| 98 | +In order to accomplish this, we persist the HTTP cookie jar to disk and reload it on startup. |
| 99 | + |
| 100 | +This lets your script reuse existing auth cookies between runs via `pickle` |
| 101 | + |
| 102 | +```python |
| 103 | +import os |
| 104 | +import pickle # PICKLE |
| 105 | + |
| 106 | +import vrchatapi |
| 107 | +from vrchatapi.api import authentication_api |
| 108 | + |
| 109 | +COOKIE_FILE = "vrchat_cookies.pkl" |
| 110 | + |
| 111 | +configuration = vrchatapi.Configuration( |
| 112 | + username="your_username_or_email", |
| 113 | + password="your_password", |
| 114 | +) |
| 115 | + |
| 116 | +with vrchatapi.ApiClient(configuration) as api_client: |
| 117 | + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" |
| 118 | + |
| 119 | + # If a saved cookie file exists, load it before making requests. |
| 120 | + if os.path.exists(COOKIE_FILE): |
| 121 | + with open(COOKIE_FILE, "rb") as fh: |
| 122 | + api_client.rest_client.pool_manager.cookiejar = pickle.load(fh) |
| 123 | + |
| 124 | + auth_api = authentication_api.AuthenticationApi(api_client) |
| 125 | + user = auth_api.get_current_user() |
| 126 | + print(f"Logged in as {user.display_name}") |
| 127 | + |
| 128 | + # Save updated cookies after successful login/use. |
| 129 | + with open(COOKIE_FILE, "wb") as fh: |
| 130 | + pickle.dump(api_client.rest_client.pool_manager.cookiejar, fh) |
| 131 | +``` |
| 132 | + |
| 133 | +## Frequently Asked Questions |
| 134 | + |
| 135 | +### Error: please identify yourself with a properly formatted user-agent... |
| 136 | + |
| 137 | +This happens when the request does not include a VRChat-compliant `User-Agent` header. |
| 138 | +Set it explicitly on the API client before making requests: |
| 139 | + |
| 140 | +```python |
| 141 | +import vrchatapi |
| 142 | + |
| 143 | +configuration = vrchatapi.Configuration( |
| 144 | + username="your_username_or_email", |
| 145 | + password="your_password", |
| 146 | +) |
| 147 | + |
| 148 | +with vrchatapi.ApiClient(configuration) as api_client: |
| 149 | + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" |
| 150 | + # Continue with API calls... |
| 151 | +``` |
| 152 | + |
| 153 | +### How do I auto-generate 2FA codes instead of typing them manually? |
| 154 | + |
| 155 | +Use `pyotp` to generate authenticator (TOTP) codes from your account's secret key. |
| 156 | +Obtain this during 2FA setup on the vrchat website by pressing "Copy" on the link displayed when scanning the 2FA QR code. |
| 157 | +It will look like this: `otpauth://totp/VRChat:your_email_here?secret=COPY_THIS_SECRET&issuer=VRChat` |
| 158 | + |
| 159 | +Install it: |
| 160 | + |
| 161 | +```package-install |
| 162 | +pip install pyotp |
| 163 | +``` |
| 164 | + |
| 165 | +Minimal code generation example: |
| 166 | + |
| 167 | +```python |
| 168 | +import pyotp |
| 169 | + |
| 170 | +TOTP_SECRET = "YOUR_BASE32_SECRET_FROM_QR_SETUP" |
| 171 | +code = pyotp.TOTP(TOTP_SECRET).now() |
| 172 | +print(code) # Example: 123456 |
| 173 | +``` |
| 174 | + |
| 175 | +Use it in the VRChat login flow: |
| 176 | + |
| 177 | +```python |
| 178 | +import pyotp |
| 179 | +import vrchatapi |
| 180 | +from vrchatapi.api import authentication_api |
| 181 | +from vrchatapi.exceptions import UnauthorizedException |
| 182 | +from vrchatapi.models.two_factor_auth_code import TwoFactorAuthCode |
| 183 | + |
| 184 | +TOTP_SECRET = "YOUR_BASE32_SECRET_FROM_QR_SETUP" |
| 185 | + |
| 186 | +configuration = vrchatapi.Configuration( |
| 187 | + username="your_username_or_email", |
| 188 | + password="your_password", |
| 189 | +) |
| 190 | + |
| 191 | +with vrchatapi.ApiClient(configuration) as api_client: |
| 192 | + api_client.user_agent = "ExampleProgram/0.0.1 my@email.com" |
| 193 | + auth_api = authentication_api.AuthenticationApi(api_client) |
| 194 | + |
| 195 | + try: |
| 196 | + current_user = auth_api.get_current_user() |
| 197 | + except UnauthorizedException as e: |
| 198 | + if e.status == 200 and "2 Factor Authentication" in e.reason: |
| 199 | + code = pyotp.TOTP(TOTP_SECRET).now() |
| 200 | + auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(code)) |
| 201 | + current_user = auth_api.get_current_user() |
| 202 | + else: |
| 203 | + raise |
| 204 | + |
| 205 | + print("Logged in as:", current_user.display_name) |
| 206 | +``` |
0 commit comments