OAuth2 Capture for Django
Store and manage OAuth2 tokens for ongoing API access to social media platforms.
Your Django app needs to post tweets for users. Your CRM creates GitHub repos in client organizations. Your marketing tool schedules LinkedIn posts for customers.
This package captures and manages the OAuth2 tokens that make these use cases possible.
Who This Is For
✅ Building social media management tools ✅ Creating GitHub integrations that act on behalf of users ✅ Need ongoing API access, not just authentication
❌ Just want social login for your Django app → Use django-allauth instead
Supported Providers
- Twitter/X - Post tweets, read timelines, manage accounts
- LinkedIn - Share posts, manage company pages, access connections
- GitHub - Create repos, manage issues, access organization data
- Reddit - Post content, read feeds, manage subreddits
- Pinterest - Create pins, manage boards
- Facebook - Publish posts, manage pages (limited by Facebook policies)
Planned: Instagram, YouTube, TikTok
What This Package Does vs django-allauth
oauth2_capture solves: "I need my app to post tweets/LinkedIn updates FOR my users"
- Your app posts to Twitter using Jane's account
- Your app creates GitHub repos in John's organizations
- Your app schedules LinkedIn posts for your marketing clients
django-allauth solves: "I need users to log into my site with social accounts"
- Users click "Login with Google" to access your Django app
- You create user profiles from their social account data
- You manage user sessions and permissions
Can you use both? Yes! allauth for login, oauth2_capture for API actions.
Quick Start (5 minutes)
1. Install
uv add git+https://github.com/heysamtexas/django-oauth2-capture.git@master
2. Add to Django Settings
INSTALLED_APPS = [
...
'oauth2_capture',
...
]
3. Run Migrations
python manage.py migrate
4. Add URLs
# urls.py
from django.urls import path, include
urlpatterns = [
...
path('oauth2/', include('oauth2_capture.urls')),
...
]
5. Verify Setup
python manage.py check oauth2_capture
Expected output: "System check identified no issues"
If error: Check INSTALLED_APPS includes 'oauth2_capture'
Provider Setup
Choose a provider to get started. Each requires different setup steps and credentials.
Twitter (Recommended for beginners)
- Create app at developer.twitter.com
- Copy Client ID and Secret
- Add to settings:
OAUTH2_CONFIG = { "twitter": { "client_id": "your_twitter_client_id", "client_secret": "your_twitter_client_secret", "scope": "tweet.read users.read tweet.write offline.access", "code_verifier": "challenge", # Required for Twitter } }
- Test: Visit
/oauth2/twitter/connect/- should redirect to Twitter
GitHub (For development tools)
- Go to GitHub Settings → Developer settings → OAuth Apps
- Create new OAuth App with redirect URI:
http://localhost:8000/oauth2/github/callback/ - Add to settings:
OAUTH2_CONFIG = { "github": { "client_id": "your_github_client_id", "client_secret": "your_github_client_secret", "scope": "user repo", # Minimal scopes to start } }
LinkedIn (For business applications)
- Create app at LinkedIn Developer Portal
- Request necessary permissions (may require approval)
- Add to settings:
OAUTH2_CONFIG = { "linkedin": { "client_id": "your_linkedin_client_id", "client_secret": "your_linkedin_client_secret", "scope": "profile email openid w_member_social", } }
Usage
1. Create Connection Links
<a href="{% url 'oauth2_capture:initiate_oauth2' 'twitter' %}">Connect Twitter</a>
<a href="{% url 'oauth2_capture:initiate_oauth2' 'github' %}">Connect GitHub</a>
2. Access Tokens in Your Views
from oauth2_capture.models import OAuth2Token
def my_view(request):
# Get a user's GitHub token
token = OAuth2Token.objects.filter(
owner=request.user,
provider='github'
).first()
if token:
# Use the token to make API requests
access_token = token.access_token
# ...
For more detailed examples, check out the demo app in the development/ directory of the repository, which shows complete implementation examples for all supported providers.
Adding a new provider
class NewProviderOAuth2Provider(OAuth2Provider):
@property
def authorize_url(self) -> str:
return "https://newprovider.com/oauth/authorize"
@property
def token_url(self) -> str:
return "https://newprovider.com/oauth/token"
@property
def user_info_url(self) -> str:
return "https://api.newprovider.com/userinfo"
def get_user_info(self, access_token: str) -> dict:
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(self.user_info_url, headers=headers, timeout=10)
return response.json()
def exchange_code_for_token(self, code: str, redirect_uri: str) -> dict:
data = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": redirect_uri,
"client_id": self.config["client_id"],
"client_secret": self.config["client_secret"],
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
response = requests.post(self.token_url, data=data, headers=headers, timeout=10)
return response.json()
User Flow
The following is a simplified user flow for how we obtain and save the oauth tokens. The flow is as follows:
sequenceDiagram
participant U as User
participant C as Client
participant P as Provider
U->>C: Clicks on "connect" with provider
C->>P: Redirects to provider's authorize URL
P->>C: Redirects to client's redirect URI with code
C->>P: Exchanges code for token
P->>C: Returns token
C->>P: Retrieves user info
P->>C: Returns user info
C->>U: Redirects to home page
C->>C: Save or update the user token in database
Note: if the user is not logged in at their provider, they will be prompted to login before they can authorize the client. (This is not shown in the diagram)
Setting up your development environment
- Clone the repository
- Create a virtual environment
- Install the requirements
- Configure the environment variables
- Acquire the client ID and client secret from the providers
- Put client_id and secrets into local
envfile in thedevelopment/folder
- Migrate the database with
python manage.py migrate
Setup each provider by following the instructions in the docs/ folder.
License
- see LICENSE file
Appendix
Provider's endpoints, docs, etc
Metadata
Release files for oauth2-capture 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| oauth2_capture-0.6.0.tar.gz | 214.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| oauth2_capture-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 238.3 kB
Release files / oauth2_capture-0.6.0.tar.gz
| Download URL | oauth2_capture-0.6.0.tar.gz |
|---|---|
| Size | 214.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a32d731c1cb00299cb7c04a85bbd0cc58006d639f26aa52ca8e92d839112eaa
|
|
BLAKE2b-256 checksum How to use checksums |
810570940df52468a2cd97bcff125783584fe69be54223f8b99a122234bb8635
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2025.
Transparency logRelease files / oauth2_capture-0.6.0-py3-none-any.whl
| Download URL | oauth2_capture-0.6.0-py3-none-any.whl |
|---|---|
| Size | 23.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f82680526213433f55baa5216cb0782c8d81417674e2884f5dccca1ec41566e6
|
|
BLAKE2b-256 checksum How to use checksums |
99e82f838c4216ad52e68e86cac65d893aaf6b43d632325414660eb56039a6a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2025.
Transparency log