Skip to content

Commit fb0a162

Browse files
authored
Deprecate project_name in logfire.configure(), remove old kwargs from signature (#428)
1 parent 8c8d80e commit fb0a162

File tree

7 files changed

+49
-57
lines changed

7 files changed

+49
-57
lines changed

logfire/_internal/config.py

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from functools import cached_property
1515
from pathlib import Path
1616
from threading import RLock, Thread
17-
from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, cast
17+
from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, TypedDict, cast
1818
from urllib.parse import urljoin
1919
from uuid import uuid4
2020
from weakref import WeakSet
@@ -50,7 +50,7 @@
5050
from opentelemetry.semconv.resource import ResourceAttributes
5151
from rich.console import Console
5252
from rich.prompt import Confirm, Prompt
53-
from typing_extensions import Self
53+
from typing_extensions import Self, Unpack
5454

5555
from logfire.exceptions import LogfireConfigError
5656
from logfire.version import VERSION
@@ -78,7 +78,7 @@
7878
from .exporters.test import TestExporter
7979
from .integrations.executors import instrument_executors
8080
from .metrics import ProxyMeterProvider
81-
from .scrubbing import NOOP_SCRUBBER, BaseScrubber, Scrubber, ScrubbingOptions, ScrubCallback
81+
from .scrubbing import NOOP_SCRUBBER, BaseScrubber, Scrubber, ScrubbingOptions
8282
from .stack_info import warn_at_user_stacklevel
8383
from .tracer import PendingSpanProcessor, ProxyTracerProvider
8484
from .utils import UnexpectedResponse, ensure_data_dir_exists, get_version, read_toml_file, suppress_instrumentation
@@ -144,11 +144,15 @@ class PydanticPlugin:
144144
"""Exclude specific modules from instrumentation."""
145145

146146

147-
def configure(
147+
class DeprecatedKwargs(TypedDict):
148+
# Empty so that passing any additional kwargs makes static type checkers complain.
149+
pass
150+
151+
152+
def configure( # noqa: D417
148153
*,
149154
send_to_logfire: bool | Literal['if-token-present'] | None = None,
150155
token: str | None = None,
151-
project_name: str | None = None,
152156
service_name: str | None = None,
153157
service_version: str | None = None,
154158
trace_sample_rate: float | None = None,
@@ -157,20 +161,16 @@ def configure(
157161
config_dir: Path | str | None = None,
158162
data_dir: Path | str | None = None,
159163
base_url: str | None = None,
160-
collect_system_metrics: None = None,
161164
id_generator: IdGenerator | None = None,
162165
ns_timestamp_generator: Callable[[], int] | None = None,
163-
processors: None = None,
164166
additional_span_processors: Sequence[SpanProcessor] | None = None,
165-
metric_readers: None = None,
166167
additional_metric_readers: Sequence[MetricReader] | None = None,
167168
pydantic_plugin: PydanticPlugin | None = None,
168169
fast_shutdown: bool = False,
169-
scrubbing_patterns: Sequence[str] | None = None,
170-
scrubbing_callback: ScrubCallback | None = None,
171170
scrubbing: ScrubbingOptions | Literal[False] | None = None,
172171
inspect_arguments: bool | None = None,
173172
tail_sampling: TailSamplingOptions | None = None,
173+
**deprecated_kwargs: Unpack[DeprecatedKwargs],
174174
) -> None:
175175
"""Configure the logfire SDK.
176176
@@ -179,11 +179,6 @@ def configure(
179179
variable if set, otherwise defaults to `True`. If `if-token-present` is provided, logs will only be sent if
180180
a token is present.
181181
token: The project token. Defaults to the `LOGFIRE_TOKEN` environment variable.
182-
project_name: Name to request when creating a new project. Defaults to the `LOGFIRE_PROJECT_NAME` environment
183-
variable, or the current directory name.
184-
Project name accepts a string value containing alphanumeric characters and
185-
hyphens (-). The hyphen character must not be located at the beginning or end of the string and should
186-
appear in between alphanumeric characters.
187182
service_name: Name of this service. Defaults to the `LOGFIRE_SERVICE_NAME` environment variable.
188183
service_version: Version of this service. Defaults to the `LOGFIRE_SERVICE_VERSION` environment variable, or the
189184
current git commit hash if available.
@@ -198,39 +193,37 @@ def configure(
198193
`LOGFIRE_CONFIG_DIR` environment variable, otherwise defaults to the current working directory.
199194
data_dir: Directory to store credentials, and logs. If `None` uses the `LOGFIRE_CREDENTIALS_DIR` environment variable, otherwise defaults to `'.logfire'`.
200195
base_url: Root URL for the Logfire API. If `None` uses the `LOGFIRE_BASE_URL` environment variable, otherwise defaults to https://logfire-api.pydantic.dev.
201-
collect_system_metrics: Legacy argument, use [`logfire.instrument_system_metrics()`](https://docs.pydantic.dev/logfire/integrations/system_metrics/) instead.
202196
id_generator: Generator for span IDs. Defaults to `RandomIdGenerator()` from the OpenTelemetry SDK.
203197
ns_timestamp_generator: Generator for nanosecond timestamps. Defaults to [`time.time_ns`][time.time_ns] from the
204198
Python standard library.
205-
processors: Legacy argument, use `additional_span_processors` instead.
206199
additional_span_processors: Span processors to use in addition to the default processor which exports spans to Logfire's API.
207-
metric_readers: Legacy argument, use `additional_metric_readers` instead.
208200
additional_metric_readers: Sequence of metric readers to be used in addition to the default reader
209201
which exports metrics to Logfire's API.
210202
pydantic_plugin: Configuration for the Pydantic plugin. If `None` uses the `LOGFIRE_PYDANTIC_PLUGIN_*` environment
211203
variables, otherwise defaults to `PydanticPlugin(record='off')`.
212204
fast_shutdown: Whether to shut down exporters and providers quickly, mostly used for tests. Defaults to `False`.
213205
scrubbing: Options for scrubbing sensitive data. Set to `False` to disable.
214-
scrubbing_patterns: Deprecated, use `scrubbing=logfire.ScrubbingOptions(extra_patterns=[...])` instead.
215-
scrubbing_callback: Deprecated, use `scrubbing=logfire.ScrubbingOptions(callback=...)` instead.
216206
inspect_arguments: Whether to enable
217207
[f-string magic](https://docs.pydantic.dev/logfire/guides/onboarding_checklist/add_manual_tracing/#f-strings).
218208
If `None` uses the `LOGFIRE_INSPECT_ARGUMENTS` environment variable.
219209
Defaults to `True` if and only if the Python version is at least 3.11.
220210
tail_sampling: Tail sampling options. Not ready for general use.
221211
"""
212+
processors = deprecated_kwargs.pop('processors', None) # type: ignore
222213
if processors is not None: # pragma: no cover
223214
raise ValueError(
224215
'The `processors` argument has been replaced by `additional_span_processors`. '
225216
'Set `send_to_logfire=False` to disable the default processor.'
226217
)
227218

219+
metric_readers = deprecated_kwargs.pop('metric_readers', None) # type: ignore
228220
if metric_readers is not None: # pragma: no cover
229221
raise ValueError(
230222
'The `metric_readers` argument has been replaced by `additional_metric_readers`. '
231223
'Set `send_to_logfire=False` to disable the default metric reader.'
232224
)
233225

226+
collect_system_metrics = deprecated_kwargs.pop('collect_system_metrics', None) # type: ignore
234227
if collect_system_metrics is False:
235228
raise ValueError(
236229
'The `collect_system_metrics` argument has been removed. '
@@ -243,6 +236,8 @@ def configure(
243236
'Use `logfire.instrument_system_metrics()` instead.'
244237
)
245238

239+
scrubbing_callback = deprecated_kwargs.pop('scrubbing_callback', None) # type: ignore
240+
scrubbing_patterns = deprecated_kwargs.pop('scrubbing_patterns', None) # type: ignore
246241
if scrubbing_callback or scrubbing_patterns:
247242
if scrubbing is not None:
248243
raise ValueError(
@@ -254,13 +249,22 @@ def configure(
254249
'Use `scrubbing=logfire.ScrubbingOptions(callback=..., extra_patterns=[...])` instead.',
255250
DeprecationWarning,
256251
)
257-
scrubbing = ScrubbingOptions(callback=scrubbing_callback, extra_patterns=scrubbing_patterns)
252+
scrubbing = ScrubbingOptions(callback=scrubbing_callback, extra_patterns=scrubbing_patterns) # type: ignore
253+
254+
project_name = deprecated_kwargs.pop('project_name', None) # type: ignore
255+
if project_name is not None:
256+
warnings.warn(
257+
'The `project_name` argument is deprecated and not needed.',
258+
DeprecationWarning,
259+
)
260+
261+
if deprecated_kwargs:
262+
raise TypeError(f'configure() got unexpected keyword arguments: {", ".join(deprecated_kwargs)}')
258263

259264
GLOBAL_CONFIG.configure(
260265
base_url=base_url,
261266
send_to_logfire=send_to_logfire,
262267
token=token,
263-
project_name=project_name,
264268
service_name=service_name,
265269
service_version=service_version,
266270
trace_sample_rate=trace_sample_rate,
@@ -308,9 +312,6 @@ class _LogfireConfigData:
308312
token: str | None
309313
"""The Logfire API token to use"""
310314

311-
project_name: str | None
312-
"""The Logfire project name to use"""
313-
314315
service_name: str
315316
"""The name of this service"""
316317

@@ -361,7 +362,6 @@ def _load_configuration(
361362
base_url: str | None,
362363
send_to_logfire: bool | Literal['if-token-present'] | None,
363364
token: str | None,
364-
project_name: str | None,
365365
service_name: str | None,
366366
service_version: str | None,
367367
trace_sample_rate: float | None,
@@ -385,7 +385,6 @@ def _load_configuration(
385385
self.base_url = param_manager.load_param('base_url', base_url)
386386
self.send_to_logfire = param_manager.load_param('send_to_logfire', send_to_logfire)
387387
self.token = param_manager.load_param('token', token)
388-
self.project_name = param_manager.load_param('project_name', project_name)
389388
self.service_name = param_manager.load_param('service_name', service_name)
390389
self.service_version = param_manager.load_param('service_version', service_version)
391390
self.trace_sample_rate = param_manager.load_param('trace_sample_rate', trace_sample_rate)
@@ -461,7 +460,6 @@ def __init__(
461460
base_url: str | None = None,
462461
send_to_logfire: bool | None = None,
463462
token: str | None = None,
464-
project_name: str | None = None,
465463
service_name: str | None = None,
466464
service_version: str | None = None,
467465
trace_sample_rate: float | None = None,
@@ -491,7 +489,6 @@ def __init__(
491489
base_url=base_url,
492490
send_to_logfire=send_to_logfire,
493491
token=token,
494-
project_name=project_name,
495492
service_name=service_name,
496493
service_version=service_version,
497494
trace_sample_rate=trace_sample_rate,
@@ -525,7 +522,6 @@ def configure(
525522
base_url: str | None,
526523
send_to_logfire: bool | Literal['if-token-present'] | None,
527524
token: str | None,
528-
project_name: str | None,
529525
service_name: str | None,
530526
service_version: str | None,
531527
trace_sample_rate: float | None,
@@ -549,7 +545,6 @@ def configure(
549545
base_url,
550546
send_to_logfire,
551547
token,
552-
project_name,
553548
service_name,
554549
service_version,
555550
trace_sample_rate,
@@ -677,7 +672,6 @@ def add_span_processor(span_processor: SpanProcessor) -> None:
677672
if (credentials := LogfireCredentials.load_creds_file(self.data_dir)) is None: # pragma: no branch
678673
credentials = LogfireCredentials.initialize_project(
679674
logfire_api_url=self.base_url,
680-
project_name=self.project_name,
681675
session=requests.Session(),
682676
)
683677
credentials.write_creds_file(self.data_dir)
@@ -1157,7 +1151,6 @@ def create_new_project(
11571151
organization: str | None = None,
11581152
default_organization: bool = False,
11591153
project_name: str | None = None,
1160-
force_project_name_prompt: bool = False,
11611154
) -> dict[str, Any]:
11621155
"""Create a new project and configure it to be used by Logfire.
11631156
@@ -1170,8 +1163,6 @@ def create_new_project(
11701163
organization: The organization name of the new project.
11711164
default_organization: Whether to create the project under the user default organization.
11721165
project_name: The default name of the project.
1173-
force_project_name_prompt: Whether to force a prompt for the project name.
1174-
service_name: Name of the service.
11751166
11761167
Returns:
11771168
The created project informations.
@@ -1216,11 +1207,10 @@ def create_new_project(
12161207
if not confirm:
12171208
sys.exit(1)
12181209

1219-
project_name_default: str | None = project_name or default_project_name()
1210+
project_name_default: str | None = default_project_name()
12201211
project_name_prompt = 'Enter the project name'
12211212
while True:
1222-
if force_project_name_prompt or not project_name:
1223-
project_name = Prompt.ask(project_name_prompt, default=project_name_default)
1213+
project_name = project_name or Prompt.ask(project_name_prompt, default=project_name_default)
12241214
while project_name and not re.match(PROJECT_NAME_PATTERN, project_name):
12251215
project_name = Prompt.ask(
12261216
"\nThe project name you've entered is invalid. Valid project names:\n"
@@ -1264,15 +1254,12 @@ def initialize_project(
12641254
cls,
12651255
*,
12661256
logfire_api_url: str,
1267-
project_name: str | None,
12681257
session: requests.Session,
12691258
) -> Self:
12701259
"""Create a new project or use an existing project on logfire.dev requesting the given project name.
12711260
12721261
Args:
12731262
logfire_api_url: The Logfire API base URL.
1274-
project_name: Name for the project.
1275-
user_token: The user's token to use to create the new project.
12761263
session: HTTP client session used to communicate with the Logfire API.
12771264
12781265
Returns:
@@ -1300,8 +1287,6 @@ def initialize_project(
13001287
credentials = cls.create_new_project(
13011288
session=session,
13021289
logfire_api_url=logfire_api_url,
1303-
project_name=project_name,
1304-
force_project_name_prompt=True,
13051290
)
13061291

13071292
try:

logfire/_internal/config_params.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ class _DefaultCallback:
5959
"""Whether to send spans to Logfire."""
6060
TOKEN = ConfigParam(env_vars=['LOGFIRE_TOKEN'])
6161
"""Token for the Logfire API."""
62-
PROJECT_NAME = ConfigParam(env_vars=['LOGFIRE_PROJECT_NAME'], allow_file_config=True)
63-
"""Name of the project. Project name accepts a string value containing alphanumeric characters and hyphens (-). The hyphen character must not be located at the beginning or end of the string and should appear in between alphanumeric characters."""
6462
SERVICE_NAME = ConfigParam(env_vars=['LOGFIRE_SERVICE_NAME', OTEL_SERVICE_NAME], allow_file_config=True, default='')
6563
"""Name of the service emitting spans. For further details, please refer to the [Service section](https://opentelemetry.io/docs/specs/semconv/resource/#service)."""
6664
SERVICE_VERSION = ConfigParam(env_vars=['LOGFIRE_SERVICE_VERSION', 'OTEL_SERVICE_VERSION'], allow_file_config=True)
@@ -104,7 +102,6 @@ class _DefaultCallback:
104102
'base_url': BASE_URL,
105103
'send_to_logfire': SEND_TO_LOGFIRE,
106104
'token': TOKEN,
107-
'project_name': PROJECT_NAME,
108105
'service_name': SERVICE_NAME,
109106
'service_version': SERVICE_VERSION,
110107
'trace_sample_rate': TRACE_SAMPLE_RATE,

logfire/_internal/scrubbing.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353

5454
@dataclass
5555
class ScrubMatch:
56-
"""An object passed to the [`scrubbing_callback`][logfire.configure(scrubbing_callback)] function."""
56+
"""An object passed to a [`ScrubbingOptions.callback`][logfire.ScrubbingOptions.callback] function."""
5757

5858
path: JsonPath
5959
"""The path to the value in the span being considered for redaction, e.g. `('attributes', 'password')`."""
@@ -68,7 +68,6 @@ class ScrubMatch:
6868
"""
6969

7070

71-
# See scrubbing_callback in logfire.configure for more info on this type.
7271
ScrubCallback = Callable[[ScrubMatch], Any]
7372

7473

@@ -152,7 +151,7 @@ class Scrubber(BaseScrubber):
152151
"""Redacts potentially sensitive data."""
153152

154153
def __init__(self, patterns: Sequence[str] | None, callback: ScrubCallback | None = None):
155-
# See scrubbing_patterns and scrubbing_callback in logfire.configure for more info on these parameters.
154+
# See ScrubbingOptions for more info on these parameters.
156155
patterns = [*DEFAULT_PATTERNS, *(patterns or [])]
157156
self._pattern = re.compile('|'.join(patterns), re.IGNORECASE | re.DOTALL)
158157
self._callback = callback

tests/test_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ def test_projects_new_invalid_project_name(tmp_dir_cwd: Path, default_credential
688688
' * may contain single hyphens\n'
689689
' * may not start or end with a hyphen\n\n'
690690
'Enter the project name you want to use:',
691-
default='invalid name',
691+
default='testprojectsnewinvalidproj0',
692692
),
693693
]
694694
console_calls = [re.sub(r'^call(\(\).)?', '', str(call)) for call in console.mock_calls]

tests/test_configure.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,6 @@ def test_read_config_from_pyproject_toml(tmp_path: Path) -> None:
476476

477477
assert GLOBAL_CONFIG.base_url == 'https://api.logfire.io'
478478
assert GLOBAL_CONFIG.send_to_logfire is False
479-
assert GLOBAL_CONFIG.project_name == 'test'
480479
assert GLOBAL_CONFIG.console
481480
assert GLOBAL_CONFIG.console.colors == 'never'
482481
assert GLOBAL_CONFIG.console.include_timestamps is False
@@ -1546,3 +1545,15 @@ def test_collect_system_metrics_true():
15461545
)
15471546
):
15481547
logfire.configure(collect_system_metrics=True) # type: ignore
1548+
1549+
1550+
def test_unknown_kwargs():
1551+
with inline_snapshot.extra.raises(snapshot('TypeError: configure() got unexpected keyword arguments: foo, bar')):
1552+
logfire.configure(foo=1, bar=2) # type: ignore
1553+
1554+
1555+
def test_project_name_deprecated():
1556+
with inline_snapshot.extra.raises(
1557+
snapshot('DeprecationWarning: The `project_name` argument is deprecated and not needed.')
1558+
):
1559+
logfire.configure(project_name='foo') # type: ignore

tests/test_logfire.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,10 +1253,10 @@ def test_format_attribute_added_after_pending_span_sent(exporter: TestExporter)
12531253
)
12541254

12551255

1256-
def check_project_name(expected_project_name: str) -> None:
1256+
def check_service_name(expected_service_name: str) -> None:
12571257
from logfire._internal.config import GLOBAL_CONFIG
12581258

1259-
assert GLOBAL_CONFIG.project_name == expected_project_name
1259+
assert GLOBAL_CONFIG.service_name == expected_service_name
12601260

12611261

12621262
@pytest.mark.parametrize(
@@ -1273,12 +1273,12 @@ def test_config_preserved_across_thread_or_process(
12731273
configure(
12741274
send_to_logfire=False,
12751275
console=False,
1276-
project_name='foobar!',
1276+
service_name='foobar!',
12771277
additional_metric_readers=[InMemoryMetricReader()],
12781278
)
12791279

12801280
with executor_factory() as executor:
1281-
executor.submit(check_project_name, 'foobar!')
1281+
executor.submit(check_service_name, 'foobar!')
12821282
executor.shutdown(wait=True)
12831283

12841284

tests/test_secret_scrubbing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def callback(match: logfire.ScrubMatch): # pragma: no cover
331331
with pytest.warns(
332332
DeprecationWarning, match='The `scrubbing_callback` and `scrubbing_patterns` arguments are deprecated.'
333333
):
334-
logfire.configure(**config_kwargs, scrubbing_patterns=['my_pattern'], scrubbing_callback=callback)
334+
logfire.configure(**config_kwargs, scrubbing_patterns=['my_pattern'], scrubbing_callback=callback) # type: ignore
335335

336336
config = logfire.DEFAULT_LOGFIRE_INSTANCE.config
337337
assert config.scrubbing
@@ -344,7 +344,7 @@ def test_scrubbing_deprecated_args_combined_with_new_options():
344344
ValueError,
345345
match='Cannot specify `scrubbing` and `scrubbing_callback` or `scrubbing_patterns` at the same time.',
346346
):
347-
logfire.configure(scrubbing_patterns=['my_pattern'], scrubbing=logfire.ScrubbingOptions())
347+
logfire.configure(scrubbing_patterns=['my_pattern'], scrubbing=logfire.ScrubbingOptions()) # type: ignore
348348

349349

350350
@pytest.mark.skipif(sys.version_info[:2] < (3, 9), reason='f-string magic is not allowed in 3.8')

0 commit comments

Comments
 (0)