Pydantic Logfire ships the client, not the platform
AI observability platform for production LLM and agent systems.
At a glance
- What is it?
- The open source half of Pydantic Logfire is a Python SDK that turns brace templates and span calls into OpenTelemetry records. The platform that stores and displays them is closed source, so the interesting boundary is between what you can install and what you can run.
- Who is it for?
- Adopt the Python SDK if your team already lives in Python and wants records it can query with SQL, and if shipping that data to a hosted service is acceptable. Skip it if the recording and display server has to sit inside your own network without an enterprise license, because this repository ships only the client.
- 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 received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- pydantic/logfire4,552 ★ · +78
| Repository | 2026-09-13 | 2026-11-14 |
|---|---|---|
| pydantic/logfire | 4.5k | 4.6k |
78 Stars in the last 62 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
`pip install logfire` pulls the CLI as well as the SDK
Start with `pip install logfire`, which brings in both the Python SDK and the Logfire CLI. If you only want the library and not the command line tool, `pip install logfire-sdk` does that, and the import stays `import logfire` either way. Point the SDK at a destination with `logfire auth`, then call `logfire.configure()` once at process start. The shortest useful program is three lines.
import logfire
logfire.configure()
logfire.info('Hello, {name}!', name='world')The README's own example goes further and wraps work in a named span, then logs the parsed value with f-string style debug syntax.
from datetime import date
import logfire
logfire.configure()
logfire.info('Hello, {name}!', name='world')
with logfire.span('Asking the user their {question}', question='age'):
user_input = input('How old are you [YYYY-mm-dd]? ')
dob = date.fromisoformat(user_input)
logfire.debug('{dob=} {age=!r}', dob=dob, age=date.today() - dob)Both fenced examples in the repository carry a `skip-run` marker, one with the reason `blocking` because of the `input()` call and one with the reason `global-instrumentation`. Read them as shape, not as scripts to paste.
Brace templates turn print calls into fields you can filter on
`logfire.info('Hello, {name}!', name='world')` is the whole idea in one line. The braces are a template, `name='world'` supplies the value, and what gets recorded is a message plus a separate `name` attribute, rather than one flat string you have to parse later. Spans use the same grammar. `logfire.span('Asking the user their {question}', question='age')` opens a named region that later records nest inside, which is how you get duration on the region instead of on each line. The debug form leans on f-string syntax: `logfire.debug('{dob=} {age=!r}', dob=dob, age=date.today() - dob)` captures the variable name automatically in the first placeholder and attaches a `repr` format spec to the second, so string values stay visibly quoted. Because the fields are structured, the query surface does not have to be free text search. What the README never spells out is any default for sampling or retention, so how fast that data grows is a decision you have to make somewhere else.
instrument_fastapi rides on an opinionated OpenTelemetry wrapper
Logfire is described as an opinionated wrapper around OpenTelemetry, and that one choice explains most of its behavior. Because the payload is standard OTel, the SDKs can export to any OTel compatible backend, and all three signals are covered: traces, metrics and logs. Support extends to virtually any language through OTel instrumentation rather than a Logfire specific agent, and separate SDK repositories exist for TypeScript and Rust, so a mixed stack does not mean two incompatible data models. On the Python side the project depends on the upstream instrumentations instead of writing its own, and the dev dependency list names them: `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette`, `opentelemetry-instrumentation-django`, `opentelemetry-instrumentation-flask`, `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-wsgi`, plus client and server builds for aiohttp. You can skip manual spans entirely and hand over the whole app with one call.
from fastapi import FastAPI
from pydantic import BaseModel
import logfire
app = FastAPI()
logfire.configure()
logfire.instrument_fastapi(app)
# next, instrument your database connector, http library etc. and add the logging handler
class User(BaseModel):
name: str
country_code: str`instrument_fastapi(app)` is the handoff point, and the comment inside the example is the honest part: your database connector and your HTTP client library still need their own instrumentation, and a logging handler still has to be added by hand.
The dev dependency group pins its own type conflicts
The `dev` dependency group in `pyproject.toml` reads like an incident report. `fastapi != 0.124.3, != 0.124.4` excludes two specific releases outright, and `pyright!=1.1.407` drops one type checker build from the editor tests. A comment attached to `types-requests` spells out the other fight in full: `requests >= 2.34` bundles inline `py.typed` annotations that shape `Session.headers` as `CaseInsensitiveDict[str]`, which rejects the `str|bytes` header values `requests` accepts at runtime and that the SDK's `DiskRetryer` passes into a `Session` in `exporters/otlp.py`, while `types-requests` types the same attribute as `MutableMapping[str, str|bytes]`. Both stubs stay in the group, with `types-requests` kept so its versions take priority. The remainder of the list is the integration surface the test suite actually exercises: `httpx >= 0.27.2`, `httpx2 >= 2.0.0`, `aiohttp >= 3.10.9`, `redis >= 5.1.1`, `pymongo >= 4.10.1`, `elasticsearch >= 8.15`, `sqlalchemy >= 1.4.54`, `pandas>=2.1.2`, `attrs >= 23.1.0`, `openai >= 1.108.1` and `litestar>=2.11.0`. That group tells you more about real integration trouble than any feature list would.
Makefile targets gate every change before it lands
Local work goes through `make`, and the targets spell out what a change has to survive. `make install` first checks that `uv` and `pre-commit` are present, then runs `uv sync --frozen`, `uv pip install -e logfire-api`, and `pre-commit install --install-hooks`. The frozen flag is deliberate: the tree ships `uv.lock`, so a contributor gets the locked set rather than whatever happens to resolve today. `make lint` runs `uv run ruff check` and then `uv run ruff format --check --diff`, and `make typecheck` runs `uv run pyright`.
uv run --no-sync pytest -n logical --dist=loadgroupThat is the whole of `make test`, and the `-n logical --dist=loadgroup` part runs the tests in parallel workers. `make generate-stubs` runs `stubgen -p logfire --include-docstrings --no-analysis`, copies `out/logfire/` into `logfire-api/logfire_api/`, removes `out`, then runs `test_override_init_pyi` twice with the first pass behind `|| true` because a failure there is expected on the first sweep.
The server that stores your spans is not in this tree
This repository holds the Python SDK and the documentation. The application that records and displays your data is closed source, and that boundary is the most consequential line in the README. The clients stay open under the MIT license, with TypeScript and Rust SDKs in their own repositories, and they can export to any OTel compatible backend, so the write path is genuinely portable. The Logfire platform, meaning the UI and the backend behind it, cannot be run from this tree. Self hosting it means purchasing an enterprise license. Two consequences follow for anyone reading this. If air-gapped or in-cluster hosting is a hard requirement, this code is not sufficient on its own, and the two real paths are the paid license or a different OTel backend with a UI you operate. If the Logfire dashboard is the reason you are here, you are on the hosted service, and nothing in this repository gives you an offline fallback to run against.
Authentication has no documented offline path
`logfire auth` is the only setup command the README gives, and it links out to the documentation for details. The README names no environment variable, token file location, service account flow for CI or headless mode. The examples also assume a person at a keyboard: the manual tracing snippet blocks on `input('How old are you [YYYY-mm-dd]? ')` and feeds the answer straight into `date.fromisoformat(user_input)`, so anything that is not an ISO date makes that call raise inside a span you thought was harmless. `logfire.configure()` is called with no arguments in both README examples, and the options it accepts are not listed there either. Rollback, retention, sampling and pricing are likewise not covered in the README. Release history is the one thing you can check locally: the feed lists v5.4.0 (2026-10-26), v5.3.0 (2026-10-23) and v5.2.0 (2026-10-13), so pin deliberately.
Editorial conclusion
Adopt the Python SDK if your team already lives in Python and wants records it can query with SQL, and if shipping that data to a hosted service is acceptable. Skip it if the recording and display server has to sit inside your own network without an enterprise license, because this repository ships only the client. Before committing, work out how `logfire auth` behaves in a non-interactive build agent, and pin the release on purpose: the release feed lists v5.4.0, v5.3.0 and v5.2.0 within two weeks of each other.
Frequently asked questions
How do I install Logfire for Python?
Run `pip install logfire`, which installs both the Python SDK and the Logfire CLI. Use `pip install logfire-sdk` for the SDK alone, since the import stays `import logfire` either way, and the repository's pyproject.toml declares requires-python >=3.10. Then run `logfire auth`.
What does Logfire do in a Python application?
It records traces, metrics and logs through an opinionated OpenTelemetry wrapper and lets you query them with standard SQL. Because the payload is OTel, the SDK can also send data to any OTel compatible backend. It also surfaces the data flowing through Pydantic validation models.
Is Logfire open source?
The SDKs are, under the MIT license, including separate TypeScript and Rust repositories, and they can export to any OTel compatible backend. The Logfire platform, meaning the UI and the server that records and displays your data, is closed source, and self hosting it requires an enterprise license.
What is Logfire Python used for?
It is the Python SDK for the Logfire observability platform. It exposes `logfire.configure()`, `logfire.info()`, `logfire.span()` and `logfire.instrument_fastapi()`, and it covers display of Python objects, event loop telemetry, profiling of Python code and of database queries, plus analytics on Pydantic validations.
How do I use Pydantic Logfire with FastAPI?
Call `logfire.configure()` and then `logfire.instrument_fastapi(app)` on your FastAPI instance, which avoids manual instrumentation for the web layer. The example in the repository notes that you still have to instrument your database connector and HTTP library yourself and add the logging handler.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pydantic-logfire)Star history chart for your README
[](https://hysenlabs.com/projects/pydantic-logfire)Was this useful?