diff --git a/CHANGELOG.md b/CHANGELOG.md index c9912754..780f5bc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Release Notes +## [v2.11.1] (2024-12-30) + +* Handle errors from `sqlalchemy.inspect` by @alexmojaki in [#733](https://github.com/pydantic/logfire/pull/733) + ## [v2.11.0] (2024-12-23) * Add `capture_request_text_body` param to `instrument_httpx` by @alexmojaki in [#722](https://github.com/pydantic/logfire/pull/722) @@ -499,3 +503,4 @@ First release from new repo! [v2.9.0]: https://github.com/pydantic/logfire/compare/v2.8.0...v2.9.0 [v2.10.0]: https://github.com/pydantic/logfire/compare/v2.9.0...v2.10.0 [v2.11.0]: https://github.com/pydantic/logfire/compare/v2.10.0...v2.11.0 +[v2.11.1]: https://github.com/pydantic/logfire/compare/v2.11.0...v2.11.1 diff --git a/logfire-api/logfire_api/_internal/integrations/sqlite3.pyi b/logfire-api/logfire_api/_internal/integrations/sqlite3.pyi index 33f823e1..50160369 100644 --- a/logfire-api/logfire_api/_internal/integrations/sqlite3.pyi +++ b/logfire-api/logfire_api/_internal/integrations/sqlite3.pyi @@ -1,13 +1,10 @@ import sqlite3 from opentelemetry.trace import TracerProvider -from typing import TypeVar, TypedDict, Unpack +from typing import Any, TypeVar -SQLite3Connection = TypeVar('SQLite3Connection', bound=sqlite3.Connection | None) +SQLite3Connection = TypeVar('SQLite3Connection', sqlite3.Connection, None) -class SQLite3InstrumentKwargs(TypedDict, total=False): - skip_dep_check: bool - -def instrument_sqlite3(*, conn: SQLite3Connection, tracer_provider: TracerProvider, **kwargs: Unpack[SQLite3InstrumentKwargs]) -> SQLite3Connection: +def instrument_sqlite3(*, conn: SQLite3Connection, tracer_provider: TracerProvider, **kwargs: Any) -> SQLite3Connection: """Instrument the `sqlite3` module so that spans are automatically created for each query. See the `Logfire.instrument_sqlite3` method for details. diff --git a/logfire-api/logfire_api/_internal/integrations/wsgi.pyi b/logfire-api/logfire_api/_internal/integrations/wsgi.pyi index 8aa43038..f8e41d25 100644 --- a/logfire-api/logfire_api/_internal/integrations/wsgi.pyi +++ b/logfire-api/logfire_api/_internal/integrations/wsgi.pyi @@ -1,19 +1,9 @@ -from logfire import Logfire as Logfire from logfire._internal.utils import maybe_capture_server_headers as maybe_capture_server_headers -from opentelemetry.trace import Span -from typing import Callable, Protocol, TypedDict -from typing_extensions import Unpack -from wsgiref.types import WSGIApplication, WSGIEnvironment +from logfire.integrations.wsgi import RequestHook as RequestHook, ResponseHook as ResponseHook +from typing import Any +from wsgiref.types import WSGIApplication -class ResponseHook(Protocol): - def __call__(self, span: Span, environ: WSGIEnvironment, status_code: int, response_headers: list[tuple[str, str]]) -> None: ... -RequestHook = Callable[[Span, WSGIEnvironment], None] - -class WSGIInstrumentKwargs(TypedDict, total=False): - request_hook: RequestHook | None - response_hook: ResponseHook | None - -def instrument_wsgi(logfire_instance: Logfire, app: WSGIApplication, *, capture_headers: bool = False, **kwargs: Unpack[WSGIInstrumentKwargs]) -> WSGIApplication: +def instrument_wsgi(app: WSGIApplication, *, capture_headers: bool = False, request_hook: RequestHook | None = None, response_hook: ResponseHook | None = None, **kwargs: Any) -> WSGIApplication: """Instrument `app` so that spans are automatically created for each request. See the `Logfire.instrument_wsgi` method for details. diff --git a/logfire-api/logfire_api/_internal/main.pyi b/logfire-api/logfire_api/_internal/main.pyi index d106df7b..9c90169d 100644 --- a/logfire-api/logfire_api/_internal/main.pyi +++ b/logfire-api/logfire_api/_internal/main.pyi @@ -5,6 +5,7 @@ import opentelemetry.trace as trace_api import requests from . import async_ as async_ from ..integrations.flask import CommenterOptions as CommenterOptions, RequestHook as FlaskRequestHook, ResponseHook as FlaskResponseHook +from ..integrations.wsgi import RequestHook as WSGIRequestHook, ResponseHook as WSGIResponseHook from ..version import VERSION as VERSION from .auto_trace import AutoTraceModule as AutoTraceModule, install_auto_tracing as install_auto_tracing from .config import GLOBAL_CONFIG as GLOBAL_CONFIG, LogfireConfig as LogfireConfig @@ -20,9 +21,8 @@ from .integrations.psycopg import PsycopgInstrumentKwargs as PsycopgInstrumentKw from .integrations.pymongo import PymongoInstrumentKwargs as PymongoInstrumentKwargs from .integrations.redis import RedisInstrumentKwargs as RedisInstrumentKwargs from .integrations.sqlalchemy import SQLAlchemyInstrumentKwargs as SQLAlchemyInstrumentKwargs -from .integrations.sqlite3 import SQLite3Connection as SQLite3Connection, SQLite3InstrumentKwargs as SQLite3InstrumentKwargs +from .integrations.sqlite3 import SQLite3Connection as SQLite3Connection from .integrations.system_metrics import Base as SystemMetricsBase, Config as SystemMetricsConfig -from .integrations.wsgi import WSGIInstrumentKwargs as WSGIInstrumentKwargs from .json_encoder import logfire_json_dumps as logfire_json_dumps from .json_schema import JsonSchemaProperties as JsonSchemaProperties, attributes_json_schema as attributes_json_schema, attributes_json_schema_properties as attributes_json_schema_properties, create_json_schema as create_json_schema from .metrics import ProxyMeterProvider as ProxyMeterProvider @@ -685,7 +685,7 @@ class Logfire: Returns: The instrumented ASGI application. """ - def instrument_wsgi(self, app: WSGIApplication, capture_headers: bool = False, **kwargs: Unpack[WSGIInstrumentKwargs]) -> WSGIApplication: + def instrument_wsgi(self, app: WSGIApplication, capture_headers: bool = False, request_hook: WSGIRequestHook | None = None, response_hook: WSGIResponseHook | None = None, **kwargs: Any) -> WSGIApplication: """Instrument `app` so that spans are automatically created for each request. Uses the WSGI [`OpenTelemetryMiddleware`][opentelemetry.instrumentation.wsgi.OpenTelemetryMiddleware] under @@ -697,6 +697,8 @@ class Logfire: Args: app: The WSGI application to instrument. capture_headers: Set to `True` to capture all request and response headers. + request_hook: A function called right after a span is created for a request. + response_hook: A function called right before a span is finished for the response. **kwargs: Additional keyword arguments to pass to the OpenTelemetry WSGI middleware. Returns: @@ -720,7 +722,7 @@ class Logfire: engine: The `sqlalchemy` engine to instrument, or `None` to instrument all engines. **kwargs: Additional keyword arguments to pass to the OpenTelemetry `instrument` methods. """ - def instrument_sqlite3(self, conn: SQLite3Connection = None, **kwargs: Unpack[SQLite3InstrumentKwargs]) -> SQLite3Connection: + def instrument_sqlite3(self, conn: SQLite3Connection = None, **kwargs: Any) -> SQLite3Connection: """Instrument the `sqlite3` module or a specific connection so that spans are automatically created for each operation. Uses the diff --git a/logfire-api/logfire_api/integrations/wsgi.pyi b/logfire-api/logfire_api/integrations/wsgi.pyi new file mode 100644 index 00000000..e7263b85 --- /dev/null +++ b/logfire-api/logfire_api/integrations/wsgi.pyi @@ -0,0 +1,5 @@ +from _typeshed import Incomplete +from wsgiref.types import WSGIEnvironment as WSGIEnvironment + +ResponseHook: Incomplete +RequestHook: Incomplete diff --git a/logfire-api/pyproject.toml b/logfire-api/pyproject.toml index 9eeb86f5..ac072bb8 100644 --- a/logfire-api/pyproject.toml +++ b/logfire-api/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "logfire-api" -version = "2.11.0" +version = "2.11.1" description = "Shim for the Logfire SDK which does nothing unless Logfire is installed" authors = [ { name = "Pydantic Team", email = "engineering@pydantic.dev" }, diff --git a/pyproject.toml b/pyproject.toml index c879639d..47b8655a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "logfire" -version = "2.11.0" +version = "2.11.1" description = "The best Python observability tool! 🪵🔥" requires-python = ">=3.8" authors = [ diff --git a/uv.lock b/uv.lock index 5b301fdb..1149fe38 100644 --- a/uv.lock +++ b/uv.lock @@ -1435,7 +1435,7 @@ wheels = [ [[package]] name = "logfire" -version = "2.11.0" +version = "2.11.1" source = { editable = "." } dependencies = [ { name = "executing" }, @@ -1718,7 +1718,7 @@ docs = [ [[package]] name = "logfire-api" -version = "2.11.0" +version = "2.11.1" source = { editable = "logfire-api" } [package.metadata]