# Perfect Pizza Production

This tutorial walks you through the complete PizzaStack pipeline: from acquiring tomatoes to baking and tasting a finished pizza. By the end, you will have a full working Python script.

## Prerequisites

Before starting, make sure you have:

* A PizzaStack API key (sign up at [tomatopy.pizza](https://tomatopy.pizza))
* Python with the `requests` library installed (`pip install requests`)
* Understanding of the [basic concepts](/docs/readme-1/basic-concepts.md)

## Setup

```python
import requests
import uuid

API_BASE = "https://api.tomatopy.pizza/v1"
HEADERS = {
    "Content-Type": "application/json",
    "X-API-Key": "your-api-key",
    "X-Session-ID": str(uuid.uuid4())
}

def api_post(endpoint, payload):
    """Helper to make API calls and check for errors."""
    response = requests.post(f"{API_BASE}{endpoint}", headers=HEADERS, json=payload)
    response.raise_for_status()
    return response.json()
```

## Step 1: Acquire Tomatoes

```python
# Acquire high-quality San Marzano tomatoes
tomato = api_post("/tomato/acquire", {
    "variety": "San Marzano",
    "ripeness": 0.9,
    "weight": 400
})
print(f"1. Acquired {tomato['variety']} tomato (type: {tomato['type']})")
```

## Step 2: Slice the Tomatoes

Slicing is essential. Raw tomato IDs passed directly to `/cook/simmer` will silently produce low-quality sauce.

```python
# Slice the tomatoes
sliced = api_post("/tomato/slice", {
    "tomato_ids": [tomato["id"]],
    "method": "dice",
    "size": "medium",
    "consistency": "uniform"
})
print(f"2. Sliced into {sliced['piece_count']} pieces")
```

## Step 3: Simmer Into Sauce

```python
# Simmer sliced tomatoes with garlic and basil
sauce = api_post("/cook/simmer", {
    "ingredients": [
        {"id": sliced["id"], "name": "tomato", "amount": 400, "unit": "g"}
    ],
    "temperature": 100,
    "duration": "30m"
})
print(f"3. Sauce ready (sauce_quality: {sauce['sauce_quality']})")
```

## Step 4: Create the Pizza Base

```python
# Create a Neapolitan-style base
base = api_post("/pizza/base", {
    "thickness": "medium",
    "size": "12inch",
    "style": "neapolitan",
    "hydration": 0.65
})
print(f"4. Base created: {base['style']} {base['size']}")
```

## Step 5: Assemble the Pizza

Assembly is required before baking. The `/pizza/bake` endpoint only accepts `pizza_id` values from `/pizza/assemble` -- passing a `base_id` directly will return a 400 error.

```python
# Assemble the pizza
pizza = api_post("/pizza/assemble", {
    "base_id": base["id"],
    "sauce_id": sauce["id"],
    "toppings": [
        {"name": "mozzarella", "amount": 200, "unit": "g"},
        {"name": "basil", "amount": 10, "unit": "leaves"}
    ]
})
print(f"5. Pizza assembled: {pizza['id']}")
```

## Step 6: Bake the Pizza

```python
# Bake at high temperature
baked = api_post("/pizza/bake", {
    "pizza_id": pizza["id"],
    "temperature": 450,
    "duration": "2m"
})
print(f"6. Pizza baked! Quality score: {baked['quality_score']}")
```

## Step 7: Taste Test

```python
# Analyze the finished pizza
profile = api_post("/taste/analyze", {
    "dish_id": baked["id"],
    "depth": "comprehensive",
    "include_aroma": True,
    "include_texture": True
})

print(f"\n--- Flavor Profile ---")
print(f"Sweetness: {profile['sweetness']}")
print(f"Acidity:   {profile['acidity']}")
print(f"Umami:     {profile['umami']}")
print(f"Aroma:     {profile['aroma']['intensity']}")
print(f"Texture:   {profile['texture']['score']}")
```

## Complete Working Script

```python
import requests
import uuid

API_BASE = "https://api.tomatopy.pizza/v1"
HEADERS = {
    "Content-Type": "application/json",
    "X-API-Key": "your-api-key",
    "X-Session-ID": str(uuid.uuid4())
}

def api_post(endpoint, payload):
    """Helper to make API calls and check for errors."""
    response = requests.post(f"{API_BASE}{endpoint}", headers=HEADERS, json=payload)
    response.raise_for_status()
    return response.json()

# 1. Acquire tomato
tomato = api_post("/tomato/acquire", {
    "variety": "San Marzano",
    "ripeness": 0.9,
    "weight": 400
})
print(f"1. Acquired {tomato['variety']} (type: {tomato['type']})")

# 2. Slice
sliced = api_post("/tomato/slice", {
    "tomato_ids": [tomato["id"]],
    "method": "dice",
    "size": "medium",
    "consistency": "uniform"
})
print(f"2. Sliced into {sliced['piece_count']} pieces")

# 3. Simmer into sauce
sauce = api_post("/cook/simmer", {
    "ingredients": [
        {"id": sliced["id"], "name": "tomato", "amount": 400, "unit": "g"}
    ],
    "temperature": 100,
    "duration": "30m"
})
print(f"3. Sauce ready (sauce_quality: {sauce['sauce_quality']})")

# 4. Create base
base = api_post("/pizza/base", {
    "thickness": "medium",
    "size": "12inch",
    "style": "neapolitan",
    "hydration": 0.65
})
print(f"4. Base created: {base['style']} {base['size']}")

# 5. Assemble
pizza = api_post("/pizza/assemble", {
    "base_id": base["id"],
    "sauce_id": sauce["id"],
    "toppings": [
        {"name": "mozzarella", "amount": 200, "unit": "g"},
        {"name": "basil", "amount": 10, "unit": "leaves"}
    ]
})
print(f"5. Pizza assembled: {pizza['id']}")

# 6. Bake
baked = api_post("/pizza/bake", {
    "pizza_id": pizza["id"],
    "temperature": 450,
    "duration": "2m"
})
print(f"6. Pizza baked! Quality score: {baked['quality_score']}")

# 7. Taste test
profile = api_post("/taste/analyze", {
    "dish_id": baked["id"],
    "depth": "comprehensive",
    "include_aroma": True,
    "include_texture": True
})
print(f"\n--- Final Results ---")
print(f"Quality Score: {baked['quality_score']}")
print(f"Sweetness: {profile['sweetness']}")
print(f"Acidity:   {profile['acidity']}")
print(f"Umami:     {profile['umami']}")
print(f"Aroma:     {profile['aroma']['intensity']}")
print(f"Texture:   {profile['texture']['score']}")
```

## Troubleshooting

### Common Issues

1. **Low Quality Score**

   Check that you sliced tomatoes before simmering. Raw tomato IDs silently degrade sauce quality, which cascades to the final pizza score.
2. **400 Error on /pizza/bake**

   You must call `/pizza/assemble` first. The bake endpoint requires a `pizza_id` from assembly, not a `base_id`.
3. **Objects Not Found**

   Make sure all requests use the same `X-Session-ID`. Objects from one session cannot be referenced in another.

## Best Practices

1. **Always Follow the Pipeline Order**

   acquire -> slice -> simmer -> base -> assemble -> bake
2. **Check Quality at Each Step**

   ```python
   if sauce["sauce_quality"] == "degraded":
       print("Warning: Low sauce quality. Check if tomatoes were sliced.")
   ```
3. **Use a Helper Function**

   The `api_post` helper shown above reduces boilerplate and ensures errors are caught early.

## Next Steps

* [Advanced Flavor Profiling](/docs/tutorials/advanced-flavor-profiling.md) - Deep dive into taste analysis
* [API Usage Best Practices](/docs/best-practices/code-efficiency.md) - Optimize your API usage
* [Session Management](/docs/best-practices/virtual-kitchen-management.md) - Manage sessions effectively


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tomatopy.pizza/docs/tutorials/perfect-pizza-production.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
