Python
Publish from Python scripts, notebooks and data pipelines with requests.
Install requests (pip install requests) and set FLATPAGE_API_KEY in your environment.
import os
import time
import requests
API = "https://flatpage.app/v1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['FLATPAGE_API_KEY']}"
def _check(res: requests.Response) -> dict:
if not res.ok:
try:
message = res.json()["error"]
except ValueError:
message = res.reason
raise RuntimeError(f"Flatpage {res.status_code}: {message}")
return res.json() if res.content else {}
def _until_live(result: dict) -> dict:
"""Waits for a publish that answered 202 (still processing)."""
for _ in range(30):
if result.get("site"):
return result["site"]
time.sleep(2)
result = _check(session.get(f"{API}/uploads/{result['uploadId']}"))
raise TimeoutError("Still processing after a minute")
def publish(path: str, site: str | None = None, link_name: str | None = None) -> dict:
"""Publishes an .html, .zip or .pdf file (up to 25 MB). Pass `site` to update that site in place."""
content_type = {
".html": "text/html",
".zip": "application/zip",
".pdf": "application/pdf",
}[os.path.splitext(path)[1].lower()]
with open(path, "rb") as f:
if site:
res = session.put(f"{API}/sites/{site}", data=f, headers={"Content-Type": content_type})
else:
params = {"linkName": link_name} if link_name else {}
res = session.post(f"{API}/sites", data=f, params=params, headers={"Content-Type": content_type})
return _until_live(_check(res))
def publish_html(html: str, site: str | None = None, link_name: str | None = None) -> dict:
"""Publishes an HTML string, for example a report you just rendered."""
if site:
res = session.put(f"{API}/sites/{site}", json={"html": html})
else:
res = session.post(f"{API}/sites", json={"html": html, "linkName": link_name})
return _until_live(_check(res))Use it:
site = publish("report.html", link_name="weekly-report")
print(site["url"]) # https://weekly-report.flatpage.page
# Every Monday: same link, new numbers
publish("report.html", site="weekly-report")
# Views for the last 30 days
stats = _check(session.get(f"{API}/sites/weekly-report/stats"))
print(stats["last30Days"]["total"])Notebooks and charts
Export a notebook or a Plotly/Altair chart to a single HTML file (jupyter nbconvert --to html, fig.write_html(..., include_plotlyjs="cdn")) and
publish it with publish(). Keep it self-contained: relative links to files
you didn't upload won't load.