schwab-py

raw JSON →
1.5.1 verified Sat May 09 auth: no python

An unofficial Python API wrapper for the Schwab HTTP API, providing access to trading, account data, market data, and streaming. Current version is 1.5.1, requires Python >=3.10. Active development with frequent releases.

pip install schwab-py
error ModuleNotFoundError: No module named 'schwab'
cause Library not installed or installed for a different Python environment.
fix
Run 'pip install schwab-py' and ensure you are using the correct Python interpreter.
error FileNotFoundError: [Errno 2] No such file or directory: '/path/to/token.json'
cause Token file path is incorrect or file doesn't exist; first-time setup required.
fix
Run auth.easy_client(app_key, app_secret, token_path) to perform initial OAuth flow and generate the token file.
error schwab.auth.AuthError: Access token expired
cause Token expired and automatic refresh failed (e.g., network issue or invalid refresh token).
fix
Delete the token file and re-authenticate using easy_client. Ensure system time is accurate.
breaking The easy_client utility logs you out of all other Schwab API sessions in the browser. Use only on a dedicated browser or incognito window.
fix Use a separate browser profile or incognito window when running easy_client.
deprecated Importing from schwab.auth (e.g., from schwab.auth import client_from_token_file) is deprecated in favor of from schwab import auth; auth.client_from_token_file(...).
fix Use 'from schwab import auth' and then auth.client_from_token_file().
gotcha The token file is a JSON file that must be kept secret. The library automatically refreshes tokens, but if the file is deleted or corrupted, you must re-authenticate.
fix Store token file securely and back it up. If lost, delete token file and re-run easy_client.
gotcha Schwab's API has rate limits. The library does not handle rate limiting automatically; you may get 429 errors.
fix Implement your own retry logic with exponential backoff for 429 responses.

Initialize client and fetch account numbers and a stock quote.

import os
from schwab import auth
from schwab.client import Client

# Set up authentication (first time will open browser for OAuth)
token_path = '/path/to/token.json'
app_key = os.environ.get('SCHWAB_APP_KEY', 'your-app-key')
app_secret = os.environ.get('SCHWAB_APP_SECRET', 'your-app-secret')

# On first run, this will prompt for login via browser
try:
    client = auth.client_from_token_file(token_path, app_key, app_secret)
except FileNotFoundError:
    # Token file doesn't exist yet; perform initial login
    client = auth.easy_client(app_key, app_secret, token_path)

# Get account info
accounts = client.get_account_numbers()
print(accounts)

# Get a quote
quote = client.get_quote('AAPL')
print(quote)