logfire-api 5.1.1__tar.gz → 5.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. {logfire_api-5.1.1 → logfire_api-5.3.0}/PKG-INFO +1 -1
  2. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/__init__.py +6 -0
  3. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/__init__.pyi +3 -1
  4. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/auth.pyi +5 -1
  5. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/run.pyi +8 -1
  6. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/config.pyi +6 -2
  7. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/config_params.pyi +4 -0
  8. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/console.pyi +3 -3
  9. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/otlp.pyi +30 -2
  10. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/claude_agent_sdk.pyi +7 -1
  11. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/fastapi.pyi +26 -3
  12. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/flask.pyi +2 -1
  13. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/mcp.pyi +7 -2
  14. logfire_api-5.3.0/logfire_api/_internal/integrations/monty.pyi +29 -0
  15. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/openai_agents.pyi +2 -1
  16. logfire_api-5.3.0/logfire_api/_internal/integrations/snowflake.pyi +7 -0
  17. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/starlette.pyi +1 -1
  18. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/json_encoder.pyi +4 -0
  19. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/logs.pyi +6 -4
  20. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/main.pyi +37 -2
  21. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/metrics.pyi +3 -2
  22. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/tracer.pyi +2 -3
  23. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/utils.pyi +0 -3
  24. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/experimental/api_client.pyi +1 -5
  25. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/logging.pyi +1 -1
  26. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/structlog.pyi +1 -1
  27. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/query_client.pyi +21 -4
  28. {logfire_api-5.1.1 → logfire_api-5.3.0}/pyproject.toml +1 -1
  29. {logfire_api-5.1.1 → logfire_api-5.3.0}/.gitignore +0 -0
  30. {logfire_api-5.1.1 → logfire_api-5.3.0}/README.md +0 -0
  31. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/__init__.pyi +0 -0
  32. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/ast_utils.pyi +0 -0
  33. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/async_.pyi +0 -0
  34. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/auth.pyi +0 -0
  35. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/auto_trace/__init__.pyi +0 -0
  36. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/auto_trace/import_hook.pyi +0 -0
  37. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/auto_trace/rewrite_ast.pyi +0 -0
  38. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/auto_trace/types.pyi +0 -0
  39. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/baggage.pyi +0 -0
  40. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/__init__.pyi +0 -0
  41. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/ai_tools.pyi +0 -0
  42. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/gateway.pyi +0 -0
  43. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/gateway_auth.pyi +0 -0
  44. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli/prompt.pyi +0 -0
  45. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/cli.pyi +0 -0
  46. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/client.pyi +0 -0
  47. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/collect_system_info.pyi +0 -0
  48. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/constants.pyi +0 -0
  49. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/db_statement_summary.pyi +0 -0
  50. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/__init__.pyi +0 -0
  51. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/dynamic_batch.pyi +0 -0
  52. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/logs.pyi +0 -0
  53. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/processor_wrapper.pyi +0 -0
  54. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/quiet_metrics.pyi +0 -0
  55. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/remove_pending.pyi +0 -0
  56. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/tail_sampling.pyi +0 -0
  57. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/exporters/wrapper.pyi +0 -0
  58. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/formatter.pyi +0 -0
  59. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/forwarding.pyi +0 -0
  60. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/http_transport.pyi +0 -0
  61. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/instrument.pyi +0 -0
  62. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/__init__.pyi +0 -0
  63. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/aiohttp_client.pyi +0 -0
  64. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/aiohttp_server.pyi +0 -0
  65. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/asgi.pyi +0 -0
  66. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/asyncpg.pyi +0 -0
  67. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/aws_lambda.pyi +0 -0
  68. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/celery.pyi +0 -0
  69. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/django.pyi +0 -0
  70. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/dspy.pyi +0 -0
  71. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/executors.pyi +0 -0
  72. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/google_genai.pyi +0 -0
  73. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/httpx.pyi +0 -0
  74. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/litellm.pyi +0 -0
  75. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/litestar.pyi +0 -0
  76. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/mysql.pyi +0 -0
  77. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/print.pyi +0 -0
  78. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/psycopg.pyi +0 -0
  79. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/pydantic_ai.pyi +0 -0
  80. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/pymongo.pyi +0 -0
  81. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/pytest.pyi +0 -0
  82. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/redis.pyi +0 -0
  83. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/requests.pyi +0 -0
  84. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/sqlalchemy.pyi +0 -0
  85. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/sqlite3.pyi +0 -0
  86. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/surrealdb.pyi +0 -0
  87. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/system_metrics.pyi +0 -0
  88. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/integrations/wsgi.pyi +0 -0
  89. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/interactive.pyi +0 -0
  90. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/json_formatter.pyi +0 -0
  91. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/json_schema.pyi +0 -0
  92. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/json_types.pyi +0 -0
  93. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/scrubbing.pyi +0 -0
  94. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/server_response.pyi +0 -0
  95. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/stack_info.pyi +0 -0
  96. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/_internal/ulid.pyi +0 -0
  97. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/cli.pyi +0 -0
  98. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/db_api.pyi +0 -0
  99. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/exceptions.pyi +0 -0
  100. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/experimental/__init__.pyi +0 -0
  101. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/experimental/annotations.pyi +0 -0
  102. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/experimental/datasets/__init__.pyi +0 -0
  103. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/experimental/query_client.pyi +0 -0
  104. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/__init__.pyi +0 -0
  105. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/aiohttp_client.pyi +0 -0
  106. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/flask.pyi +0 -0
  107. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/httpx.pyi +0 -0
  108. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/loguru.pyi +0 -0
  109. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/psycopg.pyi +0 -0
  110. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/pydantic.pyi +0 -0
  111. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/redis.pyi +0 -0
  112. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/sqlalchemy.pyi +0 -0
  113. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/integrations/wsgi.pyi +0 -0
  114. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/propagate.pyi +0 -0
  115. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/py.typed +0 -0
  116. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/sampling/__init__.pyi +0 -0
  117. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/sampling/_tail_sampling.pyi +0 -0
  118. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/types.pyi +0 -0
  119. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/__init__.pyi +0 -0
  120. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/_handlebars.pyi +0 -0
  121. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/abstract.pyi +0 -0
  122. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/composition.pyi +0 -0
  123. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/config.pyi +0 -0
  124. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/local.pyi +0 -0
  125. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/remote.pyi +0 -0
  126. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/template_validation.pyi +0 -0
  127. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/variables/variable.pyi +0 -0
  128. {logfire_api-5.1.1 → logfire_api-5.3.0}/logfire_api/version.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: logfire-api
3
- Version: 5.1.1
3
+ Version: 5.3.0
4
4
  Summary: Shim for the Logfire SDK which does nothing unless Logfire is installed
5
5
  Author-email: Pydantic Team <engineering@pydantic.dev>, Samuel Colvin <samuel@pydantic.dev>, Hasan Ramezani <hasan@pydantic.dev>, Adrian Garcia Badaracco <adrian@pydantic.dev>, David Montague <david@pydantic.dev>, Marcelo Trylesinski <marcelo@pydantic.dev>, David Hewitt <david.hewitt@pydantic.dev>, Alex Hall <alex@pydantic.dev>
6
6
  License-Expression: MIT
@@ -153,6 +153,8 @@ except ImportError:
153
153
 
154
154
  def instrument_pydantic_ai(self, *args, **kwargs) -> None: ...
155
155
 
156
+ def instrument_monty(self, *args, **kwargs) -> None: ...
157
+
156
158
  def instrument_pymongo(self, *args, **kwargs) -> None: ...
157
159
 
158
160
  def instrument_sqlalchemy(self, *args, **kwargs) -> None: ...
@@ -176,6 +178,8 @@ except ImportError:
176
178
 
177
179
  def instrument_surrealdb(self, *args, **kwargs) -> None: ...
178
180
 
181
+ def instrument_snowflake(self, *args, **kwargs) -> None: ...
182
+
179
183
  def instrument_requests(self, *args, **kwargs) -> None: ...
180
184
 
181
185
  def instrument_httpx(self, *args, **kwargs) -> None: ...
@@ -242,6 +246,7 @@ except ImportError:
242
246
  instrument_wsgi = DEFAULT_LOGFIRE_INSTANCE.instrument_wsgi
243
247
  instrument_pydantic = DEFAULT_LOGFIRE_INSTANCE.instrument_pydantic
244
248
  instrument_pydantic_ai = DEFAULT_LOGFIRE_INSTANCE.instrument_pydantic_ai
249
+ instrument_monty = DEFAULT_LOGFIRE_INSTANCE.instrument_monty
245
250
  instrument_fastapi = DEFAULT_LOGFIRE_INSTANCE.instrument_fastapi
246
251
  instrument_openai = DEFAULT_LOGFIRE_INSTANCE.instrument_openai
247
252
  instrument_openai_agents = DEFAULT_LOGFIRE_INSTANCE.instrument_openai_agents
@@ -255,6 +260,7 @@ except ImportError:
255
260
  instrument_httpx = DEFAULT_LOGFIRE_INSTANCE.instrument_httpx
256
261
  instrument_requests = DEFAULT_LOGFIRE_INSTANCE.instrument_requests
257
262
  instrument_surrealdb = DEFAULT_LOGFIRE_INSTANCE.instrument_surrealdb
263
+ instrument_snowflake = DEFAULT_LOGFIRE_INSTANCE.instrument_snowflake
258
264
  instrument_psycopg = DEFAULT_LOGFIRE_INSTANCE.instrument_psycopg
259
265
  instrument_django = DEFAULT_LOGFIRE_INSTANCE.instrument_django
260
266
  instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
@@ -16,7 +16,7 @@ from logfire.propagate import attach_context as attach_context, get_context as g
16
16
  from logfire.sampling import SamplingOptions as SamplingOptions
17
17
  from typing import Any
18
18
 
19
- __all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'AdvancedOptions', 'ConsoleOptions', 'CodeSource', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'warning', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_asgi', 'instrument_wsgi', 'instrument_pydantic', 'instrument_pydantic_ai', 'instrument_fastapi', 'instrument_openai', 'instrument_openai_agents', 'instrument_anthropic', 'instrument_google_genai', 'instrument_litellm', 'instrument_dspy', 'instrument_print', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_litestar', 'instrument_aiohttp_client', 'instrument_aiohttp_server', 'instrument_sqlalchemy', 'instrument_sqlite3', 'instrument_aws_lambda', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_surrealdb', 'instrument_system_metrics', 'instrument_mcp', 'instrument_claude_agent_sdk', 'AutoTraceModule', 'with_tags', 'with_settings', 'suppress_scopes', 'shutdown', 'no_auto_trace', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'add_non_user_code_prefix', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'loguru_handler', 'SamplingOptions', 'MetricsOptions', 'VariablesOptions', 'LocalVariablesOptions', 'variables', 'var', 'template_var', 'variables_get', 'variables_push', 'variables_push_types', 'variables_validate', 'variables_push_config', 'variables_pull_config', 'variables_build_config', 'logfire_info', 'get_baggage', 'set_baggage', 'get_context', 'attach_context', 'url_from_eval', 'forward_export_request', 'forward_export_request_starlette']
19
+ __all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'AdvancedOptions', 'ConsoleOptions', 'CodeSource', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'warning', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_asgi', 'instrument_wsgi', 'instrument_pydantic', 'instrument_pydantic_ai', 'instrument_monty', 'instrument_fastapi', 'instrument_openai', 'instrument_openai_agents', 'instrument_anthropic', 'instrument_google_genai', 'instrument_litellm', 'instrument_dspy', 'instrument_print', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_litestar', 'instrument_aiohttp_client', 'instrument_aiohttp_server', 'instrument_sqlalchemy', 'instrument_sqlite3', 'instrument_aws_lambda', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_surrealdb', 'instrument_snowflake', 'instrument_system_metrics', 'instrument_mcp', 'instrument_claude_agent_sdk', 'AutoTraceModule', 'with_tags', 'with_settings', 'suppress_scopes', 'shutdown', 'no_auto_trace', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'add_non_user_code_prefix', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'loguru_handler', 'SamplingOptions', 'MetricsOptions', 'VariablesOptions', 'LocalVariablesOptions', 'variables', 'var', 'template_var', 'variables_get', 'variables_push', 'variables_push_types', 'variables_validate', 'variables_push_config', 'variables_pull_config', 'variables_build_config', 'logfire_info', 'get_baggage', 'set_baggage', 'get_context', 'attach_context', 'url_from_eval', 'forward_export_request', 'forward_export_request_starlette']
20
20
 
21
21
  DEFAULT_LOGFIRE_INSTANCE = Logfire()
22
22
  span = DEFAULT_LOGFIRE_INSTANCE.span
@@ -26,6 +26,7 @@ log_slow_async_callbacks = DEFAULT_LOGFIRE_INSTANCE.log_slow_async_callbacks
26
26
  install_auto_tracing = DEFAULT_LOGFIRE_INSTANCE.install_auto_tracing
27
27
  instrument_pydantic = DEFAULT_LOGFIRE_INSTANCE.instrument_pydantic
28
28
  instrument_pydantic_ai = DEFAULT_LOGFIRE_INSTANCE.instrument_pydantic_ai
29
+ instrument_monty = DEFAULT_LOGFIRE_INSTANCE.instrument_monty
29
30
  instrument_asgi = DEFAULT_LOGFIRE_INSTANCE.instrument_asgi
30
31
  instrument_wsgi = DEFAULT_LOGFIRE_INSTANCE.instrument_wsgi
31
32
  instrument_fastapi = DEFAULT_LOGFIRE_INSTANCE.instrument_fastapi
@@ -54,6 +55,7 @@ instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
54
55
  instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
55
56
  instrument_mysql = DEFAULT_LOGFIRE_INSTANCE.instrument_mysql
56
57
  instrument_surrealdb = DEFAULT_LOGFIRE_INSTANCE.instrument_surrealdb
58
+ instrument_snowflake = DEFAULT_LOGFIRE_INSTANCE.instrument_snowflake
57
59
  instrument_system_metrics = DEFAULT_LOGFIRE_INSTANCE.instrument_system_metrics
58
60
  instrument_mcp = DEFAULT_LOGFIRE_INSTANCE.instrument_mcp
59
61
  instrument_claude_agent_sdk = DEFAULT_LOGFIRE_INSTANCE.instrument_claude_agent_sdk
@@ -10,4 +10,8 @@ def parse_auth(args: argparse.Namespace) -> None:
10
10
  This will authenticate your machine with Logfire and store the credentials.
11
11
  """
12
12
  def parse_logout(args: argparse.Namespace) -> None:
13
- """Log out from Logfire."""
13
+ """Log out from Logfire.
14
+
15
+ Remove stored user tokens for --region, --base-url, or a non-empty LOGFIRE_BASE_URL.
16
+ With no target configured, remove all stored user tokens.
17
+ """
@@ -1,6 +1,6 @@
1
1
  import argparse
2
2
  from _typeshed import Incomplete
3
- from collections.abc import Collection, Generator, Mapping
3
+ from collections.abc import Callable, Collection, Generator, Mapping
4
4
  from contextlib import contextmanager
5
5
  from dataclasses import dataclass
6
6
  from logfire._internal.utils import get_version as get_version
@@ -34,6 +34,13 @@ class InstrumentationContext:
34
34
  recommendations: set[InstrumentationRecommendation]
35
35
 
36
36
  def parse_run(args: argparse.Namespace) -> None: ...
37
+ def load_console_entry_point(name: str) -> Callable[[], object] | None:
38
+ """Load one installed `console_scripts` entry point before local modules can shadow it."""
39
+ @contextmanager
40
+ def without_working_directory_on_sys_path() -> Generator[None, None, None]:
41
+ """Temporarily give entry-point imports the path behavior of an installed launcher."""
42
+ def run_console_entry_point(entry_point: Callable[[], object], argv: list[str]) -> None:
43
+ """Run a loaded console entry point with the target command's arguments."""
37
44
  @contextmanager
38
45
  def alter_sys_argv(argv: list[str], cmd: str) -> Generator[None, None, None]: ...
39
46
  def is_uv_installed() -> bool:
@@ -4,12 +4,12 @@ import requests
4
4
  from ..propagate import NoExtractTraceContextPropagator as NoExtractTraceContextPropagator, WarnOnExtractTraceContextPropagator as WarnOnExtractTraceContextPropagator
5
5
  from ..types import ExceptionCallback as ExceptionCallback
6
6
  from .client import InvalidProjectName as InvalidProjectName, LogfireClient as LogfireClient, ProjectAlreadyExists as ProjectAlreadyExists
7
- from .config_params import ParamManager as ParamManager, PydanticPluginRecordValues as PydanticPluginRecordValues, normalize_token as normalize_token
7
+ from .config_params import CompressionValues as CompressionValues, ParamManager as ParamManager, PydanticPluginRecordValues as PydanticPluginRecordValues, normalize_token as normalize_token
8
8
  from .constants import ATTRIBUTES_CONFIG as ATTRIBUTES_CONFIG, ATTRIBUTES_PACKAGE_VERSIONS as ATTRIBUTES_PACKAGE_VERSIONS, LEVEL_NUMBERS as LEVEL_NUMBERS, LevelName as LevelName, RESOURCE_ATTRIBUTES_CODE_ROOT_PATH as RESOURCE_ATTRIBUTES_CODE_ROOT_PATH, RESOURCE_ATTRIBUTES_CODE_WORK_DIR as RESOURCE_ATTRIBUTES_CODE_WORK_DIR, RESOURCE_ATTRIBUTES_DEPLOYMENT_ENVIRONMENT_NAME as RESOURCE_ATTRIBUTES_DEPLOYMENT_ENVIRONMENT_NAME, RESOURCE_ATTRIBUTES_VCS_REPOSITORY_REF_REVISION as RESOURCE_ATTRIBUTES_VCS_REPOSITORY_REF_REVISION, RESOURCE_ATTRIBUTES_VCS_REPOSITORY_URL as RESOURCE_ATTRIBUTES_VCS_REPOSITORY_URL, RESOURCE_ATTRIBUTES_VERSION as RESOURCE_ATTRIBUTES_VERSION
9
9
  from .exporters.console import ConsoleColorsValues as ConsoleColorsValues, ConsoleLogExporter as ConsoleLogExporter, IndentedConsoleSpanExporter as IndentedConsoleSpanExporter, ShowParentsConsoleSpanExporter as ShowParentsConsoleSpanExporter, SimpleConsoleSpanExporter as SimpleConsoleSpanExporter
10
10
  from .exporters.dynamic_batch import DynamicBatchSpanProcessor as DynamicBatchSpanProcessor
11
11
  from .exporters.logs import CheckSuppressInstrumentationLogProcessorWrapper as CheckSuppressInstrumentationLogProcessorWrapper, MainLogProcessorWrapper as MainLogProcessorWrapper
12
- from .exporters.otlp import BodySizeCheckingOTLPSpanExporter as BodySizeCheckingOTLPSpanExporter, OTLPExporterHttpSession as OTLPExporterHttpSession, QuietLogExporter as QuietLogExporter, QuietSpanExporter as QuietSpanExporter, RetryFewerSpansSpanExporter as RetryFewerSpansSpanExporter, cleanup_disk_retryers as cleanup_disk_retryers
12
+ from .exporters.otlp import BodySizeCheckingOTLPSpanExporter as BodySizeCheckingOTLPSpanExporter, OTLPExporterHttpSession as OTLPExporterHttpSession, QuietLogExporter as QuietLogExporter, QuietSpanExporter as QuietSpanExporter, RetryFewerSpansSpanExporter as RetryFewerSpansSpanExporter, cleanup_disk_retryers as cleanup_disk_retryers, zstd_compress as zstd_compress
13
13
  from .exporters.processor_wrapper import CheckSuppressInstrumentationProcessorWrapper as CheckSuppressInstrumentationProcessorWrapper, MainSpanProcessorWrapper as MainSpanProcessorWrapper
14
14
  from .exporters.quiet_metrics import QuietMetricExporter as QuietMetricExporter
15
15
  from .exporters.remove_pending import RemovePendingSpansExporter as RemovePendingSpansExporter
@@ -45,6 +45,7 @@ from opentelemetry.sdk.metrics.export import MetricReader as MetricReader
45
45
  from opentelemetry.sdk.metrics.view import View
46
46
  from opentelemetry.sdk.resources import ResourceDetector
47
47
  from opentelemetry.sdk.trace import SpanProcessor
48
+ from opentelemetry.sdk.trace.export import SpanExporter as SpanExporter
48
49
  from opentelemetry.sdk.trace.id_generator import IdGenerator
49
50
  from pathlib import Path
50
51
  from typing import Any, ClassVar, Literal, TextIO
@@ -66,6 +67,7 @@ class ConsoleOptions:
66
67
  min_log_level: LevelName = ...
67
68
  show_project_link: bool = ...
68
69
  output: TextIO | None = ...
70
+ include_attributes: bool | None = ...
69
71
 
70
72
  @dataclass
71
73
  class AdvancedOptions:
@@ -78,6 +80,8 @@ class AdvancedOptions:
78
80
  emit_configuration_span: bool | None = ...
79
81
  server_response_hook: ServerResponseCallback | None = ...
80
82
  resource_detectors: Sequence[ResourceDetector | str] | None = ...
83
+ compression: CompressionValues | None = ...
84
+ pending_spans: bool | None = ...
81
85
  def generate_base_url(self, token: str, warn_unknown_region: bool = True) -> str:
82
86
  """Resolve the base API URL for `token`, honouring an explicitly configured `base_url`.
83
87
 
@@ -12,6 +12,7 @@ from typing import Any, TypeVar
12
12
 
13
13
  T = TypeVar('T')
14
14
  PydanticPluginRecordValues: Incomplete
15
+ CompressionValues: Incomplete
15
16
 
16
17
  @dataclass(slots=True)
17
18
  class ConfigParam:
@@ -45,6 +46,7 @@ CONSOLE_SPAN_STYLE: Incomplete
45
46
  CONSOLE_INCLUDE_TIMESTAMP: Incomplete
46
47
  CONSOLE_INCLUDE_TAGS: Incomplete
47
48
  CONSOLE_VERBOSE: Incomplete
49
+ CONSOLE_INCLUDE_ATTRIBUTES: Incomplete
48
50
  CONSOLE_MIN_LOG_LEVEL: Incomplete
49
51
  CONSOLE_SHOW_PROJECT_LINK: Incomplete
50
52
  PYDANTIC_PLUGIN_RECORD: Incomplete
@@ -56,6 +58,8 @@ IGNORE_NO_CONFIG: Incomplete
56
58
  BASE_URL: Incomplete
57
59
  DISTRIBUTED_TRACING: Incomplete
58
60
  EMIT_CONFIGURATION_SPAN: Incomplete
61
+ PENDING_SPANS: Incomplete
62
+ COMPRESSION: Incomplete
59
63
  HTTPX_CAPTURE_ALL: Incomplete
60
64
  AIOHTTP_CLIENT_CAPTURE_ALL: Incomplete
61
65
  CONFIG_PARAMS: Incomplete
@@ -35,7 +35,7 @@ class SimpleConsoleSpanExporter(SpanExporter):
35
35
  This simple version does not indent spans based on their parent(s), instead spans are printed as a
36
36
  flat list.
37
37
  """
38
- def __init__(self, output: TextIO | None = None, colors: ConsoleColorsValues = 'auto', include_timestamp: bool = True, include_tags: bool = True, verbose: bool = False, min_log_level: LevelName = 'info') -> None: ...
38
+ def __init__(self, output: TextIO | None = None, colors: ConsoleColorsValues = 'auto', include_timestamp: bool = True, include_tags: bool = True, verbose: bool = False, min_log_level: LevelName = 'info', include_attributes: bool | None = None) -> None: ...
39
39
  def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
40
40
  """Export the spans to the console."""
41
41
  def export_record(self, span: Record) -> None:
@@ -52,7 +52,7 @@ class IndentedConsoleSpanExporter(SimpleConsoleSpanExporter):
52
52
  Spans are intended based simply on how many parents they have. This will work well when spans don't overlap,
53
53
  but will be hard to understand when multiple spans are in progress at the same time.
54
54
  """
55
- def __init__(self, output: TextIO | None = None, colors: ConsoleColorsValues = 'auto', include_timestamp: bool = True, include_tags: bool = True, verbose: bool = False, min_log_level: LevelName = 'info') -> None: ...
55
+ def __init__(self, output: TextIO | None = None, colors: ConsoleColorsValues = 'auto', include_timestamp: bool = True, include_tags: bool = True, verbose: bool = False, min_log_level: LevelName = 'info', include_attributes: bool | None = None) -> None: ...
56
56
  def export_record(self, span: Record) -> None:
57
57
  """Get the span indent based on `self._indent_level`, then print the span with that indent."""
58
58
 
@@ -63,7 +63,7 @@ class ShowParentsConsoleSpanExporter(SimpleConsoleSpanExporter):
63
63
  the previously displayed span is not the parent or sibling of a span, parents are printed (with "dim" color)
64
64
  so it\'s easy (or as easy as possible in a terminal) to understand how nested spans are related.
65
65
  '''
66
- def __init__(self, output: TextIO | None = None, colors: ConsoleColorsValues = 'auto', include_timestamp: bool = True, include_tags: bool = True, verbose: bool = False, min_log_level: LevelName = 'info') -> None: ...
66
+ def __init__(self, output: TextIO | None = None, colors: ConsoleColorsValues = 'auto', include_timestamp: bool = True, include_tags: bool = True, verbose: bool = False, min_log_level: LevelName = 'info', include_attributes: bool | None = None) -> None: ...
67
67
  def export_record(self, span: Record) -> None:
68
68
  """Print any parent spans which aren't in the current stack of displayed spans, then print this span."""
69
69
 
@@ -1,4 +1,5 @@
1
1
  import atexit
2
+ import logging
2
3
  import requests
3
4
  from ..constants import ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_SPAN_TYPE_KEY as ATTRIBUTES_SPAN_TYPE_KEY, HTTP_CONNECT_TIMEOUT as HTTP_CONNECT_TIMEOUT, OTLP_MAX_INT_SIZE as OTLP_MAX_INT_SIZE, log_level_attributes as log_level_attributes
4
5
  from ..http_transport import install_connection_policy as install_connection_policy
@@ -17,19 +18,46 @@ from opentelemetry.sdk.trace.export import SpanExportResult
17
18
  from pathlib import Path
18
19
  from requests import Session
19
20
  from threading import Thread
20
- from typing import Any
21
+ from typing import Any, Protocol
22
+ from typing_extensions import Buffer
23
+
24
+ class _OTLPExportResult(Protocol):
25
+ success: bool
26
+ status_code: int | None
27
+ error: Exception | None
28
+
29
+ class _OTLPClient(Protocol):
30
+ def export(self, data: bytes) -> _OTLPExportResult: ...
31
+ def shutdown(self) -> None: ...
32
+
33
+ class _QuietConnectionErrorLogger(logging.LoggerAdapter):
34
+ def error(self, msg: object, *args: Any, **kwargs: Any) -> None: ...
35
+
36
+ class _BodySizeCheckingOTLPClient:
37
+ client: Incomplete
38
+ exporter: Incomplete
39
+ def __init__(self, client: _OTLPClient, exporter: BodySizeCheckingOTLPSpanExporter) -> None: ...
40
+ def export(self, data: bytes) -> _OTLPExportResult: ...
41
+ def shutdown(self) -> None: ...
42
+
43
+ class ZstdCompressFn(Protocol):
44
+ """Signature of `compression.zstd.compress` and `backports.zstd.compress`."""
45
+ def __call__(self, data: Buffer, level: int | None = None, options: Mapping[int, int] | None = None, zstd_dict: Any = None) -> bytes: ...
46
+
47
+ zstd_compress: ZstdCompressFn | None
21
48
 
22
49
  @atexit.register
23
50
  def cleanup_disk_retryers() -> None: ...
24
51
 
25
52
  class BodySizeCheckingOTLPSpanExporter(OTLPSpanExporter):
26
53
  max_body_size: Incomplete
54
+ current_num_spans: int
27
55
  def __init__(self, *args: Any, **kwargs: Any) -> None: ...
28
56
  def export(self, spans: Sequence[ReadableSpan]): ...
29
57
 
30
58
  class OTLPExporterHttpSession(Session):
31
59
  """A requests.Session subclass that defers failed requests to a DiskRetryer."""
32
- def __init__(self) -> None: ...
60
+ def __init__(self, *, _use_zstd: bool = False) -> None: ...
33
61
  def request(self, method: str, url: str, **kwargs: Any): ...
34
62
  def post(self, url: str, data: bytes, **kwargs: Any): ...
35
63
  @cached_property
@@ -2,7 +2,7 @@ from _typeshed import Incomplete
2
2
  from claude_agent_sdk import AssistantMessage
3
3
  from claude_agent_sdk.types import HookContext, SyncHookJSONOutput
4
4
  from contextlib import AbstractContextManager
5
- from logfire._internal.integrations.llm_providers.semconv import CONVERSATION_ID as CONVERSATION_ID, ChatMessage as ChatMessage, ERROR_TYPE as ERROR_TYPE, INPUT_MESSAGES as INPUT_MESSAGES, MessagePart as MessagePart, OPERATION_NAME as OPERATION_NAME, OUTPUT_MESSAGES as OUTPUT_MESSAGES, OutputMessage as OutputMessage, PROVIDER_NAME as PROVIDER_NAME, REQUEST_MODEL as REQUEST_MODEL, RESPONSE_MODEL as RESPONSE_MODEL, ReasoningPart as ReasoningPart, SYSTEM as SYSTEM, SYSTEM_INSTRUCTIONS as SYSTEM_INSTRUCTIONS, TOOL_CALL_ARGUMENTS as TOOL_CALL_ARGUMENTS, TOOL_CALL_ID as TOOL_CALL_ID, TOOL_CALL_RESULT as TOOL_CALL_RESULT, TOOL_NAME as TOOL_NAME, TextPart as TextPart, ToolCallPart as ToolCallPart, ToolCallResponsePart as ToolCallResponsePart
5
+ from logfire._internal.integrations.llm_providers.semconv import CONVERSATION_ID as CONVERSATION_ID, ChatMessage as ChatMessage, ERROR_TYPE as ERROR_TYPE, INPUT_MESSAGES as INPUT_MESSAGES, MessagePart as MessagePart, OPERATION_NAME as OPERATION_NAME, OUTPUT_MESSAGES as OUTPUT_MESSAGES, OutputMessage as OutputMessage, PROVIDER_NAME as PROVIDER_NAME, REQUEST_MODEL as REQUEST_MODEL, RESPONSE_FINISH_REASONS as RESPONSE_FINISH_REASONS, RESPONSE_ID as RESPONSE_ID, RESPONSE_MODEL as RESPONSE_MODEL, ReasoningPart as ReasoningPart, SYSTEM as SYSTEM, SYSTEM_INSTRUCTIONS as SYSTEM_INSTRUCTIONS, TOOL_CALL_ARGUMENTS as TOOL_CALL_ARGUMENTS, TOOL_CALL_ID as TOOL_CALL_ID, TOOL_CALL_RESULT as TOOL_CALL_RESULT, TOOL_NAME as TOOL_NAME, TextPart as TextPart, ToolCallPart as ToolCallPart, ToolCallResponsePart as ToolCallResponsePart
6
6
  from logfire._internal.main import Logfire as Logfire, LogfireSpan as LogfireSpan
7
7
  from logfire._internal.stack_info import get_user_stack_info as get_user_stack_info
8
8
  from logfire._internal.utils import handle_internal_errors as handle_internal_errors
@@ -63,5 +63,11 @@ class _ConversationState:
63
63
  """Handle UserMessage: open a new chat span for the next LLM call."""
64
64
  def handle_assistant_message(self, message: AssistantMessage) -> None:
65
65
  """Handle AssistantMessage: add output and usage to the current chat span."""
66
+ def set_finish_reason(self, stop_reason: str | None) -> None:
67
+ """Record the stop reason on the current chat span.
68
+
69
+ The CLI streams assistant messages with a null `stop_reason`;
70
+ the final one is only reported on the ResultMessage.
71
+ """
66
72
  def close(self) -> None:
67
73
  """Close chat span and end any orphaned tool spans."""
@@ -1,3 +1,4 @@
1
+ import dataclasses
1
2
  from ..constants import ONE_SECOND_IN_NANOSECONDS as ONE_SECOND_IN_NANOSECONDS
2
3
  from ..main import Logfire as Logfire, NoopSpan as NoopSpan, set_user_attributes_on_raw_span as set_user_attributes_on_raw_span
3
4
  from ..stack_info import StackInfo as StackInfo, get_code_object_info as get_code_object_info
@@ -8,21 +9,43 @@ from collections.abc import Awaitable, Callable, Iterable
8
9
  from contextlib import AbstractContextManager, contextmanager
9
10
  from fastapi import FastAPI
10
11
  from functools import lru_cache
12
+ from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
11
13
  from opentelemetry.trace import Span
12
14
  from starlette.requests import Request
15
+ from starlette.types import Receive, Scope, Send
13
16
  from starlette.websockets import WebSocket
14
17
  from typing import Any
18
+ from weakref import WeakKeyDictionary
15
19
 
16
20
  def find_mounted_apps(app: FastAPI) -> list[FastAPI]:
17
21
  """Fetch all sub-apps mounted to a FastAPI app, including nested sub-apps."""
18
- def instrument_fastapi(logfire_instance: Logfire, app: FastAPI, *, capture_headers: bool = False, request_attributes_mapper: Callable[[Request | WebSocket, dict[str, Any]], dict[str, Any] | None] | None = None, excluded_urls: str | Iterable[str] | None = None, record_send_receive: bool = False, extra_spans: bool = False, **opentelemetry_kwargs: Any) -> AbstractContextManager[None]:
22
+ def instrument_fastapi(logfire_instance: Logfire, app: FastAPI | None = None, *, capture_headers: bool = False, request_attributes_mapper: Callable[[Request | WebSocket, dict[str, Any]], dict[str, Any] | None] | None = None, excluded_urls: str | Iterable[str] | None = None, record_send_receive: bool = False, extra_spans: bool = False, **opentelemetry_kwargs: Any) -> AbstractContextManager[None]:
19
23
  """Instrument a FastAPI app so that spans and logs are automatically created for each request.
20
24
 
21
25
  See `Logfire.instrument_fastapi` for more details.
22
26
  """
27
+
28
+ class OncePerRequest:
29
+ """Run only the outermost FastAPI OpenTelemetry middleware for each ASGI request.
30
+
31
+ This way mounted apps don't start duplicate spans for the same request,
32
+ and they don't trace requests that were excluded by their outer app.
33
+ """
34
+ app: Incomplete
35
+ def __init__(self, app: OpenTelemetryMiddleware) -> None: ...
36
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: ...
37
+
38
+ @dataclasses.dataclass
39
+ class _FastAPIRegistry:
40
+ """Track Logfire instrumentation settings for FastAPI apps."""
41
+ global_instrumentation: FastAPIInstrumentation | None = ...
42
+ per_app: WeakKeyDictionary[FastAPI, FastAPIInstrumentation] = dataclasses.field(default_factory=Incomplete)
43
+ def get_instrumentation(self, app: FastAPI) -> FastAPIInstrumentation | None:
44
+ """Get the instrumentation for a specific app, or the global instrumentation if none is set."""
45
+
23
46
  @lru_cache
24
- def patch_fastapi():
25
- """Globally monkeypatch fastapi functions and return a dictionary for recording instrumentation config per app."""
47
+ def patch_fastapi() -> _FastAPIRegistry:
48
+ """Globally monkeypatch fastapi functions and return their instrumentation registry."""
26
49
 
27
50
  class FastAPIInstrumentation:
28
51
  logfire_instance: Incomplete
@@ -1,9 +1,10 @@
1
1
  from flask.app import Flask
2
+ from logfire import Logfire as Logfire
2
3
  from logfire._internal.utils import maybe_capture_server_headers as maybe_capture_server_headers
3
4
  from logfire.integrations.flask import CommenterOptions as CommenterOptions, RequestHook as RequestHook, ResponseHook as ResponseHook
4
5
  from typing import Any
5
6
 
6
- def instrument_flask(app: Flask, *, capture_headers: bool, enable_commenter: bool, commenter_options: CommenterOptions | None, excluded_urls: str | None = None, request_hook: RequestHook | None = None, response_hook: ResponseHook | None = None, **kwargs: Any):
7
+ def instrument_flask(logfire_instance: Logfire, app: Flask | None = None, *, capture_headers: bool = False, enable_commenter: bool = True, commenter_options: CommenterOptions | None = None, excluded_urls: str | None = None, request_hook: RequestHook | None = None, response_hook: ResponseHook | None = None, **kwargs: Any) -> None:
7
8
  """Instrument `app` so that spans are automatically created for each request.
8
9
 
9
10
  See the `Logfire.instrument_flask` method for details.
@@ -1,7 +1,12 @@
1
+ from collections.abc import Awaitable as Awaitable, Callable
1
2
  from logfire import LevelName as LevelName, Logfire as Logfire
2
3
  from logfire._internal.utils import handle_internal_errors as handle_internal_errors
3
4
  from logfire.propagate import attach_context as attach_context, get_context as get_context
4
- from mcp.shared.session import ReceiveRequestT as ReceiveRequestT
5
- from mcp.types import ClientRequest as ClientRequest, ClientResult as ClientResult, ServerRequest as ServerRequest, ServerResult as ServerResult
5
+ from typing import Any, Protocol
6
+
7
+ class _RequestResponder(Protocol):
8
+ """The MCP 1 responder interface used by instrumentation."""
9
+ request: Any
10
+ respond: Callable[..., Awaitable[None]]
6
11
 
7
12
  def instrument_mcp(logfire_instance: Logfire, propagate_otel_context: bool): ...
@@ -0,0 +1,29 @@
1
+ from _typeshed import Incomplete
2
+ from collections.abc import Sequence
3
+ from logfire import Logfire as Logfire
4
+ from logfire._internal.constants import ATTRIBUTES_LOG_LEVEL_NUM_KEY as ATTRIBUTES_LOG_LEVEL_NUM_KEY, ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_MESSAGE_TEMPLATE_KEY as ATTRIBUTES_MESSAGE_TEMPLATE_KEY, ATTRIBUTES_SAMPLE_RATE_KEY as ATTRIBUTES_SAMPLE_RATE_KEY, ATTRIBUTES_TAGS_KEY as ATTRIBUTES_TAGS_KEY, DISABLE_CONSOLE_KEY as DISABLE_CONSOLE_KEY
5
+ from logfire._internal.formatter import logfire_format as logfire_format
6
+ from logfire.version import VERSION as VERSION
7
+ from opentelemetry._logs import LogRecord, Logger, SeverityNumber
8
+ from opentelemetry.context import Context
9
+ from opentelemetry.trace import Link as Link, Span, SpanKind, Tracer
10
+ from opentelemetry.util import types as otel_types
11
+ from typing import Any
12
+
13
+ def instrument_monty(logfire_instance: Logfire) -> None:
14
+ """Install process-wide Monty instrumentation using Logfire's OpenTelemetry components."""
15
+
16
+ class LogfireMontyTracer(Tracer):
17
+ """Standard OTel tracer adding settings from a specific Logfire instance."""
18
+ logfire: Incomplete
19
+ def __init__(self, logfire_instance: Logfire) -> None: ...
20
+ def start_span(self, name: str, context: Context | None = None, kind: SpanKind = ..., attributes: otel_types.Attributes = None, links: Sequence[Link] | None = None, start_time: int | None = None, record_exception: bool = True, set_status_on_exception: bool = True) -> Span: ...
21
+ start_as_current_span: Incomplete
22
+
23
+ class LogfireMontyLogger(Logger):
24
+ """Standard OTel logger adding settings from a specific Logfire instance."""
25
+ logger: Incomplete
26
+ logfire: Incomplete
27
+ def __init__(self, logger: Logger, logfire_instance: Logfire) -> None: ...
28
+ def enabled(self, *, context: Context | None = None, severity_number: SeverityNumber | None = None, event_name: str | None = None) -> bool: ...
29
+ def emit(self, record: LogRecord | None = None, **kwargs: Any) -> None: ...
@@ -7,7 +7,8 @@ from agents.tracing.spans import SpanError, TSpanData
7
7
  from dataclasses import dataclass
8
8
  from logfire import Logfire as Logfire, LogfireSpan as LogfireSpan
9
9
  from logfire._internal.formatter import logfire_format as logfire_format
10
- from logfire._internal.integrations.llm_providers.openai import get_openai_usage_attributes as get_openai_usage_attributes, inputs_to_events as inputs_to_events, responses_output_events as responses_output_events
10
+ from logfire._internal.integrations.llm_providers.openai import get_openai_usage_attributes as get_openai_usage_attributes, inputs_to_events as inputs_to_events, responses_finish_reasons as responses_finish_reasons, responses_output_events as responses_output_events
11
+ from logfire._internal.integrations.llm_providers.semconv import RESPONSE_FINISH_REASONS as RESPONSE_FINISH_REASONS, RESPONSE_ID as RESPONSE_ID
11
12
  from logfire._internal.scrubbing import NOOP_SCRUBBER as NOOP_SCRUBBER
12
13
  from logfire._internal.utils import handle_internal_errors as handle_internal_errors, log_internal_error as log_internal_error, truncate_string as truncate_string
13
14
  from openai.types.responses import Response
@@ -0,0 +1,7 @@
1
+ from logfire import Logfire as Logfire
2
+ from logfire._internal.stack_info import warn_at_user_stacklevel as warn_at_user_stacklevel
3
+ from logfire._internal.utils import handle_internal_errors as handle_internal_errors
4
+ from snowflake.connector.connection import SnowflakeConnection
5
+ from types import ModuleType
6
+
7
+ def instrument_snowflake(logfire_instance: Logfire, conn_or_module: ModuleType | SnowflakeConnection | None, capture_parameters: bool) -> None: ...
@@ -5,7 +5,7 @@ from opentelemetry.instrumentation.asgi.types import ClientRequestHook, ClientRe
5
5
  from starlette.applications import Starlette
6
6
  from typing import Any
7
7
 
8
- def instrument_starlette(logfire_instance: Logfire, app: Starlette, *, record_send_receive: bool = False, capture_headers: bool = False, server_request_hook: ServerRequestHook | None = None, client_request_hook: ClientRequestHook | None = None, client_response_hook: ClientResponseHook | None = None, **kwargs: Any):
8
+ def instrument_starlette(logfire_instance: Logfire, app: Starlette | None = None, *, record_send_receive: bool = False, capture_headers: bool = False, server_request_hook: ServerRequestHook | None = None, client_request_hook: ClientRequestHook | None = None, client_response_hook: ClientResponseHook | None = None, **kwargs: Any) -> None:
9
9
  """Instrument `app` so that spans are automatically created for each request.
10
10
 
11
11
  See the `Logfire.instrument_starlette` method for details.
@@ -4,6 +4,10 @@ from functools import cache, lru_cache
4
4
  from typing import Any
5
5
 
6
6
  NUMPY_DIMENSION_MAX_SIZE: int
7
+
8
+ def pandas_display_slices(count: int, limit: int | None) -> tuple[slice, ...]:
9
+ """Return the first and last positions selected by a pandas display limit."""
10
+
7
11
  EncoderFunction: Incomplete
8
12
 
9
13
  @cache
@@ -1,8 +1,9 @@
1
1
  import dataclasses
2
2
  from dataclasses import dataclass
3
3
  from logfire._internal.constants import LEVEL_NUMBERS as LEVEL_NUMBERS
4
- from opentelemetry._logs import LogRecord, Logger, LoggerProvider
5
- from opentelemetry.util.types import _ExtendedAttributes
4
+ from opentelemetry._logs import LogRecord, Logger, LoggerProvider, SeverityNumber
5
+ from opentelemetry.context import Context
6
+ from opentelemetry.util.types import Attributes
6
7
  from threading import RLock
7
8
  from typing import Any, overload
8
9
  from weakref import WeakSet
@@ -15,7 +16,7 @@ class ProxyLoggerProvider(LoggerProvider):
15
16
  lock: RLock = dataclasses.field(default_factory=RLock)
16
17
  suppressed_scopes: set[str] = dataclasses.field(default_factory=set[str])
17
18
  min_level: int = ...
18
- def get_logger(self, name: str, version: str | None = None, schema_url: str | None = None, attributes: _ExtendedAttributes | None = None) -> Logger: ...
19
+ def get_logger(self, name: str, version: str | None = None, schema_url: str | None = None, attributes: Attributes | None = None) -> Logger: ...
19
20
  def set_min_level(self, min_level: int) -> None: ...
20
21
  def suppress_scopes(self, *scopes: str) -> None: ...
21
22
  def set_provider(self, logger_provider: LoggerProvider) -> None: ...
@@ -28,10 +29,11 @@ class ProxyLogger(Logger):
28
29
  name: str
29
30
  version: str | None = ...
30
31
  schema_url: str | None = ...
31
- attributes: _ExtendedAttributes | None = ...
32
+ attributes: Attributes | None = ...
32
33
  @overload
33
34
  def emit(self, record: LogRecord) -> None: ...
34
35
  @overload
35
36
  def emit(self, **kwargs: Any) -> None: ...
36
37
  def set_logger(self, provider: LoggerProvider) -> None: ...
38
+ def enabled(self, *, context: Context | None = None, severity_number: SeverityNumber | None = None, event_name: str | None = None) -> bool: ...
37
39
  def __getattr__(self, item: str): ...
@@ -51,6 +51,7 @@ from opentelemetry.trace import SpanContext, SpanKind
51
51
  from opentelemetry.util import types as otel_types
52
52
  from pydantic_evals.reporting import EvaluationReport
53
53
  from pymongo.monitoring import CommandFailedEvent as CommandFailedEvent, CommandStartedEvent as CommandStartedEvent, CommandSucceededEvent as CommandSucceededEvent
54
+ from snowflake.connector.connection import SnowflakeConnection
54
55
  from sqlalchemy import Engine
55
56
  from sqlalchemy.ext.asyncio import AsyncEngine
56
57
  from starlette.applications import Starlette
@@ -440,16 +441,37 @@ class Logfire:
440
441
  Pass a connection class to instrument all instances of that class.
441
442
  By default, all connection classes are instrumented.
442
443
  """
444
+ def instrument_snowflake(self, conn_or_module: ModuleType | SnowflakeConnection | None = None, *, capture_parameters: bool = False) -> None:
445
+ """Instrument the [Snowflake Connector for Python](https://docs.snowflake.com/en/developer-guide/python-connector/python-connector) so that a span is created for each query.
446
+
447
+ Calls to `execute_async()` create a `snowflake execute async` span that measures query submission,
448
+ not server-side execution.
449
+
450
+ Args:
451
+ conn_or_module: Pass a single connection instance to instrument only that connection.
452
+ By default (`None`), all connections are instrumented, including ones created later.
453
+ capture_parameters: Set to `True` to capture query parameters as span attributes.
454
+ Be cautious when enabling this, as it may lead to sensitive data being captured in traces.
455
+ Instrumenting the same target again has no effect; the first call determines this setting,
456
+ and a later call with a different value emits a warning.
457
+ A connection keeps the setting it was instrumented with, even if the module is instrumented later.
458
+ """
443
459
  def instrument_mcp(self, *, propagate_otel_context: bool = True) -> None:
444
460
  """Instrument the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).
445
461
 
446
462
  Instruments both the client and server side. If possible, calling this in both the client and server
447
463
  processes is recommended for nice distributed traces.
448
464
 
465
+ This is only needed with mcp 1.x. Version 2 of the SDK (which fastmcp 4 depends on) emits
466
+ OpenTelemetry spans and propagates the trace context via `_meta` by itself, so with it
467
+ `logfire.configure()` is all that's needed. Calling this method there does nothing
468
+ except emit a `UserWarning` saying so.
469
+
449
470
  Args:
450
471
  propagate_otel_context: Whether to enable propagation of the OpenTelemetry context
451
472
  for distributed tracing.
452
473
  Set to False to prevent setting extra fields like `traceparent` on the metadata of requests.
474
+ Ignored with mcp 2, which always propagates the context.
453
475
  """
454
476
  def instrument_claude_agent_sdk(self) -> AbstractContextManager[None]:
455
477
  """Instrument the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview).
@@ -488,6 +510,16 @@ class Logfire:
488
510
  def instrument_pydantic_ai(self, obj: pydantic_ai.Agent | None = None, /, *, include_binary_content: bool | None = None, include_content: bool | None = None, version: Literal[1, 2, 3, 4, 5] | None = None, event_mode: Literal['attributes', 'logs'] | None = None, **kwargs: Any) -> None: ...
489
511
  @overload
490
512
  def instrument_pydantic_ai(self, obj: pydantic_ai.models.Model, /, *, include_binary_content: bool | None = None, include_content: bool | None = None, version: Literal[1, 2, 3, 4, 5] | None = None, event_mode: Literal['attributes', 'logs'] | None = None, **kwargs: Any) -> pydantic_ai.models.Model: ...
513
+ def instrument_monty(self) -> None:
514
+ """Instrument Pydantic Monty.
515
+
516
+ Call this once after [`configure()`][logfire.configure] and before creating a Monty pool.
517
+ The first call selects the Logfire instance and its settings for the whole process;
518
+ subsequent calls do not replace them.
519
+
520
+ It records Monty sessions, executed code, inputs, outputs, external calls,
521
+ exceptions, printed text, and pool metrics. Recorded values are subject to Logfire's configured scrubbing.
522
+ """
491
523
  def instrument_fastapi(self, app: FastAPI, *, capture_headers: bool = False, request_attributes_mapper: Callable[[Request | WebSocket, dict[str, Any]], dict[str, Any] | None] | None = None, excluded_urls: str | Iterable[str] | None = None, record_send_receive: bool = False, extra_spans: bool = False, **opentelemetry_kwargs: Any) -> AbstractContextManager[None]:
492
524
  """Instrument a FastAPI app so that spans and logs are automatically created for each request.
493
525
 
@@ -906,6 +938,10 @@ class Logfire:
906
938
  [OpenTelemetry SQLAlchemy Instrumentation](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/sqlalchemy/sqlalchemy.html)
907
939
  library, specifically `SQLAlchemyInstrumentor().instrument()`, to which it passes `**kwargs`.
908
940
 
941
+ If the installed SQLAlchemy version is outside the range that instrumentation supports, this raises
942
+ `RuntimeError` instead of returning without recording queries.
943
+ Pass `skip_dep_check=True` to bypass this check. That may produce no spans or errors if the version really is incompatible.
944
+
909
945
  Args:
910
946
  engine: The `sqlalchemy` engine to instrument.
911
947
  engines: An iterable of `sqlalchemy` engines to instrument.
@@ -1517,7 +1553,6 @@ class FastLogfireSpan:
1517
1553
 
1518
1554
  class LogfireSpan(ReadableSpan):
1519
1555
  def __init__(self, span_name: str, otlp_attributes: dict[str, otel_types.AttributeValue], tracer: _ProxyTracer, json_schema_properties: JsonSchemaProperties, links: Sequence[tuple[SpanContext, otel_types.Attributes]], span_kind: SpanKind = ...) -> None: ...
1520
- def __getattr__(self, name: str) -> Any: ...
1521
1556
  def __enter__(self) -> LogfireSpan: ...
1522
1557
  @handle_internal_errors
1523
1558
  def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: Any) -> None: ...
@@ -1568,7 +1603,7 @@ class NoopSpan:
1568
1603
 
1569
1604
  TODO this should also be used when tracing is disabled, e.g. before `logfire.configure()` has been called.
1570
1605
  """
1571
- def __init__(self, /, *_args: Any, **__kwargs: Any) -> None: ...
1606
+ def __init__(self, *_args: Any, **__kwargs: Any) -> None: ...
1572
1607
  def __getattr__(self, _name: str) -> Any: ...
1573
1608
  def __enter__(self) -> NoopSpan: ...
1574
1609
  def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: Any) -> None: ...
@@ -2,6 +2,7 @@ import dataclasses
2
2
  from .utils import handle_internal_errors as handle_internal_errors
3
3
  from abc import ABC
4
4
  from collections.abc import Sequence
5
+ from opentelemetry.context import Context
5
6
  from opentelemetry.metrics import CallbackT as CallbackT, Counter, Histogram, Instrument, Meter, MeterProvider, ObservableCounter, ObservableGauge, ObservableUpDownCounter, UpDownCounter, _Gauge as Gauge
6
7
  from opentelemetry.util.types import Attributes
7
8
  from threading import Lock
@@ -43,10 +44,10 @@ class _ProxyInstrument(ABC, Generic[InstrumentT]):
43
44
  """Called when a real meter is set on the creating _ProxyMeter."""
44
45
 
45
46
  class _ProxyCounter(_ProxyInstrument[Counter], Counter):
46
- def add(self, amount: int | float, attributes: Attributes | None = None, *args: Any, **kwargs: Any) -> None: ...
47
+ def add(self, amount: int | float, attributes: Attributes | None = None, context: Context | None = None, *args: Any, **kwargs: Any) -> None: ...
47
48
 
48
49
  class _ProxyHistogram(_ProxyInstrument[Histogram], Histogram):
49
- def record(self, amount: int | float, attributes: Attributes | None = None, *args: Any, **kwargs: Any) -> None: ...
50
+ def record(self, amount: int | float, attributes: Attributes | None = None, context: Context | None = None, *args: Any, **kwargs: Any) -> None: ...
50
51
 
51
52
  class _ProxyObservableCounter(_ProxyInstrument[ObservableCounter], ObservableCounter): ...
52
53
  class _ProxyObservableGauge(_ProxyInstrument[ObservableGauge], ObservableGauge): ...
@@ -1,8 +1,8 @@
1
1
  import opentelemetry.trace as trace_api
2
2
  from ..types import ExceptionCallback as ExceptionCallback
3
3
  from .config import LogfireConfig as LogfireConfig
4
- from .constants import ATTRIBUTES_EXCEPTION_FINGERPRINT_KEY as ATTRIBUTES_EXCEPTION_FINGERPRINT_KEY, ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEY as ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEY, ATTRIBUTES_SAMPLE_RATE_KEY as ATTRIBUTES_SAMPLE_RATE_KEY, ATTRIBUTES_SPAN_TYPE_KEY as ATTRIBUTES_SPAN_TYPE_KEY, ATTRIBUTES_VALIDATION_ERROR_KEY as ATTRIBUTES_VALIDATION_ERROR_KEY, log_level_attributes as log_level_attributes
5
- from .utils import handle_internal_errors as handle_internal_errors, sha256_string as sha256_string
4
+ from .constants import ATTRIBUTES_EXCEPTION_FINGERPRINT_KEY as ATTRIBUTES_EXCEPTION_FINGERPRINT_KEY, ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_MESSAGE_TEMPLATE_KEY as ATTRIBUTES_MESSAGE_TEMPLATE_KEY, ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEY as ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEY, ATTRIBUTES_SAMPLE_RATE_KEY as ATTRIBUTES_SAMPLE_RATE_KEY, ATTRIBUTES_SPAN_TYPE_KEY as ATTRIBUTES_SPAN_TYPE_KEY, ATTRIBUTES_VALIDATION_ERROR_KEY as ATTRIBUTES_VALIDATION_ERROR_KEY, log_level_attributes as log_level_attributes
5
+ from .utils import handle_internal_errors as handle_internal_errors, is_instrumentation_suppressed as is_instrumentation_suppressed, sha256_string as sha256_string
6
6
  from _typeshed import Incomplete
7
7
  from collections.abc import Callable, Mapping, Sequence
8
8
  from dataclasses import dataclass, field
@@ -70,7 +70,6 @@ class _LogfireWrappedSpan(trace_api.Span, ReadableSpan):
70
70
  def record_exception(self, exception: BaseException, attributes: otel_types.Attributes = None, timestamp: int | None = None, escaped: bool = False) -> None: ...
71
71
  def increment_metric(self, name: str, attributes: Mapping[str, otel_types.AttributeValue], value: float) -> None: ...
72
72
  def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: Any) -> None: ...
73
- def __getattr__(self, name: str) -> Any: ...
74
73
 
75
74
  def get_parent_span(span: ReadableSpan) -> _LogfireWrappedSpan | None: ...
76
75
 
@@ -18,9 +18,6 @@ from types import TracebackType
18
18
  from typing import Any, ParamSpec, TypeVar, TypedDict
19
19
 
20
20
  _ = BaseExceptionGroup
21
-
22
- class BaseExceptionGroup(BaseException):
23
- """Stub for BaseExceptionGroup for Python < 3.11."""
24
21
  SysExcInfo = tuple[type[BaseException], BaseException, TracebackType | None] | tuple[None, None, None]
25
22
  P = ParamSpec('P')
26
23
  T = TypeVar('T')
@@ -6,16 +6,12 @@ from httpx._client import BaseClient
6
6
  from logfire._internal.config import get_base_url_from_token as get_base_url_from_token
7
7
  from logfire._internal.stack_info import warn_at_user_stacklevel as warn_at_user_stacklevel
8
8
  from pydantic_evals import Case, Dataset
9
- from pydantic_evals.evaluators import Evaluator, ReportEvaluator
9
+ from pydantic_evals.evaluators import Evaluator as Evaluator, ReportEvaluator as ReportEvaluator
10
10
  from types import TracebackType
11
11
  from typing import Any, Generic, Literal, overload
12
12
  from typing_extensions import NotRequired, Self, TypeForm, TypeVar, TypedDict
13
13
  from uuid import UUID
14
14
 
15
- Case = Any
16
- Dataset = Any
17
- Evaluator = Any
18
- ReportEvaluator = Any
19
15
  DEFAULT_TIMEOUT: Incomplete
20
16
  T = TypeVar('T', bound=BaseClient)
21
17
  InputsT = TypeVar('InputsT')
@@ -1,5 +1,5 @@
1
1
  from .. import Logfire as Logfire
2
- from .._internal.constants import ATTRIBUTES_LOGGING_ARGS_KEY as ATTRIBUTES_LOGGING_ARGS_KEY, ATTRIBUTES_LOGGING_NAME as ATTRIBUTES_LOGGING_NAME, ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_MESSAGE_TEMPLATE_KEY as ATTRIBUTES_MESSAGE_TEMPLATE_KEY, LOGGING_TO_OTEL_LEVEL_NUMBERS as LOGGING_TO_OTEL_LEVEL_NUMBERS
2
+ from .._internal.constants import ATTRIBUTES_LOGGING_ARGS_KEY as ATTRIBUTES_LOGGING_ARGS_KEY, ATTRIBUTES_LOGGING_NAME as ATTRIBUTES_LOGGING_NAME, ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_MESSAGE_TEMPLATE_KEY as ATTRIBUTES_MESSAGE_TEMPLATE_KEY, ATTRIBUTES_TAGS_KEY as ATTRIBUTES_TAGS_KEY, LOGGING_TO_OTEL_LEVEL_NUMBERS as LOGGING_TO_OTEL_LEVEL_NUMBERS
3
3
  from .._internal.utils import is_instrumentation_suppressed as is_instrumentation_suppressed
4
4
  from _typeshed import Incomplete
5
5
  from collections.abc import Mapping as Mapping
@@ -1,5 +1,5 @@
1
1
  from .. import Logfire as Logfire
2
- from .._internal.constants import ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY
2
+ from .._internal.constants import ATTRIBUTES_MESSAGE_KEY as ATTRIBUTES_MESSAGE_KEY, ATTRIBUTES_TAGS_KEY as ATTRIBUTES_TAGS_KEY
3
3
  from _typeshed import Incomplete
4
4
  from structlog.types import EventDict, WrappedLogger
5
5
 
@@ -7,16 +7,33 @@ from types import TracebackType
7
7
  from typing import Any, Generic, TypeVar, TypedDict
8
8
  from typing_extensions import Self
9
9
 
10
- __all__ = ['QueryExecutionError', 'QueryRequestError', 'InfoRequestError', 'UnexpectedResponseError', 'ReadTokenInfo', 'ColumnDetails', 'RowQueryResults', 'LogfireQueryClient', 'AsyncLogfireQueryClient']
10
+ __all__ = ['QueryExecutionError', 'QueryRequestError', 'InfoRequestError', 'UnexpectedResponseError', 'QueryRateLimitedError', 'ReadTokenInfo', 'ColumnDetails', 'RowQueryResults', 'LogfireQueryClient', 'AsyncLogfireQueryClient']
11
11
 
12
- class QueryExecutionError(RuntimeError):
12
+ class _ProblemDetailsMixin:
13
+ """Additional details about an error response.
14
+
15
+ The server sends an [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem detail body when the client
16
+ asks for one. When the server sends a different body, `problem` is `None`, and the other attributes are
17
+ `None` unless the response has a `Retry-After` header.
18
+ """
19
+ problem: dict[str, Any] | None
20
+ problem_type: str | None
21
+ retryable: bool | None
22
+ retry_after: float | None
23
+
24
+ class QueryExecutionError(_ProblemDetailsMixin, RuntimeError):
13
25
  """Raised when the query execution fails on the server."""
14
- class QueryRequestError(RuntimeError):
26
+ class QueryRequestError(_ProblemDetailsMixin, RuntimeError):
15
27
  """Raised when the query request is invalid."""
16
28
  class InfoRequestError(RuntimeError):
17
29
  """Raised when the request for read token info fails because of unavailable information."""
18
- class UnexpectedResponseError(RuntimeError):
30
+ class UnexpectedResponseError(_ProblemDetailsMixin, RuntimeError):
19
31
  """Raised when the API responds with an unexpected status code, such as a `5xx` server error."""
32
+ class QueryRateLimitedError(UnexpectedResponseError):
33
+ """Raised when the API responds with status code `429` because the request was rate limited.
34
+
35
+ Use `retry_after` to find how long to wait before the next request.
36
+ """
20
37
 
21
38
  class ReadTokenInfo(TypedDict, total=False):
22
39
  """Information about the read token."""
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "logfire-api"
7
- version = "5.1.1"
7
+ version = "5.3.0"
8
8
  description = "Shim for the Logfire SDK which does nothing unless Logfire is installed"
9
9
  authors = [
10
10
  { name = "Pydantic Team", email = "engineering@pydantic.dev" },
File without changes
File without changes