This document provides complete, copy-pasteable examples for programmatically generating city map posters using the MapToPoster REST API.
- Local Base URL:
http://localhost:8000 - Production Base URL:
https://your-service.onrender.com(Replace in examples if deploying to cloud)
Because the API uses an asynchronous job polling pattern, generating a poster involves two steps: submitting the request and checking status until finished.
curl -X POST http://localhost:8000/api/generate \
-H "Content-Type: application/json" \
-d '{
"city": "Rome",
"country": "Italy",
"theme": "warm_beige",
"distance": 8000,
"width": 12,
"height": 16
}'Expected Response:
{
"job_id": "4b68e9e1-64d8-4f8b-a7a2-f8c6db24e392",
"status": "pending"
}curl http://localhost:8000/api/jobs/4b68e9e1-64d8-4f8b-a7a2-f8c6db24e392Expected Response (when processing):
{
"job_id": "4b68e9e1-64d8-4f8b-a7a2-f8c6db24e392",
"status": "processing"
}Expected Response (when complete):
{
"job_id": "4b68e9e1-64d8-4f8b-a7a2-f8c6db24e392",
"status": "done",
"city": "Rome",
"country": "Italy",
"theme": "warm_beige",
"image_base64": "iVBORw0KGgoAAAANSUhEUg...",
"filename": "rome_warm_beige_22060525_120000.png",
"error": null,
"created_at": "2026-05-25T12:00:00.000",
"completed_at": "2026-05-25T12:01:15.000"
}This complete Python script submits a request, polls the backend API until completion, decodes the resulting base64 image, and saves it to a local file.
import base64
import time
import requests
API_BASE = "http://localhost:8000/api"
def generate_poster(city, country, theme="terracotta", distance=15000):
payload = {
"city": city,
"country": country,
"theme": theme,
"distance": distance,
"width": 12.0,
"height": 16.0
}
# 1. Submit the generation job
print(f"Submitting job for {city}, {country} ({theme} theme)...")
res = requests.post(f"{API_BASE}/generate", json=payload)
res.raise_for_status()
job_data = res.json()
job_id = job_data["job_id"]
print(f"Job enqueued with ID: {job_id}")
# 2. Poll for completion
while True:
status_res = requests.get(f"{API_BASE}/jobs/{job_id}")
status_res.raise_for_status()
status_data = status_res.json()
status = status_data["status"]
print(f"Current Job Status: {status}")
if status == "done":
img_b64 = status_data["image_base64"]
filename = status_data.get("filename", f"{city.lower()}_poster.png")
# Decode and write to disk
with open(filename, "wb") as f:
f.write(base64.b64decode(img_b64))
print(f"🎉 Success! Poster downloaded and saved to: {filename}")
break
elif status == "error":
print(f"❌ Generation failed. Error: {status_data.get('error')}")
break
time.sleep(5) # wait 5 seconds before polling again
if __name__ == "__main__":
generate_poster("Monaco", "Monaco", theme="neon_cyberpunk", distance=3000)This example uses Node's native fetch API to query, poll, and write the generated base64 image data to a file.
const fs = require('fs');
const path = require('path');
const API_BASE = "http://localhost:8000/api";
async function generatePoster(city, country, theme = "blueprint", distance = 10000) {
const payload = { city, country, theme, distance };
try {
// 1. Submit Job
console.log(`Submitting job for ${city}, ${country}...`);
const submitRes = await fetch(`${API_BASE}/generate`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
if (!submitRes.ok) throw new Error(`Submission failed: ${submitRes.statusText}`);
const { job_id } = await submitRes.json();
console.log(`Job enqueued. ID: ${job_id}`);
// 2. Poll Status
const pollInterval = setInterval(async () => {
const pollRes = await fetch(`${API_BASE}/jobs/${job_id}`);
if (!pollRes.ok) {
console.error(`Polling failed, retrying...`);
return;
}
const job = await pollRes.json();
console.log(`Status: ${job.status}`);
if (job.status === "done") {
clearInterval(pollInterval);
const buffer = Buffer.from(job.image_base64, 'base64');
const outputPath = path.join(__dirname, job.filename || `${city}_poster.png`);
fs.writeFileSync(outputPath, buffer);
console.log(`🎉 Success! Poster saved to ${outputPath}`);
} else if (job.status === "error") {
clearInterval(pollInterval);
console.error(`❌ Generation error: ${job.error}`);
}
}, 4000);
} catch (error) {
console.error("API error:", error);
}
}
// Execute
generatePoster("Venice", "Italy", "blueprint", 4000);