blog2video-test / scripts /CRAFTED_TEMPLATE_COMMANDS.md
Muhammad-Mehdi's picture
set the default font sizes to be used from the backend folder
7c03e16
|
Raw
History Blame Contribute Delete
8.24 kB
# Crafted templates: bundle, upload, fetch, and API
Run Python scripts from the **repository root**. They prepend `backend/` to `PYTHONPATH` and use R2 settings from backend config (e.g. `backend/.env`).
See also:
- [`../Crafted_template_guide.md`](../Crafted_template_guide.md) — end-to-end workflow
- [`../backend/templates/CRAFTED_TEMPLATE_FOLDER_SPEC.md`](../backend/templates/CRAFTED_TEMPLATE_FOLDER_SPEC.md) — folder layout and runtime behavior
---
## 1. Bundle and upload: `bundle_and_upload_crafted_template.py`
**What it does:** Copies a local template from `backend/templates/<id>`, `frontend/src/components/remotion/<id>`, `remotion-video/src/templates/<id>`, and scoped `public/` assets into **`crafted-templates/<template-id>-crafted-template/`**, writes **`manifest.json`**, and optionally uploads all files under that folder to **R2**.
### Flags
| Flag | Required | Description |
|------|----------|-------------|
| `--template-id` | Yes | Built-in folder id (e.g. `nightfall`, `default`). |
| `--template-key` | No | Internal bundle key. Default: `<template-id>_bundle`. |
| `--public-template-id` | No | Id used by the app. Default: `crafted_<template-id>_bundle`. |
| `--supported-video-style` | No | `explainer` \| `promotional` \| `storytelling`. Default: `explainer`. |
| `--upload` | No | Upload bundle to R2. If omitted, only creates the local bundle. |
| `--r2-prefix` | No* | R2 key prefix. With `--upload` and no prefix, default is `crafted-templates/<template-id>-crafted-template-<UTC-stamp>`. If `CRAFTED_TEMPLATE_R2_PREFIX` is set in settings, it is prepended when the prefix does not already include it. |
| `--replace-existing` | No | With `--upload` and `--r2-prefix`: delete objects under that prefix, then re-upload (stable URLs/manifest). |
| `--prune-source-after-bundle` | No | After bundle (and upload if enabled), remove local source folders for this template from the repo. Not valid with `--upload-existing-bundle`. |
| `--upload-existing-bundle` | No | Skip re-bundling; upload files from an existing bundle folder (`manifest.json` required at bundle root). |
| `--bundle-dir` | No | Path to that bundle folder for `--upload-existing-bundle`. Default: `crafted-templates/<template-id>-crafted-template`. |
| `--public-assets-root` | No | Under `frontend/public` and `remotion-video/public`, scoped assets live at `<root>/<template-id>/`. Default: `templates`. |
\* `--r2-prefix` is required when using `--replace-existing`.
### Examples
```bash
# Local bundle only
python scripts/bundle_and_upload_crafted_template.py --template-id <TEMPLATE_ID>
# Bundle, then delete local sources
python scripts/bundle_and_upload_crafted_template.py --template-id <TEMPLATE_ID> --prune-source-after-bundle
# Bundle and upload with auto-generated prefix
python scripts/bundle_and_upload_crafted_template.py --template-id <TEMPLATE_ID> --upload
# Bundle and upload with explicit ids and prefix
python scripts/bundle_and_upload_crafted_template.py \
--template-id <TEMPLATE_ID> \
--template-key <TEMPLATE_KEY> \
--public-template-id <PUBLIC_TEMPLATE_ID> \
--r2-prefix <R2_PREFIX> \
--upload
# Replace objects in place at an existing prefix
python scripts/bundle_and_upload_crafted_template.py \
--template-id <TEMPLATE_ID> \
--r2-prefix <R2_PREFIX> \
--upload \
--replace-existing
# Upload an already-built bundle directory
python scripts/bundle_and_upload_crafted_template.py \
--template-id <TEMPLATE_ID> \
--upload-existing-bundle \
--bundle-dir /path/to/bundle
```
### Example: `newspaper_brief` → `staging/crafted-templates/newspaper-brief/`
Use **`python3`** on macOS if `python` is not on your `PATH`.
**1) Build the local bundle** (outputs `crafted-templates/newspaper_brief-crafted-template/`):
```bash
python3 scripts/bundle_and_upload_crafted_template.py --template-id newspaper_brief
```
**2) Upload and replace the bucket folder** that matches your R2 console prefix (stable path, same manifest URL for `POST .../admin/publish`):
```bash
python3 scripts/bundle_and_upload_crafted_template.py \
--template-id newspaper_brief \
--supported-video-style storytelling \
--r2-prefix staging/crafted-templates/newspaper-brief \
--upload \
--replace-existing
```
Omit `--replace-existing` on a **first** upload to that prefix, or if you are fine with the script creating a new timestamped prefix via `--upload` alone.
If `CRAFTED_TEMPLATE_R2_PREFIX=staging` is set in `backend/.env`, you can use `--r2-prefix crafted-templates/newspaper-brief` instead; the uploader prepends `staging/` the same way as on download.
---
## 2. Fetch from R2: `fetch_crafted_template_from_r2.py`
**What it does:** Downloads `manifest.json` and all referenced objects from **R2** and restores:
- `backend/templates/<template-id>/`
- `frontend/src/components/remotion/<template-id>/`
- `remotion-video/src/templates/<template-id>/`
- `public/` files into both `frontend/public` and `remotion-video/public`
### Flags
| Flag | Required | Description |
|------|----------|-------------|
| `--template-id` | Yes | Local template id to restore into. |
| `--r2-prefix` | Yes | R2 prefix used at upload time (e.g. `crafted-templates/foo-20260506-123000`). |
| `--manifest-path` | No | Full R2 object key for the manifest. Default: `<r2-prefix>/manifest.json`. |
| `--overwrite` | No | Allow overwriting existing local files. |
### Examples
```bash
python scripts/fetch_crafted_template_from_r2.py --template-id <TEMPLATE_ID> --r2-prefix <R2_PREFIX>
python scripts/fetch_crafted_template_from_r2.py --template-id <TEMPLATE_ID> --r2-prefix <R2_PREFIX> --overwrite
python scripts/fetch_crafted_template_from_r2.py \
--template-id <TEMPLATE_ID> \
--r2-prefix <R2_PREFIX> \
--manifest-path <R2_PREFIX>/manifest.json
```
### Troubleshooting fetch
- **`zsh: command not found: python`** — On macOS use `python3`, or activate a venv that provides `python`. Run from repo root so `backend/` is importable.
- **Wrong `--template-id`** — Must be the **local template folder name** (e.g. `newspaper_brief`), i.e. what lives under `backend/templates/<id>/`. Do **not** use the public id `crafted_newspaper_brief_bundle` here unless your folders are literally named that (they usually are not).
- **Wrong `--r2-prefix`** — This must be the **full path segment in the bucket to the bundle folder**, the same value printed at upload (`r2_prefix=...`), or stored in DB as `crafted_templates.r2_prefix`. It is **not** only the namespace `staging`; that resolves to object `staging/manifest.json`, which does not exist. Typical shape: `crafted-templates/newspaper_brief-crafted-template-YYYYMMDD-HHMMSS`, or with env `CRAFTED_TEMPLATE_R2_PREFIX=staging`, objects live under `staging/crafted-templates/...`. The fetch script prepends `CRAFTED_TEMPLATE_R2_PREFIX` from `backend/.env` when missing, matching the bundle uploader—pass the suffix after staging (e.g. `crafted-templates/...`) unless you already include `staging/` in `--r2-prefix`.
---
## 3. HTTP API (list / detail / admin)
Base path: `/api/crafted-templates` (authenticated; see FastAPI router `backend/app/routers/crafted_templates.py`).
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/crafted-templates` | List crafted template summaries for the **current user** (empty if feature disabled or no entitlements). |
| `GET` | `/api/crafted-templates/{template_id}` | Full detail and package-backed fields when the user has access. |
| `GET` | `/api/crafted-templates/cache-stats` | Cache stats for rollout/debugging. |
| `POST` | `/api/crafted-templates/admin/publish` | Register a template after R2 upload; validates the package. |
| `POST` | `/api/crafted-templates/admin/grant` | Grant a user entitlement to a `public_template_id`. |
### Publish body example
```json
{
"template_key": "<TEMPLATE_KEY>",
"public_template_id": "<PUBLIC_TEMPLATE_ID>",
"name": "<DISPLAY_NAME>",
"category": "blog",
"supported_video_style": "<VIDEO_STYLE>",
"r2_prefix": "<R2_PREFIX>",
"manifest_path": "<R2_PREFIX>/manifest.json",
"checksum": null
}
```
### Grant body example
```json
{
"user_id": <USER_ID>,
"public_template_id": "<PUBLIC_TEMPLATE_ID>"
}
```