Model or dataset
datapizza-labs/datapizza-ai avatar
datapizza-labs/datapizza-ai

datapizza-ai: A Python GenAI Framework That Keeps Agents Explicit

Build reliable Gen AI solutions without overhead 🍕

2,240 stars139 forksPythonMIT

At a glance

What is it?
datapizza-ai is an MIT-licensed Python framework for building agents and RAG pipelines with OpenAI, Gemini, Anthropic, Mistral and Azure clients. Its selling point is less abstraction, which also means you assemble more of the agent loop yourself.
Who is it for?
Adopt datapizza-ai if you want a small Python surface for multi-provider clients, decorated tools and OpenTelemetry tracing, and you are comfortable owning the agent loop and dependency pinning yourself. Do not adopt it if you need a multi-month support guarantee, a large third-party integration catalogue, or a framework that decides orchestration for you.
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 120 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 problem datapizza-ai targets: provider churn and opaque agent loops

Two problems show up repeatedly in Python GenAI work. The first is provider churn. You write an application against one vendor's SDK, the model lineup shifts, and the same business logic has to be rewritten against a different client class. The second is debugging. A multi-step agent that calls tools and delegates to other agents is hard to reason about when the framework hides the loop, and even harder when there is no structured trace of what the model saw and returned.

datapizza-ai addresses both by staying close to the metal. The README frames the project as "A no-fluff GenAI framework that gets your agents from dev to prod" and lists vendor-agnostic clients for OpenAI, Google Gemini, Anthropic, Mistral and Azure as a first-class feature. The audience is Python engineers who already know what an agent loop is and would rather assemble it than inherit someone else's opinion about it. The README's own framing, "Built by Engineers, trusted by Engineers", is marketing, but the API shape behind it is consistent with that claim: a client, an Agent, a tool decorator, and tracing you opt into.

It is not aimed at people who want a visual builder or a batteries-included orchestration graph. The repository is a Python package with a docs site, and the examples in the README are short scripts, not configuration files.

How the client and Agent layers fit together

The entry point is a provider client. The README's first example constructs OpenAIClient with an api_key and calls invoke on a string, then reads result.text. That is the whole contract for a single-shot call: construct, invoke, read the text attribute.

Above the client sits Agent. The quick start builds one with a name, a client and a tools list, then calls agent.run with a natural language prompt. The README's weather example shows the expected shape of the answer: the agent receives "What is the weather in Rome?", the model selects the get_weather tool, and the printed result is the tool's return string.

Multi-agent composition is expressed through can_call. In the trip planning example, a planner_agent is given a system prompt and then told planner_agent.can_call([weather_agent, web_search_agent]). The planner is expected to route work to the two specialists. The README does not document the termination conditions, the maximum delegation depth, or what happens when two sub-agents both claim the same request, so treat the delegation semantics as something you verify against the source before you build a production topology on it.

Everything routes through the same client object in that example: all three agents share one OpenAIClient instance, with the model set to gpt-4.1 at construction. Swapping providers therefore means changing the client class, not the agent code.

Tools, decorators and the RAG side of the package

Tools are plain Python functions wrapped with @tool from datapizza.tools. The decorator reads the type annotations, so get_weather(city: str) -> str becomes a callable the model can select. This is the least surprising part of the design and the easiest to test, because the underlying function still runs as ordinary Python.

On the retrieval side, the README lists document processing for PDF, DOCX and images via Azure AI and Docling, context-aware chunking and embedding, and built-in reranking with Cohere named as an example reranker. The document ingestion example is truncated in the supplied README at the sentence about parsing PDFs and splitting them into chunks, so the exact pipeline API for ingestion is not visible in the material available here. What is clear is that these pieces are described as optional components rather than a single monolithic index: the README's feature table puts them under a "Composable" heading with "Reusable blocks: Declarative configuration, easy overrides".

That composability is the reason the package is split. Core installation is pip install datapizza-ai, and provider support arrives through separate distributions such as datapizza-ai-clients-openai, datapizza-ai-clients-google and datapizza-ai-clients-anthropic. The DuckDuckGo search tool is a fourth package, datapizza-ai-tools-duckduckgo. You pay for what you import.

Getting it running: install lines and the tracing context manager

The install path is a single pip command for the core, plus optional provider packages. The README gives pip install datapizza-ai, then pip install datapizza-ai-clients-openai, datapizza-ai-clients-google and datapizza-ai-clients-anthropic for specific providers, and pip install datapizza-ai-tools-duckduckgo for the search tool. Python 3.10 or newer is required according to the badge in the README.

The tracing API is a context manager. You import ContextTracing from datapizza.tracing, wrap the agent call in with ContextTracing().trace("my_ai_operation"):, and the README shows a console summary with total spans, duration, and a table of model name, prompt tokens, completion tokens and cached tokens. The sample output in the README reports three spans and a duration of 2.45 seconds for a Bitcoin news query against gpt-4o-mini. That is a README illustration, not a benchmark, and it should not be read as a performance claim.

The README also states that the framework provides OpenTelemetry tracing and an optional client I/O tracing toggle that logs inputs, outputs and in-memory context. The console summary and the OpenTelemetry export are described in the same section, but the material here does not show the exporter configuration, so confirm from the docs whether the OTLP endpoint is set through environment variables or through a tracing constructor argument before you plan a collector deployment.

Where the low-abstraction approach costs you

The trade-off is explicit in the project's own pitch. "Less abstraction, more control" cuts both ways. A framework that hides the loop can also handle retries, partial tool failures, context window trimming and message history compaction for you. datapizza-ai's README shows memory management as a feature bullet under "Persistent conversations and context awareness", but the examples given are single-turn: one invoke call, one agent.run call, one planner run. Nothing in the supplied material shows how history is persisted, where it is stored, or how it is truncated when a conversation outgrows the model's context window.

Version maturity is the second constraint. The release history shows v0.1.0 on 2026-03-13, preceded by v0.0.9 in November 2025 and v0.0.7 in October 2025. A 0.x version line means the public API can move between minor releases, and the split into separately versioned client and tool packages multiplies the number of version pairs you have to keep compatible. Pin your dependencies and read the release notes before upgrading.

The third constraint is scope. If your problem is a single prompt against a single model, this framework adds a client class and a dependency tree for no benefit. If your problem is a stateful workflow engine with human-in-the-loop approvals and durable execution across process restarts, the README does not describe those primitives, and you would be building them on top.

How it differs from LangChain and LlamaIndex

The comparison that matters is with LangChain and LlamaIndex, because both occupy the same Python slot.

LangChain's approach is a broad integration surface: chains, runnables, a large catalogue of community connectors, and LangGraph for stateful agent orchestration. Its cost is indirection. Tracing a failure often means reading through several layers of wrappers before you find the call that actually hit the provider. datapizza-ai inverts that. There is a client, an Agent, a @tool decorator and a can_call relationship, and the README's examples fit on one screen. You get fewer integrations and you write more glue.

LlamaIndex is retrieval-first. Its centre of gravity is indexing, node parsing, query engines and retrievers, with agents layered on later. datapizza-ai's README lists document processing, chunking and reranking as features, but the agent examples come first and the ingestion example is the one truncated in the README. If your project is fundamentally a search or question-answering system over a document corpus, LlamaIndex's retrieval abstractions are deeper and better documented than what is visible here.

Pydantic AI is the closer analogue in spirit: typed, Pythonic, provider-agnostic. The difference visible in this material is that datapizza-ai ships its own OpenTelemetry tracing context manager and an explicit can_call mechanism for agent-to-agent delegation, rather than routing through a graph definition.

Maintenance cost, licence and what to pin

The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive arrangement and, unlike copyleft licences, it does not require you to publish modifications. This is a description of the licence text, not legal advice; if your organisation has a licence review process, run the package and its optional client distributions through it.

The maintenance cost is organisational rather than financial. The project is not archived and the last push recorded is 2026-05-19, so the repository is active. But the version history is short and the 0.x line means you own the upgrade risk. The concrete steps are to pin datapizza-ai and every datapizza-ai-clients-* and datapizza-ai-tools-* package to exact versions in your lockfile, and to re-run your agent test suite after each bump, because a change in one client package can alter tool-call formatting without any change in the core package.

There is no separate enterprise tier, no hosted control plane and no vendor account implied by the material here. Your operational surface is the Python process, your provider API keys, and whichever tracing backend you point OpenTelemetry at.

Editorial conclusion

Adopt datapizza-ai if you want a small Python surface for multi-provider clients, decorated tools and OpenTelemetry tracing, and you are comfortable owning the agent loop and dependency pinning yourself. Do not adopt it if you need a multi-month support guarantee, a large third-party integration catalogue, or a framework that decides orchestration for you. Before committing, verify three things against the docs and the source: how the planner-style can_call delegation terminates, whether the tracing exporter is configured or only the local console summary, and which provider package versions pair with datapizza-ai 0.1.0.

Official sources

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

Community notes