Model or dataset
backblaze-labs/genblaze avatar
backblaze-labs/genblaze

Genblaze: a Python pipeline SDK where every generated asset carries a provenance manifest

Genblaze is an open source Python SDK for orchestrating generative AI media pipelines across video, audio, and image providers with built in provenance for every output.

555 stars24 forksPythonMIT

At a glance

What is it?
Backblaze's Genblaze wraps eleven generative media providers behind one Pipeline API and emits a canonical manifest per run. The manifest is the product; the provider abstraction is the convenience. Here is what the documentation actually commits to, and where the model breaks down.
Who is it for?
Adopt Genblaze if you run multi-provider media generation and need a per-run manifest that survives a provider swap, and if your assets land in B2 or another S3-compatible store so that ObjectStorageSink can hash them. Do not adopt it for a chat-only loop, for a browser-side TypeScript app, or for adversarial provenance where you need C2PA or a signer you control.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap Genblaze claims: between one API call and a production media pipeline

Most generative media work starts as a single call to a single vendor and ends, six months later, as a graph of calls across three vendors with no record of which model produced which file. Genblaze targets that second state. The README frames the positioning directly: it sits between calling a single video API and running a media pipeline in production. The intended user is a Python engineer who already knows they will chain steps (text to image to video, or speech to transcript to music bed) and who has been asked, by a client, a regulator, or their own legal team, to prove what produced a given file. The project is explicit about who it is not for: a chat-only loop, a JavaScript or TypeScript generation UI, or anyone who does not care about provenance. In those cases the provider SDK is described as simpler, and that is correct. The provenance layer is the reason to accept the extra abstraction.

Pipeline, Step, Run, Manifest: the four objects that carry the design

The core package exposes Pipeline, Step, Run, Manifest, sinks, and tracers. A Pipeline holds Steps; a Step names a provider and a model; a Run is one execution; a Manifest is the record of that execution. The README states that a manifest captures provider, model, prompt, params, and timestamps, which is what makes replay possible: either genblaze replay manifest.json or by feeding the canonical params back into a Pipeline. That is the data flow. Providers are adapters, one package each, and the README lists eleven across video, image, audio, and chat. The swap story is a single line change, Sora to Runway to Veo, because the orchestration layer never sees provider-specific shapes. Two mechanisms sit on top of that. fallback_models=[...] retries on MODEL_ERROR, which means a dead upstream model degrades to the next entry rather than failing the run. And probe_models plus provider-contract tests are described as CI-grade, intended to catch upstream API drift before users hit it. That last point matters more than it reads: eleven adapters against fast-moving vendor APIs is a maintenance surface, and the repository's answer is automated contract checking rather than manual review.

Manifest.verify() is tamper-evident, not tamper-proof, and URL-only outputs fail it

This is the part worth reading twice. Manifest.verify() checks the manifest hash and requires every output asset to declare a valid sha256. The README then draws a boundary the project does not hide: outputs become SHA-256-covered when providers return bytes or when ObjectStorageSink transfers them into durable storage, and URL-only outputs do not pass Manifest.verify(). So the guarantee is conditional on your storage path, not on the SDK alone. The second boundary is stated in the same paragraph: the manifest is tamper-evident in trusted storage, and you should pair it with your own signer or C2PA when adversarial verification matters. A hash chain proves that bytes match a recorded digest; it does not prove who recorded the digest. Anyone with write access to the manifest store can produce a fresh, internally consistent manifest. The README also notes that callers fetching asset.url should re-hash those bytes separately, and that the CLI's opt-in genblaze verify --fetch mode does exactly that. Opt-in is the right default here, since fetching every asset to re-hash is a bandwidth decision, but it also means a plain verify run tells you less than its name suggests.

Install, extras, and the wave-tag trap in the release notes

The umbrella install is pip install genblaze, which pulls genblaze-core and genblaze-s3 so a working provenance pipeline exists out of the box. Provider adapters are opt-in extras: genblaze[gmicloud], genblaze[video], genblaze[all], or individual packages such as genblaze-openai, genblaze-google, genblaze-nvidia, genblaze-runway, genblaze-luma, genblaze-elevenlabs, and genblaze-stability-audio. Install names use hyphens and imports use underscores, so pip install genblaze-gmicloud maps to import genblaze_gmicloud. The quickstart sets GMI_API_KEY, B2_KEY_ID, and B2_APP_KEY, then builds a Pipeline from genblaze_core with Modality, ObjectStorageSink, and KeyStrategy, plus GMICloudVideoProvider and an S3 backend. S3StorageBackend.for_backblaze("bucket") is the documented storage entry point, and the README says it works against any S3-compatible store including AWS S3, Cloudflare R2, and MinIO. The versioning warning is the sharpest thing in the README. A GitHub Release tag such as v0.7.0 is not a genblaze version. It names a CHANGELOG wave, and every package in that wave versions independently. Pinning genblaze==0.4.0 either fails outright or resolves silently to an unrelated umbrella build from a different wave. Even pinning the exact umbrella version is not fully reproducible, because the umbrella pins ranges such as genblaze-core>=0.3.8,<0.4 rather than exact versions. The documented fix is a lockfile via pip freeze, uv lock, or a constraints file.

The maintenance cost is eleven adapters, and the release cadence shows it

Three releases landed in roughly six weeks: v0.5.0 on 2026-07-17, v0.6.0 on 2026-07-22, v0.7.0 on 2026-07-28, with the last push to main on 2026-09-10. That pace is consistent with a project still finding its adapter surface, and it has a direct cost for anyone pinning versions: the wave-tag scheme means the changelog and the PyPI version numbers are two different sequences that happen to look alike. Upgrade work is therefore not just bumping a number. You re-resolve the umbrella's ranges, regenerate the lockfile, and re-run whatever provider-contract checks cover the adapters you actually use. The compensating control is the probe_models and conformance tooling, which is the right shape for this problem but only helps if you run it. The licence is MIT, which is permissive and imposes no copyleft obligation on your own code; the practical constraint is not the licence text but the provider terms sitting underneath it, since each adapter calls a commercial API under that vendor's own conditions. Nothing here is legal advice, and the provider terms are the thing to read if you plan to redistribute generated media.

Where a provider SDK or a different framework is the better call

The README names two alternatives and gives a real reason for each. If you only need an LLM chat loop, use the provider's SDK or LangChain: Genblaze's value is in media steps and manifests, and a chat loop exercises neither. If you are building a UI-driven generation app in JavaScript or TypeScript, use the Vercel AI SDK, which lives in the runtime where your UI already is. Genblaze does publish @genblaze/spec on npm, but that is TypeScript types for the manifest schema, not a client library, so it will not run a pipeline from a browser. The sharper comparison is against the provider SDK you would otherwise use directly, say genblaze-openai against the OpenAI Python SDK. The provider SDK gives you the newest model on day one and no adapter layer to wait on. Genblaze gives you one Pipeline shape across eleven adapters and a manifest per run, at the cost of adapter lag whenever a vendor changes its API. That trade is worth it when you are genuinely multi-provider or genuinely need the provenance record. It is dead weight when you have one provider and no audit requirement.

What to check before you build on it

Three checks, all traceable to the material above. First, confirm your adapters return bytes or route through ObjectStorageSink. If a provider only hands back a URL, that asset will not pass Manifest.verify(), and you have adopted a provenance layer that does not cover your outputs. Second, decide your pinning strategy before the first deploy: pick the exact umbrella version from the wave's released package versions list, then generate a lockfile, because the umbrella's ranges leave genblaze-core floating. Third, if you need to prove authorship to a sceptical third party rather than detect accidental corruption, plan the signer or C2PA layer now, since the manifest alone is tamper-evident in trusted storage and no more. If those three hold, the replay path is the payoff: genblaze replay manifest.json reconstructs a run from provider, model, prompt, params, and timestamps, which is the concrete thing you get for accepting a pipeline abstraction over a direct API call.

Editorial conclusion

Adopt Genblaze if you run multi-provider media generation and need a per-run manifest that survives a provider swap, and if your assets land in B2 or another S3-compatible store so that ObjectStorageSink can hash them. Do not adopt it for a chat-only loop, for a browser-side TypeScript app, or for adversarial provenance where you need C2PA or a signer you control. Before committing, verify three things in your own environment: that your chosen adapters return bytes or route through ObjectStorageSink rather than URL-only outputs, that a lockfile pins the transitive genblaze-core range the umbrella leaves open, and that the exact umbrella version you pin exists on PyPI rather than only as a wave tag.

Official sources

  1. backblaze-labs/genblaze on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes