Skip to content

Latest commit

 

History

History
183 lines (146 loc) · 5.13 KB

File metadata and controls

183 lines (146 loc) · 5.13 KB

MapToPoster API Examples

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)

1. Using cURL (Terminal)

Because the API uses an asynchronous job polling pattern, generating a poster involves two steps: submitting the request and checking status until finished.

Step 1: Submit a generation request

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"
}

Step 2: Poll status using the job_id

curl http://localhost:8000/api/jobs/4b68e9e1-64d8-4f8b-a7a2-f8c6db24e392

Expected 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"
}

2. Using Python

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)

3. Using JavaScript / Node.js

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);