Metadata-Version: 2.4
Name: sprezzature-video
Version: 0.2.0
Summary: Project launch films for the sprezzature stack: one spec drives landscape, portrait and square on a single time grid, every on-screen claim verified against the code it describes, and the asset tree audited for whether the film can be rendered again from a clone.
Author-email: Warith HARCHAOUI <warithmetics@deraison.ai>
License-Expression: BSD-3-Clause
Project-URL: Homepage, https://sprezzature.ai/
Project-URL: Repository, https://github.com/warith-harchaoui/sprezzature-video
Keywords: video,launch-video,demo-video,storyboard,webvtt,hyperframes,sprezzature
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Video
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: sprezzature-audio>=1.5.0
Requires-Dist: os-helper>=2.10.0
Requires-Dist: audio-helper>=1.6.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: voice
Requires-Dist: sprezzature-audio[narrate]>=1.5.0; extra == "voice"
Provides-Extra: post
Requires-Dist: video-helper>=2.7.0; extra == "post"
Provides-Extra: local
Requires-Dist: playwright>=1.40; extra == "local"
Provides-Extra: cli
Requires-Dist: click>=8.1; extra == "cli"
Provides-Extra: api
Requires-Dist: fastapi>=0.115; extra == "api"
Requires-Dist: uvicorn[standard]>=0.30; extra == "api"
Provides-Extra: mcp
Requires-Dist: fastapi-mcp>=0.3; extra == "mcp"
Requires-Dist: mcp<2.0; extra == "mcp"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.11; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: httpx2>=2.0.0; extra == "dev"
Dynamic: license-file

# sprezzature-video

[🇫🇷 LISEZMOI.md](https://github.com/warith-harchaoui/sprezzature-video/blob/main/LISEZMOI.md) · 🇬🇧 README.md

A film about a project makes **claims** about that project — how many chart
kinds, how many tests, how many packages — and burns them into pixels, where
nothing ever reads them again. Prose in a README gets re-read. A number in a
keyframe does not.

So this package is not a renderer. Its centre is a checker that holds a film's
assertions against the code they describe, in both directions, and the renderer
sits behind a seam because which tool grabs the frames is the least interesting
decision here.

Part of the [sprezzature](https://sprezzature.ai/) suite.

---

## Why it exists

The five films that served on sprezzature.ai said **"127 chart kinds"**. The
catalogue had held 167 since September. The number was baked into ten
compositions and five rendered MP4s, so nothing short of a re-cut could correct
it — and nothing, anywhere, was watching. That is this package's whole subject.

## What's here

| Module | What it owns |
|---|---|
| `claims` | A claim is a declared pair: the text on screen, and the place in the code that decides whether it is true. `verify_all` checks every declared claim still holds; `undeclared_numbers` checks every number *visible* on screen is a declared claim. |
| `assets` | Can this film be rendered again from a clone? Three classes: `TRACKED` (a copy of a tracked file, proved equal to its source), `DERIVED` (output of a tool still on the machine), `SOLE` (exists in exactly one place). Divergence is reported, never silently repaired. |
| `captions` | WebVTT built from the narration script and the **measured** length of each audio file — not transcribed, and not typed. |
| `post` | The poster baked as frame 0, because Slack, X and Discord regenerate their thumbnail server-side from the first frame whatever a `poster=` attribute says. Plus loudness normalisation across a series. |

### Both directions, and why the second one matters

```python
from sprezzature_video import Claim, ClaimSource, verify, undeclared_numbers

claim = Claim(
    text="167 kinds, every one hand-authored.",
    value=167,
    source=ClaimSource(
        path="sprezzature-figures/sprezzature_figures/catalog/figures.json",
        method="json_len",
    ),
)
verify(claim, root).ok  # does the code still agree?
undeclared_numbers(html, [claim])  # is anything on screen unaccounted for?
```

Checking only declared claims protects the numbers somebody remembered to
declare — never the one typed into a keyframe at midnight and left to go stale.

## Install

```bash
pip install sprezzature-video                    # the checker and the ledger
pip install 'sprezzature-video[voice,post]'      # plus narration and ffmpeg work
```

## Boundaries

Which package owns what, between this suite and
[ai-helpers](https://deraison.ai/ai-helpers), is written down in
[BOUNDARIES.md](BOUNDARIES.md). The short version: **ai-helpers owns the
primitive, sprezzature owns the opinion.** Voice arrives through
`sprezzature-audio[narrate]`, ffmpeg through `video-helper`, and rendering
through Hyperframes behind a seam.

## Status

0.2.0. The checker, the asset ledger, the captions, the post-processing, the
YAML spec loader and all five surfaces are written and tested — 46 tests, with
CI on 3.10/3.11/3.12. The renderer seam is still out of band: Hyperframes is
driven directly, and `renderers/` returns in the commit that gives it a
module.

## License

BSD-3-Clause.
