Python client for the OG Pilot Open Graph image generator with Django integration
Project description
OG Pilot Python
A Python client for generating OG Pilot Open Graph images via signed JWTs, with first-class Django integration.
Installation
pip install og-pilot
For Django integration:
pip install og-pilot[django]
Quick Start
Basic Usage
import og_pilot
# Configure globally (reads from OG_PILOT_API_KEY and OG_PILOT_DOMAIN env vars by default)
og_pilot.configure(
api_key="your-api-key",
domain="example.com"
)
# Generate an image URL
image_url = og_pilot.create_image(
template="blog_post",
title="How to Build Amazing OG Images",
description="A complete guide to social media previews",
author_name="Jane Smith",
)
print(image_url)
# https://ogpilot.com/api/v1/images?token=eyJ...
Using Environment Variables
The SDK automatically reads from environment variables:
export OG_PILOT_API_KEY="your-api-key"
export OG_PILOT_DOMAIN="example.com"
import og_pilot
# No configuration needed - uses env vars
url = og_pilot.create_image(title="My Page", template="default")
Cache Busting with iat
By default, OG Pilot caches images indefinitely. Use iat (issued at) to refresh the cache:
import time
from datetime import datetime
# Using Unix timestamp
url = og_pilot.create_image(
title="My Post",
template="blog",
iat=int(time.time()) # Changes daily
)
# Using datetime
url = og_pilot.create_image(
title="My Post",
template="blog",
iat=datetime.now()
)
Get JSON Metadata
data = og_pilot.create_image(
title="Hello OG Pilot",
template="page",
json=True
)
print(data) # {"url": "...", "width": 1200, "height": 630, ...}
Custom Client Instance
For multiple configurations or dependency injection:
from og_pilot import create_client
client = create_client(
api_key="your-api-key",
domain="example.com",
open_timeout=10,
read_timeout=30,
)
url = client.create_image({"template": "default", "title": "Hello"})
Django Integration
1. Add to Installed Apps
# settings.py
INSTALLED_APPS = [
# ...
'og_pilot.django',
]
2. Configure Settings
# settings.py
# Option 1: Using settings dict
OG_PILOT = {
'API_KEY': 'your-api-key', # or use OG_PILOT_API_KEY env var
'DOMAIN': 'example.com', # or use OG_PILOT_DOMAIN env var
# Optional:
# 'BASE_URL': 'https://ogpilot.com',
# 'OPEN_TIMEOUT': 5,
# 'READ_TIMEOUT': 10,
}
# Option 2: Using environment variables (no settings needed)
# Just set OG_PILOT_API_KEY and OG_PILOT_DOMAIN
3. Verify Configuration
python manage.py og_pilot_check
python manage.py og_pilot_check --test # Also sends a test request
4. Use in Templates
{% load og_pilot_tags %}
<!DOCTYPE html>
<html>
<head>
<!-- Option 1: Generate URL and use manually -->
{% og_pilot_image title=page.title template="blog_post" as og_image_url %}
<meta property="og:image" content="{{ og_image_url }}" />
<meta property="og:title" content="{{ page.title }}" />
<!-- Option 2: Simple tag (outputs URL directly) -->
<meta property="og:image" content="{% og_pilot_url title=page.title template='default' %}" />
<!-- Option 3: Complete meta tags (requires template) -->
{% og_pilot_meta_tags title=page.title description=page.description template="blog" %}
</head>
<body>
...
</body>
</html>
5. Use in Views
from django.shortcuts import render
import og_pilot
def blog_post(request, slug):
post = get_object_or_404(Post, slug=slug)
og_image_url = og_pilot.create_image(
template="blog_post",
title=post.title,
description=post.excerpt,
author_name=post.author.name,
publish_date=post.published_at.strftime("%Y-%m-%d"),
)
return render(request, 'blog/post.html', {
'post': post,
'og_image_url': og_image_url,
})
Custom Meta Tags Template
Create templates/og_pilot/meta_tags.html in your project to customize the output of {% og_pilot_meta_tags %}:
<!-- templates/og_pilot/meta_tags.html -->
<meta property="og:title" content="{{ title }}" />
<meta property="og:description" content="{{ description }}" />
<meta property="og:image" content="{{ image_url }}" />
<meta property="og:type" content="article" />
<meta property="og:site_name" content="{{ site_name }}" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{{ title }}" />
<meta name="twitter:description" content="{{ description }}" />
<meta name="twitter:image" content="{{ image_url }}" />
Configuration Options
| Option | Environment Variable | Default | Description |
|---|---|---|---|
api_key |
OG_PILOT_API_KEY |
None | Your OG Pilot API key (required) |
domain |
OG_PILOT_DOMAIN |
None | Your registered domain (required) |
base_url |
- | https://ogpilot.com |
OG Pilot API URL |
open_timeout |
- | 5 |
Connection timeout (seconds) |
read_timeout |
- | 10 |
Read timeout (seconds) |
Error Handling
from og_pilot import create_image
from og_pilot.exceptions import ConfigurationError, RequestError
try:
url = create_image(title="My Post", template="blog")
except ConfigurationError as e:
# Missing API key or domain
print(f"Configuration error: {e}")
except RequestError as e:
# API request failed
print(f"Request error: {e}")
if e.status_code:
print(f"Status code: {e.status_code}")
except ValueError as e:
# Missing required parameter (e.g., title)
print(f"Validation error: {e}")
API Reference
Module-level Functions
og_pilot.configure(**kwargs)- Configure the global clientog_pilot.reset_config()- Reset to default configurationog_pilot.get_config()- Get the current configurationog_pilot.client()- Get a client using global configog_pilot.create_client(**kwargs)- Create a new client with custom configog_pilot.create_image(params, *, json=False, iat=None, headers=None, **kwargs)- Generate image URL
Client Class
from og_pilot import Client, Configuration
config = Configuration(api_key="...", domain="...")
client = Client(config)
# Generate URL
url = client.create_image(
params={"template": "default", "title": "Hello"},
json_response=False, # Set True for JSON metadata
iat=None, # Optional cache busting timestamp
headers={}, # Optional additional headers
)
Development
# Clone the repository
git clone https://github.com/sunergos-ro/og-pilot-python.git
cd og-pilot-python
# Create virtual environment
python -m venv .venv
source .venv/bin/activate
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linter
ruff check .
# Run type checker
mypy og_pilot
Publishing to PyPI
This section explains how to publish the package to PyPI so users can install it with pip install og-pilot.
Prerequisites
-
Create PyPI Account: Register at https://pypi.org/account/register/
-
Create API Token: Go to https://pypi.org/manage/account/token/ and create a token with "Upload packages" scope.
-
Install Build Tools:
pip install build twine
Publishing Steps
1. Update Version
Edit pyproject.toml and og_pilot/__init__.py to update the version number:
# og_pilot/__init__.py
__version__ = "0.2.0" # New version
# pyproject.toml
[project]
version = "0.2.0"
2. Build the Package
# Clean previous builds
rm -rf dist/ build/ *.egg-info
# Build source distribution and wheel
python -m build
This creates:
dist/og_pilot-0.1.0.tar.gz(source distribution)dist/og_pilot-0.1.0-py3-none-any.whl(wheel)
3. Test on TestPyPI (Optional but Recommended)
# Upload to TestPyPI first
twine upload --repository testpypi dist/*
# Test installation from TestPyPI
pip install --index-url https://test.pypi.org/simple/ og-pilot
4. Upload to PyPI
# Upload to production PyPI
twine upload dist/*
You'll be prompted for credentials:
- Username:
__token__ - Password: Your PyPI API token (starts with
pypi-)
5. Configure Credentials (Optional)
To avoid entering credentials each time, create ~/.pypirc:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-YOUR-TOKEN-HERE
[testpypi]
username = __token__
password = pypi-YOUR-TESTPYPI-TOKEN-HERE
Then secure it:
chmod 600 ~/.pypirc
Automated Publishing with GitHub Actions
Create .github/workflows/publish.yml:
name: Publish to PyPI
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write # Required for trusted publishing
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install build dependencies
run: pip install build
- name: Build package
run: python -m build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
# Uses trusted publishing - configure at pypi.org
Setting Up Trusted Publishing
- Go to your PyPI project: https://pypi.org/manage/project/og-pilot/settings/publishing/
- Add a new publisher:
- Owner:
sunergos-ro - Repository:
og-pilot-python - Workflow:
publish.yml - Environment:
release
- Owner:
Version Numbering
Follow Semantic Versioning:
MAJOR.MINOR.PATCH(e.g.,1.2.3)- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
Release Checklist
- Update version in
pyproject.tomlandog_pilot/__init__.py - Update CHANGELOG (if you have one)
- Run tests:
pytest - Run linter:
ruff check . - Run type checker:
mypy og_pilot - Build:
python -m build - Test locally:
pip install dist/*.whl - Upload to TestPyPI (optional)
- Upload to PyPI
- Create GitHub release with tag
v0.1.0
License
MIT License - see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file og_pilot-0.1.0.tar.gz.
File metadata
- Download URL: og_pilot-0.1.0.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ba6e9a3eb7566a70e5d0e0079ca6bc8dc59a6ea9ea3d222588613f7ee2009fc
|
|
| MD5 |
ee801b4c267322d7286eb8d029c098ae
|
|
| BLAKE2b-256 |
3f532159088ec79f1d3f9e191b9363deaea254deb1f87698179d923e9d84deae
|
File details
Details for the file og_pilot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: og_pilot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d0982aeb438ded6eb64b78efc77746636aee3f4cc3669fc4c6b0f8a595089ed
|
|
| MD5 |
db1cae6d71ff2c492aaf4df67df92c6e
|
|
| BLAKE2b-256 |
feeb7c686db049c263dc934f809985b97fe1ab0913b5b2b81fd0222684d5b372
|