## Deliver public assets through CDN for Flask

### Summary
Cdn assets for a Flask app on Ample. Verified on Flask: a versioned, immutable-cached asset uploaded to a published bucket and served from the CDN URL. Build and start: `pip install into .ample/python from requirements.txt`, then `waitress from app.py reading PORT on the python-3.12 template.`

### Prerequisites
- A Flask project (`pip install into .ample/python from requirements.txt`, then `waitress from app.py reading PORT on the python-3.12 template`).
- A bucket from `ample bucket create` with credentials passed as encrypted S3_* environment variables.
- An Ample account token with `servers:write`, `buckets:read`.

### Workload
Deliver public assets through CDN.

### Framework
Flask

### Tested Configuration
- **Template:** python-3.12
- **Runtime:** python
- **Size:** s-1vcpu-1gb
- **Install:** `python3 -m pip install --target .ample/python -r requirements.txt`
- **Start:** `PYTHONPATH=.ample/python:${PYTHONPATH:-} python3 app.py`

### Workflow Steps
1. **Build and start**  
   `pip install into .ample/python from requirements.txt`, then `waitress from app.py reading PORT on the python-3.12 template`; the server must bind `0.0.0.0` on PORT.
2. **Publish a bucket for public assets**  
   Publish only the asset bucket; upload versioned keys with an immutable Cache-Control header and build URLs from its public URL.  
   `ample bucket publish`
3. **Verify**  
   Fetch the live URL and `/p/versioned-static-assets` on the example; on failure read the build and runtime logs.  
   `ample logs  --kind build`

### Limitations
- Verified on the python-3.12 template at s-1vcpu-1gb; other sizes and Flask major versions are not verified.
- Region, compliance attestations and request-duration limits are unknown and not claimed.
- The CDN serves published-bucket objects only; cache rules, purge and TTL control are not verified.

### Cost Estimate
- **Currency:** USD
- **Monthly Amount:** 5.0
- **Basis:** Size prices from pricing.toml (loaded by the API) at build revision 1ac5595375130d45290090e82ed0f554ccd45405-dirty
- **Components:**  
  - **Name:** app server  
    **Size:** s-1vcpu-1gb  
    **Quantity:** 1.0  
    **Monthly Amount:** 5.0
- **Note:** Always-on monthly price of the tested sizes; apps auto-pause when idle. Buckets are allocation-priced per quota and not included.

### Evidence Summary
- **Kind:** canary_run  
   **Summary:** Flask pattern fixture deployed on Ample (pip install into .ample/python from requirements.txt, then waitress from app.py reading PORT on the python-3.12 template); for this guide: a versioned, immutable-cached asset uploaded to a published bucket and served from the CDN URL.
   **Observed At:** 2026-09-21T01:14:18Z
- **Known Unknowns:** region availability is unknown until a verified region fact is recorded, compliance attestations are unknown; none are claimed.

### Examples
- **Flask pattern fixture**  
  Verified CDN assets on Flask.  
  **Source Reference:** tests/deploy-canaries/flask-patterns

### Success Checks
1. **Description:** app responds on its public URL  
   **Kind:** http_get  
   **Path:** /  
   **Expect:** ample canary flask patterns
2. **Description:** versioned-static-assets check from the example  
   **Kind:** http_get  
   **Path:** /p/versioned-static-assets  
   **Expect:** see the pattern fixture checks

### Next Actions
- **Browse the catalog index**  
  **Operation ID:** catalog_index  
  **Method:** GET  
  **Relative Path:** /v1/catalog
- **Search published recipes by intent, stack and constraints**  
  **Operation ID:** search_recipes  
  **Method:** POST  
  **Relative Path:** /v1/catalog/search  
  **Parameters:**  
  ```json
  {
    "body": {
      "limit": 5,
      "query": "Deliver public assets through CDN for Flask"
    }
  }
  ```
- **Prepare a side-effect-free deployment plan for an authorized project**  
  **Operation ID:** plan_deployment  
  **Method:** POST  
  **Relative Path:** /v1/catalog/plan  
  **Parameters:**  
  ```json
  {
    "body": {
      "inputs": {},
      "projectId": "",
      "recipeId": "page:guides:flask:cdn-assets",
      "recipeRevision": "r1"
    }
  }
  ```
