og-pilot 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Environments
54
+ .env
55
+ .venv
56
+ env/
57
+ venv/
58
+ ENV/
59
+ env.bak/
60
+ venv.bak/
61
+
62
+ # IDE
63
+ .idea/
64
+ .vscode/
65
+ *.swp
66
+ *.swo
67
+ *~
68
+
69
+ # mypy
70
+ .mypy_cache/
71
+ .dmypy.json
72
+ dmypy.json
73
+
74
+ # ruff
75
+ .ruff_cache/
76
+
77
+ # OS
78
+ .DS_Store
79
+ Thumbs.db
80
+ .venv/
og_pilot-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sunergos IT LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,502 @@
1
+ Metadata-Version: 2.4
2
+ Name: og-pilot
3
+ Version: 0.1.0
4
+ Summary: Python client for the OG Pilot Open Graph image generator with Django integration
5
+ Project-URL: Homepage, https://ogpilot.com
6
+ Project-URL: Documentation, https://ogpilot.com/docs
7
+ Project-URL: Repository, https://github.com/sunergos-ro/og-pilot-python
8
+ Project-URL: Issues, https://github.com/sunergos-ro/og-pilot-python/issues
9
+ Project-URL: Changelog, https://github.com/sunergos-ro/og-pilot-python/commits/main
10
+ Author-email: Sunergos IT LLC <office@sunergos.ro>, Raul Popadineti <raul@sunergos.ro>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: django,meta-tags,og-image,og-pilot,open-graph,seo,social-media
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Web Environment
16
+ Classifier: Framework :: Django
17
+ Classifier: Framework :: Django :: 4.2
18
+ Classifier: Framework :: Django :: 5.0
19
+ Classifier: Framework :: Django :: 5.1
20
+ Classifier: Intended Audience :: Developers
21
+ Classifier: License :: OSI Approved :: MIT License
22
+ Classifier: Operating System :: OS Independent
23
+ Classifier: Programming Language :: Python :: 3
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Programming Language :: Python :: 3.13
28
+ Classifier: Topic :: Internet :: WWW/HTTP
29
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
30
+ Requires-Python: >=3.10
31
+ Requires-Dist: pyjwt>=2.0.0
32
+ Requires-Dist: requests>=2.25.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: django>=4.2; extra == 'dev'
35
+ Requires-Dist: mypy>=1.0; extra == 'dev'
36
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
37
+ Requires-Dist: pytest>=7.0; extra == 'dev'
38
+ Requires-Dist: responses>=0.23.0; extra == 'dev'
39
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
40
+ Requires-Dist: types-requests>=2.31.0; extra == 'dev'
41
+ Provides-Extra: django
42
+ Requires-Dist: django>=4.2; extra == 'django'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # OG Pilot Python
46
+
47
+ A Python client for generating OG Pilot Open Graph images via signed JWTs, with first-class Django integration.
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ pip install og-pilot
53
+ ```
54
+
55
+ For Django integration:
56
+
57
+ ```bash
58
+ pip install og-pilot[django]
59
+ ```
60
+
61
+ ## Quick Start
62
+
63
+ ### Basic Usage
64
+
65
+ ```python
66
+ import og_pilot
67
+
68
+ # Configure globally (reads from OG_PILOT_API_KEY and OG_PILOT_DOMAIN env vars by default)
69
+ og_pilot.configure(
70
+ api_key="your-api-key",
71
+ domain="example.com"
72
+ )
73
+
74
+ # Generate an image URL
75
+ image_url = og_pilot.create_image(
76
+ template="blog_post",
77
+ title="How to Build Amazing OG Images",
78
+ description="A complete guide to social media previews",
79
+ author_name="Jane Smith",
80
+ )
81
+
82
+ print(image_url)
83
+ # https://ogpilot.com/api/v1/images?token=eyJ...
84
+ ```
85
+
86
+ ### Using Environment Variables
87
+
88
+ The SDK automatically reads from environment variables:
89
+
90
+ ```bash
91
+ export OG_PILOT_API_KEY="your-api-key"
92
+ export OG_PILOT_DOMAIN="example.com"
93
+ ```
94
+
95
+ ```python
96
+ import og_pilot
97
+
98
+ # No configuration needed - uses env vars
99
+ url = og_pilot.create_image(title="My Page", template="default")
100
+ ```
101
+
102
+ ### Cache Busting with `iat`
103
+
104
+ By default, OG Pilot caches images indefinitely. Use `iat` (issued at) to refresh the cache:
105
+
106
+ ```python
107
+ import time
108
+ from datetime import datetime
109
+
110
+ # Using Unix timestamp
111
+ url = og_pilot.create_image(
112
+ title="My Post",
113
+ template="blog",
114
+ iat=int(time.time()) # Changes daily
115
+ )
116
+
117
+ # Using datetime
118
+ url = og_pilot.create_image(
119
+ title="My Post",
120
+ template="blog",
121
+ iat=datetime.now()
122
+ )
123
+ ```
124
+
125
+ ### Get JSON Metadata
126
+
127
+ ```python
128
+ data = og_pilot.create_image(
129
+ title="Hello OG Pilot",
130
+ template="page",
131
+ json=True
132
+ )
133
+ print(data) # {"url": "...", "width": 1200, "height": 630, ...}
134
+ ```
135
+
136
+ ### Custom Client Instance
137
+
138
+ For multiple configurations or dependency injection:
139
+
140
+ ```python
141
+ from og_pilot import create_client
142
+
143
+ client = create_client(
144
+ api_key="your-api-key",
145
+ domain="example.com",
146
+ open_timeout=10,
147
+ read_timeout=30,
148
+ )
149
+
150
+ url = client.create_image({"template": "default", "title": "Hello"})
151
+ ```
152
+
153
+ ## Django Integration
154
+
155
+ ### 1. Add to Installed Apps
156
+
157
+ ```python
158
+ # settings.py
159
+ INSTALLED_APPS = [
160
+ # ...
161
+ 'og_pilot.django',
162
+ ]
163
+ ```
164
+
165
+ ### 2. Configure Settings
166
+
167
+ ```python
168
+ # settings.py
169
+
170
+ # Option 1: Using settings dict
171
+ OG_PILOT = {
172
+ 'API_KEY': 'your-api-key', # or use OG_PILOT_API_KEY env var
173
+ 'DOMAIN': 'example.com', # or use OG_PILOT_DOMAIN env var
174
+ # Optional:
175
+ # 'BASE_URL': 'https://ogpilot.com',
176
+ # 'OPEN_TIMEOUT': 5,
177
+ # 'READ_TIMEOUT': 10,
178
+ }
179
+
180
+ # Option 2: Using environment variables (no settings needed)
181
+ # Just set OG_PILOT_API_KEY and OG_PILOT_DOMAIN
182
+ ```
183
+
184
+ ### 3. Verify Configuration
185
+
186
+ ```bash
187
+ python manage.py og_pilot_check
188
+ python manage.py og_pilot_check --test # Also sends a test request
189
+ ```
190
+
191
+ ### 4. Use in Templates
192
+
193
+ ```html
194
+ {% load og_pilot_tags %}
195
+
196
+ <!DOCTYPE html>
197
+ <html>
198
+ <head>
199
+ <!-- Option 1: Generate URL and use manually -->
200
+ {% og_pilot_image title=page.title template="blog_post" as og_image_url %}
201
+ <meta property="og:image" content="{{ og_image_url }}" />
202
+ <meta property="og:title" content="{{ page.title }}" />
203
+
204
+ <!-- Option 2: Simple tag (outputs URL directly) -->
205
+ <meta property="og:image" content="{% og_pilot_url title=page.title template='default' %}" />
206
+
207
+ <!-- Option 3: Complete meta tags (requires template) -->
208
+ {% og_pilot_meta_tags title=page.title description=page.description template="blog" %}
209
+ </head>
210
+ <body>
211
+ ...
212
+ </body>
213
+ </html>
214
+ ```
215
+
216
+ ### 5. Use in Views
217
+
218
+ ```python
219
+ from django.shortcuts import render
220
+ import og_pilot
221
+
222
+ def blog_post(request, slug):
223
+ post = get_object_or_404(Post, slug=slug)
224
+
225
+ og_image_url = og_pilot.create_image(
226
+ template="blog_post",
227
+ title=post.title,
228
+ description=post.excerpt,
229
+ author_name=post.author.name,
230
+ publish_date=post.published_at.strftime("%Y-%m-%d"),
231
+ )
232
+
233
+ return render(request, 'blog/post.html', {
234
+ 'post': post,
235
+ 'og_image_url': og_image_url,
236
+ })
237
+ ```
238
+
239
+ ### Custom Meta Tags Template
240
+
241
+ Create `templates/og_pilot/meta_tags.html` in your project to customize the output of `{% og_pilot_meta_tags %}`:
242
+
243
+ ```html
244
+ <!-- templates/og_pilot/meta_tags.html -->
245
+ <meta property="og:title" content="{{ title }}" />
246
+ <meta property="og:description" content="{{ description }}" />
247
+ <meta property="og:image" content="{{ image_url }}" />
248
+ <meta property="og:type" content="article" />
249
+ <meta property="og:site_name" content="{{ site_name }}" />
250
+
251
+ <meta name="twitter:card" content="summary_large_image" />
252
+ <meta name="twitter:title" content="{{ title }}" />
253
+ <meta name="twitter:description" content="{{ description }}" />
254
+ <meta name="twitter:image" content="{{ image_url }}" />
255
+ ```
256
+
257
+ ## Configuration Options
258
+
259
+ | Option | Environment Variable | Default | Description |
260
+ |--------|---------------------|---------|-------------|
261
+ | `api_key` | `OG_PILOT_API_KEY` | None | Your OG Pilot API key (required) |
262
+ | `domain` | `OG_PILOT_DOMAIN` | None | Your registered domain (required) |
263
+ | `base_url` | - | `https://ogpilot.com` | OG Pilot API URL |
264
+ | `open_timeout` | - | `5` | Connection timeout (seconds) |
265
+ | `read_timeout` | - | `10` | Read timeout (seconds) |
266
+
267
+ ## Error Handling
268
+
269
+ ```python
270
+ from og_pilot import create_image
271
+ from og_pilot.exceptions import ConfigurationError, RequestError
272
+
273
+ try:
274
+ url = create_image(title="My Post", template="blog")
275
+ except ConfigurationError as e:
276
+ # Missing API key or domain
277
+ print(f"Configuration error: {e}")
278
+ except RequestError as e:
279
+ # API request failed
280
+ print(f"Request error: {e}")
281
+ if e.status_code:
282
+ print(f"Status code: {e.status_code}")
283
+ except ValueError as e:
284
+ # Missing required parameter (e.g., title)
285
+ print(f"Validation error: {e}")
286
+ ```
287
+
288
+ ## API Reference
289
+
290
+ ### Module-level Functions
291
+
292
+ - `og_pilot.configure(**kwargs)` - Configure the global client
293
+ - `og_pilot.reset_config()` - Reset to default configuration
294
+ - `og_pilot.get_config()` - Get the current configuration
295
+ - `og_pilot.client()` - Get a client using global config
296
+ - `og_pilot.create_client(**kwargs)` - Create a new client with custom config
297
+ - `og_pilot.create_image(params, *, json=False, iat=None, headers=None, **kwargs)` - Generate image URL
298
+
299
+ ### Client Class
300
+
301
+ ```python
302
+ from og_pilot import Client, Configuration
303
+
304
+ config = Configuration(api_key="...", domain="...")
305
+ client = Client(config)
306
+
307
+ # Generate URL
308
+ url = client.create_image(
309
+ params={"template": "default", "title": "Hello"},
310
+ json_response=False, # Set True for JSON metadata
311
+ iat=None, # Optional cache busting timestamp
312
+ headers={}, # Optional additional headers
313
+ )
314
+ ```
315
+
316
+ ## Development
317
+
318
+ ```bash
319
+ # Clone the repository
320
+ git clone https://github.com/sunergos-ro/og-pilot-python.git
321
+ cd og-pilot-python
322
+
323
+ # Create virtual environment
324
+ python -m venv .venv
325
+ source .venv/bin/activate
326
+
327
+ # Install dev dependencies
328
+ pip install -e ".[dev]"
329
+
330
+ # Run tests
331
+ pytest
332
+
333
+ # Run linter
334
+ ruff check .
335
+
336
+ # Run type checker
337
+ mypy og_pilot
338
+ ```
339
+
340
+ ---
341
+
342
+ # Publishing to PyPI
343
+
344
+ This section explains how to publish the package to PyPI so users can install it with `pip install og-pilot`.
345
+
346
+ ## Prerequisites
347
+
348
+ 1. **Create PyPI Account**: Register at https://pypi.org/account/register/
349
+
350
+ 2. **Create API Token**: Go to https://pypi.org/manage/account/token/ and create a token with "Upload packages" scope.
351
+
352
+ 3. **Install Build Tools**:
353
+ ```bash
354
+ pip install build twine
355
+ ```
356
+
357
+ ## Publishing Steps
358
+
359
+ ### 1. Update Version
360
+
361
+ Edit `pyproject.toml` and `og_pilot/__init__.py` to update the version number:
362
+
363
+ ```python
364
+ # og_pilot/__init__.py
365
+ __version__ = "0.2.0" # New version
366
+ ```
367
+
368
+ ```toml
369
+ # pyproject.toml
370
+ [project]
371
+ version = "0.2.0"
372
+ ```
373
+
374
+ ### 2. Build the Package
375
+
376
+ ```bash
377
+ # Clean previous builds
378
+ rm -rf dist/ build/ *.egg-info
379
+
380
+ # Build source distribution and wheel
381
+ python -m build
382
+ ```
383
+
384
+ This creates:
385
+ - `dist/og_pilot-0.1.0.tar.gz` (source distribution)
386
+ - `dist/og_pilot-0.1.0-py3-none-any.whl` (wheel)
387
+
388
+ ### 3. Test on TestPyPI (Optional but Recommended)
389
+
390
+ ```bash
391
+ # Upload to TestPyPI first
392
+ twine upload --repository testpypi dist/*
393
+
394
+ # Test installation from TestPyPI
395
+ pip install --index-url https://test.pypi.org/simple/ og-pilot
396
+ ```
397
+
398
+ ### 4. Upload to PyPI
399
+
400
+ ```bash
401
+ # Upload to production PyPI
402
+ twine upload dist/*
403
+ ```
404
+
405
+ You'll be prompted for credentials:
406
+ - Username: `__token__`
407
+ - Password: Your PyPI API token (starts with `pypi-`)
408
+
409
+ ### 5. Configure Credentials (Optional)
410
+
411
+ To avoid entering credentials each time, create `~/.pypirc`:
412
+
413
+ ```ini
414
+ [distutils]
415
+ index-servers =
416
+ pypi
417
+ testpypi
418
+
419
+ [pypi]
420
+ username = __token__
421
+ password = pypi-YOUR-TOKEN-HERE
422
+
423
+ [testpypi]
424
+ username = __token__
425
+ password = pypi-YOUR-TESTPYPI-TOKEN-HERE
426
+ ```
427
+
428
+ Then secure it:
429
+ ```bash
430
+ chmod 600 ~/.pypirc
431
+ ```
432
+
433
+ ## Automated Publishing with GitHub Actions
434
+
435
+ Create `.github/workflows/publish.yml`:
436
+
437
+ ```yaml
438
+ name: Publish to PyPI
439
+
440
+ on:
441
+ release:
442
+ types: [published]
443
+
444
+ jobs:
445
+ publish:
446
+ runs-on: ubuntu-latest
447
+ environment: release
448
+ permissions:
449
+ id-token: write # Required for trusted publishing
450
+
451
+ steps:
452
+ - uses: actions/checkout@v4
453
+
454
+ - name: Set up Python
455
+ uses: actions/setup-python@v5
456
+ with:
457
+ python-version: '3.12'
458
+
459
+ - name: Install build dependencies
460
+ run: pip install build
461
+
462
+ - name: Build package
463
+ run: python -m build
464
+
465
+ - name: Publish to PyPI
466
+ uses: pypa/gh-action-pypi-publish@release/v1
467
+ # Uses trusted publishing - configure at pypi.org
468
+ ```
469
+
470
+ ### Setting Up Trusted Publishing
471
+
472
+ 1. Go to your PyPI project: https://pypi.org/manage/project/og-pilot/settings/publishing/
473
+ 2. Add a new publisher:
474
+ - Owner: `sunergos-ro`
475
+ - Repository: `og-pilot-python`
476
+ - Workflow: `publish.yml`
477
+ - Environment: `release`
478
+
479
+ ## Version Numbering
480
+
481
+ Follow [Semantic Versioning](https://semver.org/):
482
+ - `MAJOR.MINOR.PATCH` (e.g., `1.2.3`)
483
+ - MAJOR: Breaking changes
484
+ - MINOR: New features (backward compatible)
485
+ - PATCH: Bug fixes (backward compatible)
486
+
487
+ ## Release Checklist
488
+
489
+ - [ ] Update version in `pyproject.toml` and `og_pilot/__init__.py`
490
+ - [ ] Update CHANGELOG (if you have one)
491
+ - [ ] Run tests: `pytest`
492
+ - [ ] Run linter: `ruff check .`
493
+ - [ ] Run type checker: `mypy og_pilot`
494
+ - [ ] Build: `python -m build`
495
+ - [ ] Test locally: `pip install dist/*.whl`
496
+ - [ ] Upload to TestPyPI (optional)
497
+ - [ ] Upload to PyPI
498
+ - [ ] Create GitHub release with tag `v0.1.0`
499
+
500
+ ## License
501
+
502
+ MIT License - see [LICENSE](LICENSE) for details.