logfire-api 0.46.1__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 (65) hide show
  1. logfire_api-0.46.1/.gitignore +10 -0
  2. logfire_api-0.46.1/PKG-INFO +15 -0
  3. logfire_api-0.46.1/README.md +7 -0
  4. logfire_api-0.46.1/logfire_api/__init__.py +190 -0
  5. logfire_api-0.46.1/logfire_api/__init__.pyi +47 -0
  6. logfire_api-0.46.1/logfire_api/_internal/__init__.pyi +0 -0
  7. logfire_api-0.46.1/logfire_api/_internal/ast_utils.pyi +34 -0
  8. logfire_api-0.46.1/logfire_api/_internal/async_.pyi +22 -0
  9. logfire_api-0.46.1/logfire_api/_internal/auth.pyi +55 -0
  10. logfire_api-0.46.1/logfire_api/_internal/auto_trace/__init__.pyi +15 -0
  11. logfire_api-0.46.1/logfire_api/_internal/auto_trace/import_hook.pyi +38 -0
  12. logfire_api-0.46.1/logfire_api/_internal/auto_trace/rewrite_ast.pyi +51 -0
  13. logfire_api-0.46.1/logfire_api/_internal/auto_trace/types.pyi +24 -0
  14. logfire_api-0.46.1/logfire_api/_internal/backfill.pyi +72 -0
  15. logfire_api-0.46.1/logfire_api/_internal/cli.pyi +48 -0
  16. logfire_api-0.46.1/logfire_api/_internal/collect_system_info.pyi +6 -0
  17. logfire_api-0.46.1/logfire_api/_internal/config.pyi +307 -0
  18. logfire_api-0.46.1/logfire_api/_internal/config_params.pyi +82 -0
  19. logfire_api-0.46.1/logfire_api/_internal/constants.pyi +38 -0
  20. logfire_api-0.46.1/logfire_api/_internal/exporters/__init__.pyi +0 -0
  21. logfire_api-0.46.1/logfire_api/_internal/exporters/console.pyi +39 -0
  22. logfire_api-0.46.1/logfire_api/_internal/exporters/fallback.pyi +12 -0
  23. logfire_api-0.46.1/logfire_api/_internal/exporters/file.pyi +64 -0
  24. logfire_api-0.46.1/logfire_api/_internal/exporters/otlp.pyi +49 -0
  25. logfire_api-0.46.1/logfire_api/_internal/exporters/processor_wrapper.pyi +18 -0
  26. logfire_api-0.46.1/logfire_api/_internal/exporters/quiet_metrics.pyi +8 -0
  27. logfire_api-0.46.1/logfire_api/_internal/exporters/remove_pending.pyi +9 -0
  28. logfire_api-0.46.1/logfire_api/_internal/exporters/tail_sampling.pyi +35 -0
  29. logfire_api-0.46.1/logfire_api/_internal/exporters/wrapper.pyi +32 -0
  30. logfire_api-0.46.1/logfire_api/_internal/formatter.pyi +50 -0
  31. logfire_api-0.46.1/logfire_api/_internal/instrument.pyi +17 -0
  32. logfire_api-0.46.1/logfire_api/_internal/integrations/__init__.pyi +0 -0
  33. logfire_api-0.46.1/logfire_api/_internal/integrations/aiohttp_client.pyi +7 -0
  34. logfire_api-0.46.1/logfire_api/_internal/integrations/asyncpg.pyi +5 -0
  35. logfire_api-0.46.1/logfire_api/_internal/integrations/django.pyi +7 -0
  36. logfire_api-0.46.1/logfire_api/_internal/integrations/executors.pyi +18 -0
  37. logfire_api-0.46.1/logfire_api/_internal/integrations/fastapi.pyi +28 -0
  38. logfire_api-0.46.1/logfire_api/_internal/integrations/flask.pyi +8 -0
  39. logfire_api-0.46.1/logfire_api/_internal/integrations/httpx.pyi +7 -0
  40. logfire_api-0.46.1/logfire_api/_internal/integrations/psycopg.pyi +12 -0
  41. logfire_api-0.46.1/logfire_api/_internal/integrations/pymongo.pyi +7 -0
  42. logfire_api-0.46.1/logfire_api/_internal/integrations/redis.pyi +7 -0
  43. logfire_api-0.46.1/logfire_api/_internal/integrations/requests.pyi +7 -0
  44. logfire_api-0.46.1/logfire_api/_internal/integrations/sqlalchemy.pyi +7 -0
  45. logfire_api-0.46.1/logfire_api/_internal/integrations/starlette.pyi +8 -0
  46. logfire_api-0.46.1/logfire_api/_internal/json_encoder.pyi +12 -0
  47. logfire_api-0.46.1/logfire_api/_internal/json_formatter.pyi +15 -0
  48. logfire_api-0.46.1/logfire_api/_internal/json_schema.pyi +21 -0
  49. logfire_api-0.46.1/logfire_api/_internal/json_types.pyi +55 -0
  50. logfire_api-0.46.1/logfire_api/_internal/main.pyi +927 -0
  51. logfire_api-0.46.1/logfire_api/_internal/metrics.pyi +67 -0
  52. logfire_api-0.46.1/logfire_api/_internal/scrubbing.pyi +93 -0
  53. logfire_api-0.46.1/logfire_api/_internal/stack_info.pyi +39 -0
  54. logfire_api-0.46.1/logfire_api/_internal/tracer.pyi +75 -0
  55. logfire_api-0.46.1/logfire_api/_internal/utils.pyi +85 -0
  56. logfire_api-0.46.1/logfire_api/cli.pyi +3 -0
  57. logfire_api-0.46.1/logfire_api/exceptions.pyi +2 -0
  58. logfire_api-0.46.1/logfire_api/integrations/__init__.pyi +0 -0
  59. logfire_api-0.46.1/logfire_api/integrations/logging.pyi +30 -0
  60. logfire_api-0.46.1/logfire_api/integrations/loguru.pyi +19 -0
  61. logfire_api-0.46.1/logfire_api/integrations/pydantic.pyi +96 -0
  62. logfire_api-0.46.1/logfire_api/integrations/structlog.pyi +12 -0
  63. logfire_api-0.46.1/logfire_api/propagate.pyi +41 -0
  64. logfire_api-0.46.1/logfire_api/version.pyi +3 -0
  65. logfire_api-0.46.1/pyproject.toml +31 -0
@@ -0,0 +1,10 @@
1
+ # python generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # venv
10
+ .venv
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.3
2
+ Name: logfire-api
3
+ Version: 0.46.1
4
+ Summary: Shim for the Logfire SDK which does nothing unless Logfire is installed
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
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+
9
+ # logfire-api
10
+
11
+ Shim for the logfire SDK Python API which does nothing unless logfire is installed.
12
+
13
+ This package is designed to be used by packages that want to provide opt-in integration with [Logfire](https://github.com/pydantic/logfire).
14
+
15
+ The package provides a clone of the Python API exposed by the `logfire` package which does nothing if the `logfire` package is not installed, but makes real calls when it is.
@@ -0,0 +1,7 @@
1
+ # logfire-api
2
+
3
+ Shim for the logfire SDK Python API which does nothing unless logfire is installed.
4
+
5
+ This package is designed to be used by packages that want to provide opt-in integration with [Logfire](https://github.com/pydantic/logfire).
6
+
7
+ The package provides a clone of the Python API exposed by the `logfire` package which does nothing if the `logfire` package is not installed, but makes real calls when it is.
@@ -0,0 +1,190 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import contextmanager
4
+ import importlib
5
+ import sys
6
+ from typing import TYPE_CHECKING, ContextManager, Literal
7
+ from contextlib import nullcontext
8
+ from unittest.mock import MagicMock
9
+
10
+ try:
11
+ logfire_module = importlib.import_module('logfire')
12
+ sys.modules[__name__] = logfire_module
13
+
14
+ except ImportError:
15
+ if not TYPE_CHECKING: # pragma: no branch
16
+ LevelName = Literal['trace', 'debug', 'info', 'notice', 'warn', 'warning', 'error', 'fatal']
17
+ VERSION = '0.0.0'
18
+ METRICS_PREFERRED_TEMPORALITY = {}
19
+
20
+ def configure(*args, **kwargs): ...
21
+
22
+ class LogfireSpan:
23
+ def __getattr__(self, attr):
24
+ return MagicMock() # pragma: no cover
25
+
26
+ def __enter__(self):
27
+ return self
28
+
29
+ def __exit__(self, *args, **kwargs) -> None: ...
30
+
31
+ @property
32
+ def message_template(self) -> str: # pragma: no cover
33
+ return ''
34
+
35
+ @property
36
+ def tags(self) -> Sequence[str]: # pragma: no cover
37
+ return []
38
+
39
+ @property
40
+ def message(self) -> str: # pragma: no cover
41
+ return ''
42
+
43
+ @message.setter
44
+ def message(self, message: str): ... # pragma: no cover
45
+
46
+ def is_recording(self) -> bool: # pragma: no cover
47
+ return False
48
+
49
+ class Logfire:
50
+ def __getattr__(self, attr):
51
+ return MagicMock() # pragma: no cover
52
+
53
+ def __init__(self, *args, **kwargs) -> None: ...
54
+
55
+ def span(self, *args, **kwargs) -> LogfireSpan:
56
+ return LogfireSpan()
57
+
58
+ def log(self, *args, **kwargs) -> None: ...
59
+
60
+ def trace(self, *args, **kwargs) -> None: ...
61
+
62
+ def debug(self, *args, **kwargs) -> None: ...
63
+
64
+ def notice(self, *args, **kwargs) -> None: ...
65
+
66
+ def info(self, *args, **kwargs) -> None: ...
67
+
68
+ def warn(self, *args, **kwargs) -> None: ...
69
+
70
+ def error(self, *args, **kwargs) -> None: ...
71
+
72
+ def fatal(self, *args, **kwargs) -> None: ...
73
+
74
+ def with_tags(self, *args, **kwargs) -> Logfire:
75
+ return self
76
+
77
+ def with_settings(self, *args, **kwargs) -> Logfire:
78
+ return self
79
+
80
+ def force_flush(self, *args, **kwargs) -> None: ...
81
+
82
+ def log_slow_async_callbacks(self, *args, **kwargs) -> None: # pragma: no branch
83
+ return nullcontext()
84
+
85
+ def install_auto_tracing(self, *args, **kwargs) -> None: ...
86
+
87
+ def instrument(self, *args, **kwargs):
88
+ def decorator(func):
89
+ return func
90
+
91
+ return decorator
92
+
93
+ def instrument_fastapi(self, *args, **kwargs) -> ContextManager[None]:
94
+ return nullcontext()
95
+
96
+ def instrument_pymongo(self, *args, **kwargs) -> None: ...
97
+
98
+ def instrument_sqlalchemy(self, *args, **kwargs) -> None: ...
99
+
100
+ def instrument_redis(self, *args, **kwargs) -> None: ...
101
+
102
+ def instrument_flask(self, *args, **kwargs) -> None: ...
103
+
104
+ def instrument_starlette(self, *args, **kwargs) -> None: ...
105
+
106
+ def instrument_django(self, *args, **kwargs) -> None: ...
107
+
108
+ def instrument_psycopg(self, *args, **kwargs) -> None: ...
109
+
110
+ def instrument_requests(self, *args, **kwargs) -> None: ...
111
+
112
+ def instrument_httpx(self, *args, **kwargs) -> None: ...
113
+
114
+ def instrument_asyncpg(self, *args, **kwargs) -> None: ...
115
+
116
+ def instrument_anthropic(self, *args, **kwargs) -> ContextManager[None]:
117
+ return nullcontext()
118
+
119
+ def instrument_openai(self, *args, **kwargs) -> ContextManager[None]:
120
+ return nullcontext()
121
+
122
+ def instrument_aiohttp_client(self, *args, **kwargs) -> None: ...
123
+
124
+ def shutdown(self, *args, **kwargs) -> None: ...
125
+
126
+ DEFAULT_LOGFIRE_INSTANCE = Logfire()
127
+ span = DEFAULT_LOGFIRE_INSTANCE.span
128
+ log = DEFAULT_LOGFIRE_INSTANCE.log
129
+ trace = DEFAULT_LOGFIRE_INSTANCE.trace
130
+ debug = DEFAULT_LOGFIRE_INSTANCE.debug
131
+ notice = DEFAULT_LOGFIRE_INSTANCE.notice
132
+ info = DEFAULT_LOGFIRE_INSTANCE.info
133
+ warn = DEFAULT_LOGFIRE_INSTANCE.warn
134
+ error = DEFAULT_LOGFIRE_INSTANCE.error
135
+ fatal = DEFAULT_LOGFIRE_INSTANCE.fatal
136
+ with_tags = DEFAULT_LOGFIRE_INSTANCE.with_tags
137
+ with_settings = DEFAULT_LOGFIRE_INSTANCE.with_settings
138
+ force_flush = DEFAULT_LOGFIRE_INSTANCE.force_flush
139
+ log_slow_async_callbacks = DEFAULT_LOGFIRE_INSTANCE.log_slow_async_callbacks
140
+ install_auto_tracing = DEFAULT_LOGFIRE_INSTANCE.install_auto_tracing
141
+ instrument = DEFAULT_LOGFIRE_INSTANCE.instrument
142
+ instrument_fastapi = DEFAULT_LOGFIRE_INSTANCE.instrument_fastapi
143
+ instrument_openai = DEFAULT_LOGFIRE_INSTANCE.instrument_openai
144
+ instrument_anthropic = DEFAULT_LOGFIRE_INSTANCE.instrument_anthropic
145
+ instrument_asyncpg = DEFAULT_LOGFIRE_INSTANCE.instrument_asyncpg
146
+ instrument_httpx = DEFAULT_LOGFIRE_INSTANCE.instrument_httpx
147
+ instrument_requests = DEFAULT_LOGFIRE_INSTANCE.instrument_requests
148
+ instrument_psycopg = DEFAULT_LOGFIRE_INSTANCE.instrument_psycopg
149
+ instrument_django = DEFAULT_LOGFIRE_INSTANCE.instrument_django
150
+ instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
151
+ instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
152
+ instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
153
+ instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
154
+ instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
155
+ instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
156
+ shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown
157
+
158
+ def no_auto_trace(x):
159
+ return x
160
+
161
+ @contextmanager
162
+ def suppress_instrumentation():
163
+ yield
164
+
165
+ class ConsoleOptions:
166
+ def __init__(self, *args, **kwargs) -> None: ...
167
+
168
+ class TailSamplingOptions:
169
+ def __init__(self, *args, **kwargs) -> None: ...
170
+
171
+ class ScrubbingOptions:
172
+ def __init__(self, *args, **kwargs) -> None: ...
173
+
174
+ class PydanticPlugin:
175
+ def __init__(self, *args, **kwargs) -> None: ...
176
+
177
+ class ScrubMatch:
178
+ def __init__(self, *args, **kwargs) -> None: ...
179
+
180
+ class AutoTraceModule:
181
+ def __init__(self, *args, **kwargs) -> None: ...
182
+
183
+ class StructlogProcessor:
184
+ def __init__(self, *args, **kwargs) -> None: ...
185
+
186
+ class LogfireLoggingHandler:
187
+ def __init__(self, *args, **kwargs) -> None: ...
188
+
189
+ def load_spans_from_file(*args, **kwargs):
190
+ return []
@@ -0,0 +1,47 @@
1
+ from ._internal.auto_trace import AutoTraceModule as AutoTraceModule
2
+ from ._internal.auto_trace.rewrite_ast import no_auto_trace as no_auto_trace
3
+ from ._internal.config import ConsoleOptions as ConsoleOptions, METRICS_PREFERRED_TEMPORALITY as METRICS_PREFERRED_TEMPORALITY, PydanticPlugin as PydanticPlugin, configure as configure
4
+ from ._internal.constants import LevelName as LevelName
5
+ from ._internal.exporters.file import load_file as load_spans_from_file
6
+ from ._internal.exporters.tail_sampling import TailSamplingOptions as TailSamplingOptions
7
+ from ._internal.main import Logfire as Logfire, LogfireSpan as LogfireSpan
8
+ from ._internal.scrubbing import ScrubMatch as ScrubMatch, ScrubbingOptions as ScrubbingOptions
9
+ from ._internal.utils import suppress_instrumentation as suppress_instrumentation
10
+ from .integrations.logging import LogfireLoggingHandler as LogfireLoggingHandler
11
+ from .integrations.structlog import LogfireProcessor as StructlogProcessor
12
+ from .version import VERSION as VERSION
13
+
14
+ __all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'ConsoleOptions', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'error', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_fastapi', 'instrument_openai', 'instrument_anthropic', 'instrument_asyncpg', 'instrument_httpx', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_sqlalchemy', 'instrument_redis', 'instrument_pymongo', 'AutoTraceModule', 'with_tags', 'with_settings', 'shutdown', 'load_spans_from_file', 'no_auto_trace', 'METRICS_PREFERRED_TEMPORALITY', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'TailSamplingOptions']
15
+
16
+ DEFAULT_LOGFIRE_INSTANCE = Logfire()
17
+ span = DEFAULT_LOGFIRE_INSTANCE.span
18
+ instrument = DEFAULT_LOGFIRE_INSTANCE.instrument
19
+ force_flush = DEFAULT_LOGFIRE_INSTANCE.force_flush
20
+ log_slow_async_callbacks = DEFAULT_LOGFIRE_INSTANCE.log_slow_async_callbacks
21
+ install_auto_tracing = DEFAULT_LOGFIRE_INSTANCE.install_auto_tracing
22
+ instrument_fastapi = DEFAULT_LOGFIRE_INSTANCE.instrument_fastapi
23
+ instrument_openai = DEFAULT_LOGFIRE_INSTANCE.instrument_openai
24
+ instrument_anthropic = DEFAULT_LOGFIRE_INSTANCE.instrument_anthropic
25
+ instrument_asyncpg = DEFAULT_LOGFIRE_INSTANCE.instrument_asyncpg
26
+ instrument_httpx = DEFAULT_LOGFIRE_INSTANCE.instrument_httpx
27
+ instrument_requests = DEFAULT_LOGFIRE_INSTANCE.instrument_requests
28
+ instrument_psycopg = DEFAULT_LOGFIRE_INSTANCE.instrument_psycopg
29
+ instrument_django = DEFAULT_LOGFIRE_INSTANCE.instrument_django
30
+ instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
31
+ instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
32
+ instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
33
+ instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
34
+ instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
35
+ instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
36
+ shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown
37
+ with_tags = DEFAULT_LOGFIRE_INSTANCE.with_tags
38
+ with_settings = DEFAULT_LOGFIRE_INSTANCE.with_settings
39
+ log = DEFAULT_LOGFIRE_INSTANCE.log
40
+ trace = DEFAULT_LOGFIRE_INSTANCE.trace
41
+ debug = DEFAULT_LOGFIRE_INSTANCE.debug
42
+ info = DEFAULT_LOGFIRE_INSTANCE.info
43
+ notice = DEFAULT_LOGFIRE_INSTANCE.notice
44
+ warn = DEFAULT_LOGFIRE_INSTANCE.warn
45
+ error = DEFAULT_LOGFIRE_INSTANCE.error
46
+ fatal = DEFAULT_LOGFIRE_INSTANCE.fatal
47
+ __version__ = VERSION
File without changes
@@ -0,0 +1,34 @@
1
+ import ast
2
+ from .constants import 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
3
+ from .stack_info import StackInfo as StackInfo, get_filepath_attribute as get_filepath_attribute
4
+ from .utils import uniquify_sequence as uniquify_sequence
5
+ from dataclasses import dataclass
6
+ from opentelemetry.util import types as otel_types
7
+
8
+ @dataclass(frozen=True)
9
+ class LogfireArgs:
10
+ """Values passed to `logfire.instrument` and/or values stored in a logfire instance as basic configuration.
11
+
12
+ These determine the arguments passed to the method calls added by the AST transformer.
13
+ """
14
+ tags: tuple[str, ...]
15
+ sample_rate: float | None
16
+ msg_template: str | None = ...
17
+ span_name: str | None = ...
18
+ extract_args: bool = ...
19
+
20
+ @dataclass
21
+ class BaseTransformer(ast.NodeTransformer):
22
+ """Helper for rewriting ASTs to wrap function bodies in `with {logfire_method_name}(...):`."""
23
+ logfire_args: LogfireArgs
24
+ logfire_method_name: str
25
+ filename: str
26
+ module_name: str
27
+ qualname_stack = ...
28
+ def __post_init__(self) -> None: ...
29
+ def visit_ClassDef(self, node: ast.ClassDef): ...
30
+ def visit_FunctionDef(self, node: ast.FunctionDef | ast.AsyncFunctionDef): ...
31
+ def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef): ...
32
+ def rewrite_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef, qualname: str) -> ast.AST: ...
33
+ def logfire_method_call_node(self, node: ast.FunctionDef | ast.AsyncFunctionDef, qualname: str) -> ast.Call: ...
34
+ def logfire_method_arg_values(self, qualname: str, lineno: int) -> tuple[str, dict[str, otel_types.AttributeValue]]: ...
@@ -0,0 +1,22 @@
1
+ from .constants import ONE_SECOND_IN_NANOSECONDS as ONE_SECOND_IN_NANOSECONDS
2
+ from .main import Logfire as Logfire
3
+ from .stack_info import StackInfo as StackInfo, get_code_object_info as get_code_object_info, get_stack_info_from_frame as get_stack_info_from_frame
4
+ from .utils import safe_repr as safe_repr
5
+ from _typeshed import Incomplete
6
+ from types import CoroutineType
7
+ from typing import Any, ContextManager
8
+
9
+ ASYNCIO_PATH: Incomplete
10
+
11
+ def log_slow_callbacks(logfire: Logfire, slow_duration: float) -> ContextManager[None]:
12
+ """Log a warning whenever a function running in the asyncio event loop blocks for too long.
13
+
14
+ See Logfire.log_slow_async_callbacks.
15
+ Inspired by https://gitlab.com/quantlane/libs/aiodebug.
16
+ """
17
+
18
+ class _CallbackAttributes(StackInfo, total=False):
19
+ name: str
20
+ stack: list[StackInfo]
21
+
22
+ def stack_info_from_coroutine(coro: CoroutineType[Any, Any, Any]) -> StackInfo: ...
@@ -0,0 +1,55 @@
1
+ import requests
2
+ from .utils import UnexpectedResponse as UnexpectedResponse
3
+ from _typeshed import Incomplete
4
+ from logfire.exceptions import LogfireConfigError as LogfireConfigError
5
+ from typing import TypedDict
6
+
7
+ HOME_LOGFIRE: Incomplete
8
+ DEFAULT_FILE: Incomplete
9
+
10
+ class UserTokenData(TypedDict):
11
+ """User token data."""
12
+ token: str
13
+ expiration: str
14
+
15
+ class DefaultFile(TypedDict):
16
+ """Content of the default.toml file."""
17
+ tokens: dict[str, UserTokenData]
18
+
19
+ class NewDeviceFlow(TypedDict):
20
+ """Matches model of the same name in the backend."""
21
+ device_code: str
22
+ frontend_auth_url: str
23
+
24
+ def request_device_code(session: requests.Session, base_api_url: str) -> tuple[str, str]:
25
+ """Request a device code from the Logfire API.
26
+
27
+ Args:
28
+ session: The `requests` session to use.
29
+ base_api_url: The base URL of the Logfire instance.
30
+
31
+ Returns:
32
+ return data['device_code'], data['frontend_auth_url']
33
+ The device code and the frontend URL to authenticate the device at, as a `NewDeviceFlow` dict.
34
+ """
35
+ def poll_for_token(session: requests.Session, device_code: str, base_api_url: str) -> UserTokenData:
36
+ """Poll the Logfire API for the user token.
37
+
38
+ This function will keep polling the API until it receives a user token, not that
39
+ each request should take ~10 seconds as the API endpoint will block waiting for the user to
40
+ complete authentication.
41
+
42
+ Args:
43
+ session: The `requests` session to use.
44
+ device_code: The device code to poll for.
45
+ base_api_url: The base URL of the Logfire instance.
46
+
47
+ Returns:
48
+ The user token.
49
+ """
50
+ def is_logged_in(data: DefaultFile, logfire_url: str) -> bool:
51
+ """Check if the user is logged in.
52
+
53
+ Returns:
54
+ True if the user is logged in, False otherwise.
55
+ """
@@ -0,0 +1,15 @@
1
+ from ..constants import ONE_SECOND_IN_NANOSECONDS as ONE_SECOND_IN_NANOSECONDS
2
+ from ..main import Logfire as Logfire
3
+ from .import_hook import LogfireFinder as LogfireFinder
4
+ from .types import AutoTraceModule as AutoTraceModule
5
+ from typing import Callable, Literal, Sequence
6
+
7
+ def install_auto_tracing(logfire: Logfire, modules: Sequence[str] | Callable[[AutoTraceModule], bool], *, check_imported_modules: Literal['error', 'warn', 'ignore'] = 'error', min_duration: float = 0) -> None:
8
+ """Install automatic tracing.
9
+
10
+ See `Logfire.install_auto_tracing` for more information.
11
+ """
12
+ def modules_func_from_sequence(modules: Sequence[str]) -> Callable[[AutoTraceModule], bool]: ...
13
+
14
+ class AutoTraceModuleAlreadyImportedException(Exception): ...
15
+ class AutoTraceModuleAlreadyImportedWarning(Warning): ...
@@ -0,0 +1,38 @@
1
+ from ..main import Logfire as Logfire
2
+ from .rewrite_ast import exec_source as exec_source
3
+ from .types import AutoTraceModule as AutoTraceModule
4
+ from dataclasses import dataclass
5
+ from importlib.abc import Loader, MetaPathFinder
6
+ from importlib.machinery import ModuleSpec
7
+ from types import ModuleType
8
+ from typing import Callable, Sequence
9
+
10
+ @dataclass
11
+ class LogfireFinder(MetaPathFinder):
12
+ """The import hook entry point, inserted into `sys.meta_path` to apply AST rewriting to matching modules."""
13
+ logfire: Logfire
14
+ modules_filter: Callable[[AutoTraceModule], bool]
15
+ min_duration: int
16
+ def find_spec(self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = None) -> ModuleSpec | None:
17
+ """This is the method that is called by the import system.
18
+
19
+ It uses the other existing meta path finders to do most of the standard work,
20
+ particularly finding the module's source code and filename.
21
+ If it finds a module spec that matches the filter, it returns a new spec that uses the LogfireLoader.
22
+ """
23
+
24
+ @dataclass
25
+ class LogfireLoader(Loader):
26
+ """An import loader produced by LogfireFinder which executes a modified AST of the module's source code."""
27
+ plain_spec: ModuleSpec
28
+ source: str
29
+ logfire: Logfire
30
+ min_duration: int
31
+ def exec_module(self, module: ModuleType):
32
+ """Execute a modified AST of the module's source code in the module's namespace.
33
+
34
+ This is called by the import system.
35
+ """
36
+ def create_module(self, spec: ModuleSpec): ...
37
+ def __getattr__(self, item: str):
38
+ """Forward some methods to the plain spec's loader (likely a `SourceFileLoader`) if they exist."""
@@ -0,0 +1,51 @@
1
+ import ast
2
+ from ..ast_utils import BaseTransformer as BaseTransformer, LogfireArgs as LogfireArgs
3
+ from ..main import Logfire as Logfire
4
+ from dataclasses import dataclass
5
+ from typing import Any, Callable, ContextManager, TypeVar
6
+
7
+ def exec_source(source: str, filename: str, module_name: str, globs: dict[str, Any], logfire_instance: Logfire, min_duration: int) -> None:
8
+ """Execute a modified AST of the module's source code in the module's namespace.
9
+
10
+ The modified AST wraps the body of every function definition in `with context_factories[index]():`.
11
+ `context_factories` is added to the module's namespace as `logfire_<uuid>`.
12
+ `index` is a different constant number for each function definition.
13
+ `context_factories[index]` is one of these:
14
+ - `partial(logfire_instance._fast_span, name, attributes)` where the name and attributes
15
+ are constructed from `filename`, `module_name`, attributes of `logfire_instance`,
16
+ and the qualified name and line number of the current function.
17
+ - `MeasureTime`, a class that measures the time elapsed. If it exceeds `min_duration`,
18
+ then `context_factories[index]` is replaced with the `partial` above.
19
+ If `min_duration` is greater than 0, then `context_factories[index]` is initially `MeasureTime`.
20
+ Otherwise, it's initially the `partial` above.
21
+ """
22
+ def rewrite_ast(source: str, filename: str, logfire_name: str, module_name: str, logfire_instance: Logfire, context_factories: list[Callable[[], ContextManager[Any]]], min_duration: int) -> ast.AST: ...
23
+
24
+ @dataclass
25
+ class AutoTraceTransformer(BaseTransformer):
26
+ """Trace all encountered functions except those explicitly marked with `@no_auto_trace`."""
27
+ logfire_instance: Logfire
28
+ context_factories: list[Callable[[], ContextManager[Any]]]
29
+ min_duration: int
30
+ def check_no_auto_trace(self, node: ast.FunctionDef | ast.AsyncFunctionDef | ast.ClassDef) -> bool:
31
+ """Return true if the node has a `@no_auto_trace` or `@logfire.no_auto_trace` decorator."""
32
+ def visit_ClassDef(self, node: ast.ClassDef): ...
33
+ def visit_FunctionDef(self, node: ast.FunctionDef | ast.AsyncFunctionDef): ...
34
+ def logfire_method_call_node(self, node: ast.FunctionDef | ast.AsyncFunctionDef, qualname: str) -> ast.Call: ...
35
+ T = TypeVar('T')
36
+
37
+ def no_auto_trace(x: T) -> T:
38
+ """Decorator to prevent a function/class from being traced by `logfire.install_auto_tracing`.
39
+
40
+ This is useful for small functions that are called very frequently and would generate too much noise.
41
+
42
+ The decorator is detected at import time.
43
+ Only `@no_auto_trace` or `@logfire.no_auto_trace` are supported.
44
+ Renaming/aliasing either the function or module won't work.
45
+ Neither will calling this indirectly via another function.
46
+
47
+ Any decorated function, or any function defined anywhere inside a decorated function/class,
48
+ will be completely ignored by `logfire.install_auto_tracing`.
49
+
50
+ This decorator simply returns the argument unchanged, so there is zero runtime overhead.
51
+ """
@@ -0,0 +1,24 @@
1
+ from dataclasses import dataclass
2
+ from typing import Sequence
3
+
4
+ @dataclass
5
+ class AutoTraceModule:
6
+ """Information about a module being imported that should maybe be traced automatically.
7
+
8
+ This object will be passed to a function that should return True if the module should be traced.
9
+ In particular it'll be passed to a function that's passed to `install_auto_tracing` as the `modules` argument.
10
+ """
11
+ name: str
12
+ filename: str | None
13
+ def parts_start_with(self, prefix: str | Sequence[str]) -> bool:
14
+ """Return True if the module name starts with any of the given prefixes, using dots as boundaries.
15
+
16
+ For example, if the module name is `foo.bar.spam`, then `parts_start_with('foo')` will return True,
17
+ but `parts_start_with('bar')` or `parts_start_with('foo_bar')` will return False.
18
+ In other words, this will match the module itself or any submodules.
19
+
20
+ If a prefix contains any characters other than letters, numbers, and dots,
21
+ then it will be treated as a regular expression.
22
+ """
23
+
24
+ def get_module_pattern(module: str): ...
@@ -0,0 +1,72 @@
1
+ from .constants import LevelName
2
+ from _typeshed import Incomplete
3
+ from datetime import datetime
4
+ from pathlib import Path
5
+ from pydantic import BaseModel
6
+ from typing import Any, IO
7
+
8
+ __all__ = ['generate_trace_id', 'generate_span_id', 'Log', 'StartSpan', 'PrepareBackfill']
9
+
10
+ def generate_trace_id() -> int:
11
+ """Generate a new trace ID.
12
+
13
+ Returns:
14
+ A new trace ID.
15
+ """
16
+ def generate_span_id() -> int:
17
+ """Generate a new span ID.
18
+
19
+ Returns:
20
+ A new span ID.
21
+ """
22
+
23
+ class Log(BaseModel):
24
+ """A log record."""
25
+ model_config = pydantic_config
26
+ msg_template: str
27
+ level: LevelName
28
+ service_name: str
29
+ attributes: dict[str, Any]
30
+ trace_id: int
31
+ span_id: int
32
+ parent_span_id: int | None
33
+ timestamp: datetime | None
34
+ formatted_msg: str | None
35
+ otel_resource_attributes: dict[str, Any]
36
+
37
+ class StartSpan(BaseModel):
38
+ """A span."""
39
+ model_config = pydantic_config
40
+ span_name: str
41
+ msg_template: str
42
+ service_name: str
43
+ parent: StartSpan | int | None
44
+ log_attributes: dict[str, Any]
45
+ span_id: int
46
+ trace_id: int
47
+ parent_span_id: int | None
48
+ start_timestamp: datetime | None
49
+ formatted_msg: str | None
50
+ otel_resource_attributes: dict[str, Any]
51
+ def end(self, end_timestamp: datetime) -> Span:
52
+ """End the span at a given timestamp."""
53
+
54
+ class Span(StartSpan):
55
+ end_timestamp: datetime | None
56
+
57
+ class PrepareBackfill:
58
+ """Prepare a backfill of logfire logs and spans from a file or stream.
59
+
60
+ Attributes:
61
+ store_path: The path to the file or stream to backfill.
62
+ open_spans: A mapping of open spans, keyed by (trace_id, span_id).
63
+ processor: The span processor to use for the backfill.
64
+ """
65
+ store_path: Incomplete
66
+ processor: Incomplete
67
+ scrubber: Incomplete
68
+ def __init__(self, file: Path | str | IO[bytes], batch: bool = True) -> None: ...
69
+ def __enter__(self) -> PrepareBackfill: ...
70
+ def write(self, data: Log | Span) -> None:
71
+ """Write the data to the backfill."""
72
+ def __exit__(self, *_: Any) -> None: ...
@@ -0,0 +1,48 @@
1
+ import argparse
2
+ from ..version import VERSION as VERSION
3
+ from .auth import DEFAULT_FILE as DEFAULT_FILE, DefaultFile as DefaultFile, HOME_LOGFIRE as HOME_LOGFIRE, is_logged_in as is_logged_in, poll_for_token as poll_for_token, request_device_code as request_device_code
4
+ from .config import LogfireCredentials as LogfireCredentials
5
+ from .config_params import ParamManager as ParamManager
6
+ from .constants import LOGFIRE_BASE_URL as LOGFIRE_BASE_URL
7
+ from .tracer import SDKTracerProvider as SDKTracerProvider
8
+ from .utils import read_toml_file as read_toml_file
9
+ from _typeshed import Incomplete
10
+ from logfire.exceptions import LogfireConfigError as LogfireConfigError
11
+ from logfire.propagate import ContextCarrier as ContextCarrier, get_context as get_context
12
+
13
+ BASE_OTEL_INTEGRATION_URL: str
14
+ BASE_DOCS_URL: str
15
+ INTEGRATIONS_DOCS_URL: Incomplete
16
+ LOGFIRE_LOG_FILE: Incomplete
17
+ file_handler: Incomplete
18
+ logger: Incomplete
19
+
20
+ def version_callback() -> None:
21
+ """Show the version and exit."""
22
+ def parse_whoami(args: argparse.Namespace) -> None:
23
+ """Show user authenticated username and the URL to your Logfire project."""
24
+ def parse_clean(args: argparse.Namespace) -> None:
25
+ """Remove the contents of the Logfire data directory."""
26
+ def parse_backfill(args: argparse.Namespace) -> None:
27
+ """Bulk upload data to Logfire."""
28
+
29
+ OTEL_PACKAGES: set[str]
30
+ OTEL_PACKAGE_LINK: Incomplete
31
+
32
+ def parse_inspect(args: argparse.Namespace) -> None:
33
+ """Inspect installed packages and recommend packages that might be useful."""
34
+ def parse_auth(args: argparse.Namespace) -> None:
35
+ """Authenticate with Logfire.
36
+
37
+ This will authenticate your machine with Logfire and store the credentials.
38
+ """
39
+ def parse_list_projects(args: argparse.Namespace) -> None:
40
+ """List user projects."""
41
+ def parse_create_new_project(args: argparse.Namespace) -> None:
42
+ """Create a new project."""
43
+ def parse_use_project(args: argparse.Namespace) -> None:
44
+ """Use an existing project."""
45
+ def parse_info(_args: argparse.Namespace) -> None:
46
+ """Show versions of logfire, OS and related packages."""
47
+ def main(args: list[str] | None = None) -> None:
48
+ """Run the CLI."""
@@ -0,0 +1,6 @@
1
+ def collect_package_info() -> dict[str, str]:
2
+ """Retrieve the package information for all installed packages.
3
+
4
+ Returns:
5
+ A dicts with the package name and version.
6
+ """