Server technologies
Python
Read release-pinned content from Python with the standard library.
PeopleTide Content · HTTP integration guides
1. Prepare your project.
Use Python 3.11+. Export CONTENT_ORIGIN, CONTENT_ORGANIZATION_ID, and CONTENT_SITE_ID in your process environment. No pip package is needed. Save this self-contained example as content_delivery.py.
Connect and render.
Publish an article of type article with slug welcome and a body field before running the example. Split the labelled files into the paths shown.
# content_delivery.py — Python 3.11+, standard library only
import json, os
from urllib.request import urlopen
from urllib.parse import urljoin, urlsplit
from http.server import BaseHTTPRequestHandler, HTTPServer
ORIGIN = os.environ.get('CONTENT_ORIGIN', 'https://content.peopletide.com')
PREFIX = '/delivery/v1/' + os.environ['CONTENT_ORGANIZATION_ID'] + '/' + os.environ['CONTENT_SITE_ID'] + '/'
def read(path):
url = urljoin(ORIGIN, path)
parsed, base = urlsplit(url), urlsplit(ORIGIN)
if (parsed.scheme, parsed.netloc) != (base.scheme, base.netloc) or not parsed.path.startswith(PREFIX):
raise ValueError('Unexpected delivery URL')
with urlopen(url, timeout=8) as response:
return json.load(response)
def article(slug):
current = read(PREFIX + 'current.json')
manifest = read(current['url'])
entry = next((e for e in manifest['entries'] if e['type'] == 'article' and e['slug'] == slug), None)
return {'releaseId': current['releaseId'], 'document': read(entry['url'])} if entry else None
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
try:
result = article('welcome')
status = 200 if result else 404
body = result or {'error': 'Article not published'}
except Exception:
status, body = 503, {'error': 'Content temporarily unavailable'}
self.send_response(status)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(body).encode())
if __name__ == '__main__':
HTTPServer(('127.0.0.1', 3000), Handler).serve_forever()Choose when content refreshes.
The demonstration server fetches per request and returns JSON. Use a production WSGI/ASGI server for a deployed application. Cache immutable URLs separately from a discovery pointer with at most a 30-second freshness window.
Verify success and failure.
Run python3 content_delivery.py and open http://127.0.0.1:3000. Check the releaseId and title. Change the welcome slug in the handler to an unknown slug to exercise 404; stop delivery to exercise 503. Use an escaping template engine when rendering HTML.