Marvin (PrefectHQ)
raw JSON → 3.2.7 verified Tue May 12 auth: no python install: stale quickstart: draft
AI functions and agentic workflow library by PrefectHQ. Provides decorator-based AI functions (marvin.fn, marvin.classify, marvin.extract, marvin.cast) and agent/task orchestration. v3.0 released 2024 — merged with ControlFlow, switched LLM backend from OpenAI-only to Pydantic AI (multi-provider). Current version: 3.2.7 (Mar 2026). WARNING: 'marvin' on PyPI is PrefectHQ's AI library — not the SDSS astronomy Marvin library (sdss-marvin on PyPI).
pip install marvin Common errors
error ValueError: OpenAI API key not found! ↓
cause Marvin often defaults to using OpenAI for its language models and requires an API key to be set, even when other providers might be intended for use or local models are running.
fix
Set the
OPENAI_API_KEY or MARVIN_OPENAI_API_KEY environment variable before running your application. Alternatively, you can configure it programmatically using marvin.settings.openai.api_key = 'your_key_here' (though environment variables are recommended for production). error ImportError: cannot import name 'ai_fn' from 'marvin' ↓
cause In Marvin v3.0+, the API was significantly refactored, and older function names like `ai_fn` and `ai_model` were renamed to `fn` and `Agent` respectively. Attempting to import the old names from the top-level `marvin` package will result in an `ImportError`.
fix
Update your imports to use the new names:
from marvin import fn, Agent instead of from marvin import ai_fn, ai_model. error AttributeError: module 'openai' has no attribute 'ChatCompletion' ↓
cause This error typically arises when using an outdated version of the `openai` Python library (specifically versions older than 1.0.0) with code that expects the newer client-based API for chat completions. Marvin uses Pydantic AI which interfaces with various LLM providers, including OpenAI, making this a common dependency issue.
fix
Upgrade your
openai package to the latest version using pip install --upgrade openai and update your code to use the modern client API (e.g., from openai import OpenAI; client = OpenAI(); client.chat.completions.create(...)). Warnings
breaking marvin v2 was OpenAI-only. v3 uses Pydantic AI as backend supporting all providers. marvin.settings.openai.api_key configuration pattern from v2 is gone. ↓
fix Set OPENAI_API_KEY env var. Or configure other providers via pydantic-ai settings.
breaking ControlFlow's @flow decorator removed in v3. ControlFlow merged into marvin. Use marvin.Thread() context manager instead. ↓
fix Replace @flow decorated functions with 'with marvin.Thread(): marvin.run(...)' pattern.
breaking Thread/message history storage changed to SQLite in v3. No database migrations available — expect data loss when updating during development. ↓
fix Reset SQLite data after version updates during development. Production: handle migrations manually.
gotcha Name collision: 'marvin' PyPI package is PrefectHQ's AI library. 'sdss-marvin' is the SDSS astronomy toolkit. LLMs may conflate them. They are completely unrelated. ↓
fix pip install marvin for AI functions. pip install sdss-marvin for astronomy. Never mix.
gotcha Marvin defaults to OpenAI gpt-4o. No model specified = OpenAI API call. Fails silently with AuthenticationError if OPENAI_API_KEY not set. ↓
fix Set OPENAI_API_KEY or configure a different pydantic-ai provider explicitly.
gotcha ai_fn decorator from very old v1 docs still appears in many tutorials. Renamed to marvin.fn in v2+. ↓
fix Use @marvin.fn not @ai_fn.
breaking Installation of Python packages with Rust extensions (e.g., 'temporalio') often fails on Alpine Linux (musl) due to dynamic linking requirements of the Rust toolchain or its dependencies (e.g., missing 'libgcc_s.so.1' and '_Unwind' symbols). This occurs because the Rust components might be compiled for glibc, which is incompatible with musl environments. ↓
fix Install build essentials and C/C++ libraries in your Alpine environment (e.g., 'apk add build-base libstdc++'). Alternatively, use a glibc-based Python image or ensure you're using a Rust toolchain specifically compiled for musl targets.
Install compatibility stale last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - - -
3.10 slim (glibc) - - 6.23s 367M
3.11 alpine (musl) - - - -
3.11 slim (glibc) - - 8.13s 399M
3.12 alpine (musl) - - - -
3.12 slim (glibc) - - 9.05s 385M
3.13 alpine (musl) - - - -
3.13 slim (glibc) - - 8.55s 384M
3.9 alpine (musl) - - 8.80s 80.5M
3.9 slim (glibc) - - 7.63s 80M
Imports
- marvin.extract wrong
from marvin import settings settings.openai.api_key = 'sk-...' result = marvin.extract(...)correctimport marvin result = marvin.extract( 'i found $30 on the ground and bought 5 bagels for $10', int, instructions='only USD amounts' ) print(result) # [30, 10] - marvin.fn decorator wrong
from marvin import ai_fn @ai_fn def sentiment(text: str) -> float: ...correctimport marvin @marvin.fn def sentiment(text: str) -> float: """Returns sentiment score from -1.0 (negative) to 1.0 (positive).""" score = sentiment('I love this product!') print(score) # ~0.9 - marvin.Thread (v3) wrong
from controlflow import flow @flow def my_flow(): ...correctimport marvin with marvin.Thread() as thread: marvin.run('What is quantum computing?') marvin.run('How does that relate to AI?')
Quickstart draft last tested: 2026-04-23
# pip install marvin
import marvin
import os
# Set OPENAI_API_KEY env var — marvin uses OpenAI by default
# Structured extraction
numbers = marvin.extract(
'I paid $45 for lunch and $12 for coffee',
int,
instructions='USD amounts only'
)
print(numbers) # [45, 12]
# Classification
category = marvin.classify(
'The new iPhone has great camera features',
labels=['tech', 'sports', 'politics']
)
print(category) # 'tech'
# AI function
@marvin.fn
def translate(text: str, language: str) -> str:
"""Translates text to the given language."""
print(translate('Hello world', 'Spanish')) # 'Hola mundo'