mrkeyoor.com_
Sat 08 Aug 20:58 UTC
PyPIUtilsupdated 08 Aug 2026

logfire-api

logfire-api is an optional-integration shim for Python library authors. Code imports logfire_api and writes against a clone of Pydantic Logfire's public Python API. If the real logfire package is installed, the shim replaces its own module entry with logfire and calls become real telemetry. If logfire is absent, logging, spans, decorators, integrations, baggage, and configuration quietly become no-ops. It is not an observability backend, exporter, or lightweight edition of the Logfire SDK.

Verdict

A clever dependency-boundary tool for library authors, and the wrong package for most applications. If you expect to see telemetry, install and configure logfire rather than trusting a shim whose core promise is silence.

API stability3/5The package deliberately clones Logfire's public import surface and ships a large py.typed stub tree, so ordinary info, span, instrument, with_tags, context, and integration calls type-check without the SDK. Stability depends on close version alignment with a fast-growing upstream API, however, and the permissive fallback can hide a misspelled or newly added runtime attribute behind MagicMock.
Docs2/5The package README is admirably direct about its audience and no-op contract, and the source plus type stubs make the mechanism inspectable. It is only a few lines long, though, with no dedicated compatibility policy, dependency-extra recipe, dual-environment testing guide, fallback return-value reference, or warning about the sys.modules aliasing behavior developers discover in the implementation.
Maintenance5/5PyPI lists 4.40.0 released in August 2026, the pydantic/logfire repository was pushed the same week, and the package's generated declarations cover a wide current surface including framework, database, AI, context, sampling, and variables APIs. It is maintained alongside the real SDK, which is exactly what a compatibility shim needs, though consumers should still pin compatible ranges.
Ecosystem3/5The shim mirrors Logfire's broad set of integrations and lets downstream libraries offer opt-in telemetry without requiring the full SDK. Its millions of installs likely include transitive use, which fits that role. Outside the Logfire ecosystem it adds little: it is not an exporter, neutral tracing standard, backend, logger, or general plugin interface, and the hosted Logfire server remains separate.

Use it if

  • You maintain a reusable package that should emit Logfire telemetry only when its application opts in
  • You want a zero-runtime-dependency import path with bundled type stubs matching the current Logfire API
  • Your library must keep working when Logfire is not installed, without scattered try and except ImportError blocks
  • You accept silent no-op behavior as the explicit contract for the optional integration
Skip it if

Setup reality

For a reusable library, add logfire-api as a normal dependency and import it as logfire_api. Do not depend on logfire unless telemetry is mandatory; the whole point is that the host application chooses whether to install the full SDK. Version 4.40.0 requires Python 3.10 or newer and declares no runtime dependencies. At import time it tries importlib.import_module('logfire'). When successful, it assigns that real module into sys.modules under the shim name, so subsequent logfire_api calls are actual Logfire calls. When the import fails, the local implementation supplies no-op functions, context managers, decorators, integration methods, baggage and context helpers, and placeholder option classes. That means development can look perfectly healthy while production emits nothing, or the reverse, unless you test both dependency states. The fallback is intentionally forgiving: unknown instance attributes return MagicMock, configure accepts arbitrary arguments, instrument returns the original function, ASGI and WSGI helpers return the original app, span returns a context manager whose is_recording() is false, and logfire_info reports that it is not implemented. This is convenient for compatibility but poor at catching misspellings dynamically; depend on the shipped py.typed stubs and run a type checker. Avoid using runtime-specific return values from optional calls, because fallback methods often return None, empty dictionaries, null context managers, or mocks rather than meaningful SDK objects. Import through logfire_api consistently inside the library. Importing logfire directly defeats optional installation, while mixing both names makes tests dependent on import order and the sys.modules substitution. Document an extra such as your-package[logfire] that installs a compatible logfire version for application owners. In CI, run one environment with only logfire-api and another with the full SDK. The no-SDK test should prove functionality is unchanged; the SDK test should assert emitted spans or use Logfire's test facilities. This package does not configure credentials, an exporter, a project, scrubbing, or sampling for users. Those are application-level Logfire responsibilities.

Patterns

Emit a structured event from a libraryemit-optional-log

import logfire_api

def parse_document(document_id: str) -> None:
    logfire_api.info('Parsing document {document_id}', document_id=document_id)
    # library work continues whether Logfire is installed or not

With only logfire-api installed, this call returns silently and records no event.

Wrap work in an optional spantrace-optional-span

import logfire_api

def rebuild_index(index_name: str) -> None:
    with logfire_api.span('Rebuild index {index_name}', index_name=index_name):
        run_rebuild(index_name)

The fallback span is a valid context manager, so library control flow stays the same without the SDK.

Decorate a function without requiring Logfireinstrument-function

import logfire_api

@logfire_api.instrument('Resolve customer')
def resolve_customer(customer_id: str):
    return repository.get(customer_id)

When Logfire is absent, the fallback decorator returns the original function unchanged.

Create a tagged optional loggerattach-tags

import logfire_api

telemetry = logfire_api.with_tags('payments', 'library')
telemetry.info('Payment adapter selected {adapter}', adapter='example')

The fallback returns the same no-op Logfire instance; do not use tags as application state.

Record and re-raise an exceptionrecord-exception

import logfire_api

def load_record(record_id: str):
    try:
        return backend.load(record_id)
    except Exception:
        logfire_api.exception('Failed to load {record_id}', record_id=record_id)
        raise

The exception still propagates without Logfire because the explicit raise, not the telemetry call, preserves behavior.

Pass optional trace context across a boundarypropagate-context

import logfire_api

def outgoing_headers() -> dict[str, str]:
    context = logfire_api.get_context()
    return {f'x-trace-{key}': str(value) for key, value in context.items()}

def consume(headers: dict[str, str]):
    context = {key[8:]: value for key, value in headers.items() if key.startswith('x-trace-')}
    with logfire_api.attach_context(context):
        process_message()

Without the real SDK, get_context returns an empty dictionary and attach_context is a no-op context manager.

Suppress telemetry around internal transportsuppress-instrumentation

import logfire_api

def export_internal_batch(batch):
    with logfire_api.suppress_instrumentation():
        transport.send(batch)

The fallback is a null context manager; this pattern matters only when the full SDK is present.

Detect whether the real SDK is installeddetect-real-sdk

from importlib.util import find_spec

LOGFIRE_AVAILABLE = find_spec('logfire') is not None

Check the real package name before importing the shim; after import, logfire_api may be an alias to the logfire module.

Keep library behavior independent of telemetrytest-both-modes

def test_processing_result_is_not_telemetry_dependent(monkeypatch):
    import logfire_api

    monkeypatch.setattr(logfire_api, 'info', lambda *args, **kwargs: None)
    assert process('input') == 'expected'

Run a separate integration environment with logfire installed to test real event emission; this only proves the library tolerates no-op telemetry.

Alternatives

PackageRegistryPick it when
logfirePyPIYou own the application and actually want the Logfire SDK, exporters, integrations, and configuration
opentelemetry-apiPyPIYou want a vendor-neutral instrumentation API whose provider can be installed separately
structlogPyPIYour requirement is structured application logging rather than optional traces, metrics, and Logfire integrations