feat: Add logfire.db_api — PEP 249 DB API 2.0 interface#1692
Conversation
Adds a DB API 2.0 (PEP 249) compatible module that wraps LogfireQueryClient, enabling Logfire query data to work with any tool that supports standard Python database connections — pandas read_sql(), marimo SQL cells, Jupyter %%sql, etc.
Deploying logfire-docs with
|
| Latest commit: |
7f132c2
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://96b654e2.logfire-docs.pages.dev |
| Branch Preview URL: | https://feat-db-api-2.logfire-docs.pages.dev |
The DB API is for querying data from the Logfire platform, not for instrumenting applications, so it doesn't belong in the no-op shim.
logfire/db_api.py
Outdated
| base_url: str | None = None, | ||
| timeout: float = 30.0, | ||
| *, | ||
| min_timestamp: datetime | None = None, |
There was a problem hiding this comment.
This needs a default, not having one in the query client is enough of a problem
There was a problem hiding this comment.
Added a default of timedelta(days=30) which gets resolved to datetime.now(utc) - timedelta at connection time. The min_timestamp parameter now accepts datetime | timedelta | None:
timedelta(default) — relative window computed at connect timedatetime— exact boundNone— no filter
There was a problem hiding this comment.
Pull request overview
Adds a new logfire.db_api module implementing a PEP 249 (DB API 2.0) interface on top of LogfireQueryClient, enabling interoperability with DB-API consumers (e.g., pandas read_sql, notebook SQL magics), plus accompanying tests and documentation.
Changes:
- Introduce
logfire.db_apiwithconnect(),Connection,Cursor, parameter interpolation, and truncation warnings at the server row limit. - Add comprehensive pytest coverage for connection/cursor behavior, fetching methods, parameter substitution, timestamps, and warnings.
- Document usage patterns (basic usage, pandas, parameters, row limits) in the query API guide.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
logfire/db_api.py |
New DB API 2.0 wrapper around LogfireQueryClient with client-side param interpolation and truncation warnings. |
tests/test_db_api.py |
New tests validating PEP 249-style behaviors and the wrapper’s HTTP request construction via mock transport. |
docs/how-to-guides/query-api.md |
New documentation section explaining how to use logfire.db_api with common tools. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add default min_timestamp of 30 days ago (accepts datetime, timedelta, or None) - Reject str/bytes as parameters in _substitute_params - Use pytest.warns for truncation warning test - Fix skip directive in marimo docs example
- Use `if parameters is not None:` so empty dict/list still triggers `%%` → `%` conversion per pyformat paramstyle - Remove unused `marimo` import from docs code block
…on-level filters Previously, cursor-level min_timestamp/max_timestamp used `or` fallback which made it impossible to explicitly disable a connection-level timestamp filter from a cursor (None would always fall through to the connection value). Now _UNSET means "inherit from connection" and None means "no filter".
|
Re: Devin's comment about truncation warning and Good catch. Disallowed |
When limit=None was passed through, the server would silently cap at 500 rows and our truncation warning wouldn't fire since effective_limit was None. Now cursor.limit is typed as int, always resolving to a concrete value.
Summary
logfire.db_apimodule implementing PEP 249 (DB API 2.0), wrapping the existingLogfireQueryClientread_sql(), marimo SQL cells, Jupyter%%sqlmagic, and any other DB API 2.0 compatible tool — notably, marimo has built-in support for DB API 2.0 connections in its SQL cellsquery_json_rowsunder the hood with client-side parameter interpolation (pyformatstyle). Plan is to move to server-side parameterization in a follow-up once theparamsfield is plumbed through the backend query endpointlogfire-api. @alexmojaki — not sure this module really belongs inlogfire-apisince it's a tool for querying data rather than something libraries would use as a no-op shim. Happy to remove the stubs if you agree