A comprehensive Python module for handling Charles Schwab API authentication with OAuth 2.0 flow, automatic token management, and Google Cloud Storage integration.
- 🔐 OAuth 2.0 Authentication: Complete implementation of Schwab API OAuth flow
- 🔄 Flexible Token Management: Support for fresh authentication and GCS-stored tokens
- 💾 Token Persistence: Saves access and refresh tokens locally and (optionally) to Google Cloud Storage
- ☁️ Cloud Storage Integration: Automatic token backup, retrieval, and validation from GCS
- 🛡️ Robust Error Handling: Comprehensive error handling for all authentication scenarios
- 🎯 Easy Integration: Simple class-based design for seamless integration into larger projects
- ⚡ Dual Mode Operation: Fresh authentication or GCS-based token refresh
- 🔧 Modular Architecture: Separate GCS module for cloud storage operations
- Python 3.8+
- Charles Schwab Developer Account
- Registered Schwab API Application
- Google Cloud Storage Account (for cloud token storage)
-
Clone the repository with submodules:
git clone --recursive <repository-url> cd charles-schwab-authentication-module
-
Create and activate a virtual environment:
# Create virtual environment python -m venv venv # Activate virtual environment # On macOS/Linux: source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install required dependencies:
# Ensure pip is up to date pip install --upgrade pip # Install dependencies pip install -r requirements.txt
-
Initialize submodules:
git submodule update --init --recursive
- Visit the Charles Schwab Developer Portal
- Create a developer account
- Register a new application
- Note your App Key and App Secret
- Set your redirect URI to
https://127.0.0.1
- Create a Google Cloud Storage bucket for token storage
- Set up a service account with Storage Object Admin permissions
- Download the service account key (JSON format)
- Configure the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable
IMPORTANT: You must create a .env file in the main directory for the application to work properly.
-
Copy the example file:
cp gcs-python-module/env.example .env
-
Edit the
.envfile with your actual credentials:# Schwab API Configuration SCHWAB_APP_KEY=your-actual-schwab-app-key SCHWAB_APP_SECRET=your-actual-schwab-app-secret # Google Cloud Storage Configuration GCS_BUCKET_NAME=your-actual-gcs-bucket-name GOOGLE_APPLICATION_CREDENTIALS=service-account-credentials.json
-
Replace the placeholder values:
your-actual-schwab-app-key: Your Schwab API App Keyyour-actual-schwab-app-secret: Your Schwab API App Secretyour-actual-gcs-bucket-name: Your Google Cloud Storage bucket nameservice-account-credentials.json: Path to your GCS service account key file (usually just the filename if it's in the same directory)
Note: If you don't have a GCS bucket set up, you can leave GCS_BUCKET_NAME empty, but the cloud storage features won't work.
Run the script to authenticate locally and upload refresh token to GCS:
# Authenticate interactively, cache tokens locally, and push them to GCS
python schwab_authentication_client.py --authenticate
# or simply (default behavior)
python schwab_authentication_client.pyThis will:
- Prompt you to visit the authorization URL
- Ask you to paste the redirect URL after authorization
- Generate fresh access and refresh tokens
- Persist both tokens to local files (
schwab_access_token.txt,schwab_refresh_token.txt) - Upload both token files to Google Cloud Storage (when configured)
Get a new access token using the refresh token stored in Google Cloud Storage:
python schwab_authentication_client.py --get-access-tokenThis will:
- Try the cached access token stored locally
- Fall back to the access token cached in Google Cloud Storage
- Refresh the access token using a local refresh token
- Refresh using a GCS refresh token if the local copy is missing or invalid
- Run the OAuth workflow if no refresh tokens are available
- Perfect for automated scripts and services that need reliable token rotation
When you run the program, you'll see:
=== GETTING FRESH TOKENS ===
Getting new Schwab tokens...
1. Visit this URL: https://api.schwabapi.com/v1/oauth/authorize?client_id=...
2. Log in and authorize the app
3. You'll be redirected to a URL that looks like:
https://127.0.0.1/?code=LONG_CODE_HERE&session=...
4. Copy the ENTIRE redirect URL
Paste the full redirect URL here: [YOU PASTE THE URL HERE]
Extracted code: ABC123...
Tokens obtained successfully!
Access Token: eyJ0eXAiOiJKV1QiLCJ...
Refresh Token: eyJ0eXAiOiJKV1QiLCJ...
Refresh token saved to schwab_refresh_token.txt
File schwab_refresh_token.txt uploaded to schwab_refresh_token.txt.
✅ Tokens obtained and uploaded to GCS successfully!
Initializes the authenticator with credentials from environment variables.
Environment Variables Required:
SCHWAB_APP_KEY: Your Schwab application keySCHWAB_APP_SECRET: Your Schwab application secretGCS_BUCKET_NAME: Your Google Cloud Storage bucket name (optional)GOOGLE_APPLICATION_CREDENTIALS: Path to your GCS service account key file (optional)
Main method to get a valid access token.
Parameters:
use_gcs_refresh_token(bool): If True, attempts to use GCS-stored refresh token first
Returns:
str: Valid access token, or None if authentication fails
Example:
from schwab_authentication_client import SchwabAuthenticationClient
auth = SchwabAuthenticationClient()
# Unified workflow (automatically handles cache → GCS → refresh → OAuth)
access_token = auth.get_valid_access_token()Retrieves a refresh token by checking local storage first, then Google Cloud Storage, and optionally triggering the OAuth workflow.
Convenience wrapper around get_valid_access_token() for backwards compatibility.
Persists and retrieves the cached access token file.
Handles the complete fresh token generation workflow.
Returns:
str: Refresh token, or None if authentication fails
Example:
auth = SchwabAuth()
refresh_token = auth.automated_token_management()Refreshes access token using refresh token.
Parameters:
refresh_token(str): The refresh token to useapp_key(str): Your Schwab application keyapp_secret(str): Your Schwab application secret
Returns:
str: New access token, or None if refresh fails
Saves refresh token to local file.
Parameters:
refresh_token(str): The refresh token to save
Loads refresh token from local file.
Returns:
str: Refresh token if found, None otherwise
Uploads the local refresh token file to Google Cloud Storage.
Downloads refresh token from Google Cloud Storage to local file.
Returns:
str: Refresh token if download successful, None otherwise
from schwab_authentication_client import SchwabAuthenticationClient
auth = SchwabAuthenticationClient()
# Unified token retrieval (local cache → GCS cache → refresh → OAuth)
access_token = auth.get_valid_access_token()
# Use the token for API calls
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
# Make API requests
import requests
response = requests.get('https://api.schwabapi.com/v1/accounts', headers=headers)from schwab_authentication_client import SchwabAuthenticationClient
auth = SchwabAuthenticationClient()
access_token = auth.get_valid_access_token()
# Use token for WebSocket authentication
streaming_client.login_with_token(access_token)from schwab_authentication_client import SchwabAuthenticationClient
import time
def get_schwab_data():
auth = SchwabAuthenticationClient()
access_token = auth.get_valid_access_token()
return access_token
# Use in automated scripts
access_token = get_schwab_data()charles-schwab-authentication-module/
├── schwab_authentication_client.py # Main authentication client
├── schwab_access_token.txt # Stored access token (auto-generated)
├── schwab_refresh_token.txt # Stored refresh token (auto-generated)
├── .env # Environment variables (you create this)
├── requirements.txt # Python dependencies
├── README.md # This file
├── .gitmodules # Git submodule configuration
└── google-cloud-storage-client/ # Google Cloud Storage module
├── google_cloud_storage_client.py # GCS client class
├── requirements.txt # GCS module dependencies
├── README.md # GCS module documentation
└── tests/ # GCS module tests
├── integration_test.py
└── README.md
| Variable | Description | Required | Default |
|---|---|---|---|
SCHWAB_APP_KEY |
Your Schwab application key | Yes | - |
SCHWAB_APP_SECRET |
Your Schwab application secret | Yes | - |
GCS_BUCKET_NAME |
Your Google Cloud Storage bucket name | No | - |
GOOGLE_APPLICATION_CREDENTIALS |
Path to your GCS service account key file | No | - |
The module includes comprehensive error handling for:
- Missing environment variables
- API request failures
- Invalid authorization codes
- Token refresh failures
- File I/O errors
- Google Cloud Storage operation failures
- Network connectivity issues
- Authentication flow interruptions
- Never commit your
.envfile to version control - Keep your App Key and App Secret secure
- The refresh token file contains sensitive data - protect it accordingly
- Use HTTPS in production environments
- Store your Google Cloud service account key securely
- Consider using Google Cloud Secret Manager for production deployments
- Rotate credentials regularly for enhanced security
-
"No valid refresh token available"
- Solution: Run the program again to get fresh tokens
- Check: Ensure GCS bucket exists and is accessible
-
"Error getting tokens"
- Check: Your App Key and App Secret are correct
- Verify: Redirect URI matches your app configuration
- Ensure: Authorization code is complete and unmodified
-
"Failed to get access token"
- Try: Running the program again to get fresh tokens
- Check: Internet connection and API credentials
- Verify: Refresh token hasn't expired
-
Google Cloud Storage Errors
- Verify: Service account has correct permissions
- Check: Bucket name is correct and exists
- Ensure: Service account key file path is correct
- Test: GCS connectivity and bucket access
-
Environment Variable Issues
- Missing .env file: Create
.envfile by copyinggcs-python-module/env.example - GCS_BUCKET_NAME is None: Add your bucket name to the
.envfile - GOOGLE_APPLICATION_CREDENTIALS not found: Ensure the path to your service account key is correct
- SCHWAB credentials not loaded: Verify your App Key and App Secret are correct in
.env
- Missing .env file: Create
-
Virtual Environment Issues
- Ensure: Virtual environment is activated before installing dependencies
- Fix: Use
venv\Scripts\activateon Windows instead ofsource venv/bin/activate - Reinstall:
pip install -r requirements.txtif packages aren't found
-
Git Submodule Issues
- Initialize:
git submodule init && git submodule update - Recursive:
git submodule update --init --recursive - Verify:
gcs-python-module/directory exists and containsgcs_client.py
- Initialize:
For debugging, you can add print statements or modify the error messages in the class methods:
# Enable debug output
import logging
logging.basicConfig(level=logging.DEBUG)
# Or add debug prints
auth = SchwabAuth()
print(f"App Key: {auth.APP_KEY[:10]}...")
print(f"GCS Bucket: {auth.GCS_BUCKET_NAME}")The project includes a comprehensive Google Cloud Storage module (gcs-python-module/) that provides:
- Service Account Authentication: Secure authentication using service account keys
- Comprehensive Operations: Upload, download, list, delete, and manage files and buckets
- Error Handling: Robust error handling with detailed logging
- Type Hints: Full type annotation support for better development experience
- Testing: Integration tests for all GCS operations
See the gcs-python-module/README.md for detailed documentation on the GCS client functionality.
Run tests with pytest:
pytest tests/- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
This tool is for educational and development purposes. Always follow Charles Schwab's API terms of service and rate limiting guidelines. The tool is not intended for production trading without proper testing and validation.
For issues related to:
- Schwab API: Contact Charles Schwab Developer Support
- Google Cloud Storage: Check the GCS module documentation
- This Tool: Open an issue in this repository
- Integration: Check the parent project documentation
- Enhanced GCS Integration: Improved token management with fallback options
- Better Error Handling: More comprehensive error scenarios and recovery
- Updated Documentation: Comprehensive README with integration examples
- Python 3.8+ Support: Updated minimum Python version requirement
- Added Google Cloud Storage Integration: Automatic token upload to GCS
- Modular Architecture: Separated GCS functionality into dedicated module
- Enhanced Security: Cloud-based token backup and storage
- Comprehensive GCS Client: Full GCS operations support
- Updated Dependencies: Added Google Cloud Storage requirements
- Initial Release: Class-based architecture
- Fresh Token Generation: Always gets fresh tokens on every run
- Token Persistence: Saves refresh tokens for reference
- Comprehensive Error Handling: Robust error handling for API calls