From 072699fcc626ea6df86ee832042df8f591e01b01 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 30 Oct 2024 14:17:34 -0400 Subject: [PATCH 01/17] check creds for token --- logfire/_internal/config.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 3090de435..e36bc9414 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -801,11 +801,14 @@ def add_span_processor(span_processor: SpanProcessor) -> None: if isinstance(self.metrics, MetricsOptions): metric_readers = list(self.metrics.additional_readers) - if (self.send_to_logfire == 'if-token-present' and self.token is not None) or self.send_to_logfire is True: + credentials = LogfireCredentials.load_creds_file(self.data_dir) # pragma: no branch + token_present = (self.token is not None) or (credentials is not None) + + if (self.send_to_logfire == 'if-token-present' and token_present) or self.send_to_logfire is True: show_project_link = self.console and self.console.show_project_link if self.token is None: - if (credentials := LogfireCredentials.load_creds_file(self.data_dir)) is None: # pragma: no branch + if credentials is None: credentials = LogfireCredentials.initialize_project( logfire_api_url=self.advanced.base_url, session=requests.Session(), @@ -818,10 +821,13 @@ def add_span_processor(span_processor: SpanProcessor) -> None: else: def check_token(): + nonlocal credentials + assert self.token is not None - creds = self._initialize_credentials_from_token(self.token) - if show_project_link and creds is not None: # pragma: no branch - creds.print_token_summary() + if credentials is None: + credentials = self._initialize_credentials_from_token(self.token) + if show_project_link and credentials is not None: # pragma: no branch + credentials.print_token_summary() thread = Thread(target=check_token, name='check_logfire_token') thread.start() From 76607ef7dac4bca8d94b7ddd265545edc879efc0 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 30 Oct 2024 14:31:13 -0400 Subject: [PATCH 02/17] adding test --- tests/test_configure.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_configure.py b/tests/test_configure.py index 423fdd5be..c89935435 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1297,6 +1297,29 @@ def test_send_to_logfire_if_token_present_not_empty(capsys: pytest.CaptureFixtur del os.environ['LOGFIRE_TOKEN'] +def test_send_to_logfire_if_token_present_in_logfire_dir(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None: + creds_file = tmp_path / 'logfire_credentials.json' + creds_file.write_text( + """ + { + "token": "foobar", + "project_name": "myproject", + "project_url": "fake_project_url", + "logfire_api_url": "https://logfire-api.pydantic.dev" + } + """ + ) + with requests_mock.Mocker() as request_mocker: + request_mocker.get( + 'https://logfire-api.pydantic.dev/v1/info', + json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + ) + configure(send_to_logfire='if-token-present') + wait_for_check_token_thread() + assert len(request_mocker.request_history) == 1 + assert capsys.readouterr().err == 'Logfire project URL: fake_project_url\n' + + def test_load_creds_file_invalid_json_content(tmp_path: Path): creds_file = tmp_path / 'logfire_credentials.json' creds_file.write_text('invalid-data') From 4726cf796868b7324f4093466c402db0bc98995f Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Wed, 30 Oct 2024 14:44:12 -0400 Subject: [PATCH 03/17] try fixing test --- logfire/_internal/config.py | 10 ++++------ tests/test_configure.py | 11 +++++------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index e36bc9414..2f9b06f48 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -816,22 +816,20 @@ def add_span_processor(span_processor: SpanProcessor) -> None: credentials.write_creds_file(self.data_dir) self.token = credentials.token self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url - if show_project_link: # pragma: no branch - credentials.print_token_summary() else: def check_token(): nonlocal credentials assert self.token is not None - if credentials is None: - credentials = self._initialize_credentials_from_token(self.token) - if show_project_link and credentials is not None: # pragma: no branch - credentials.print_token_summary() + credentials = credentials or self._initialize_credentials_from_token(self.token) thread = Thread(target=check_token, name='check_logfire_token') thread.start() + if show_project_link and credentials is not None: # pragma: no branch + credentials.print_token_summary() + headers = {'User-Agent': f'logfire/{VERSION}', 'Authorization': self.token} session = OTLPExporterHttpSession(max_body_size=OTLP_MAX_BODY_SIZE) session.headers.update(headers) diff --git a/tests/test_configure.py b/tests/test_configure.py index c89935435..3ab29a157 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1304,20 +1304,19 @@ def test_send_to_logfire_if_token_present_in_logfire_dir(tmp_path: Path, capsys: { "token": "foobar", "project_name": "myproject", - "project_url": "fake_project_url", - "logfire_api_url": "https://logfire-api.pydantic.dev" + "project_url": "http://dash.localhost:8000/", + "logfire_api_url": "http://dash.localhost:8000/" } """ ) with requests_mock.Mocker() as request_mocker: request_mocker.get( 'https://logfire-api.pydantic.dev/v1/info', - json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + json={'project_name': 'myproject', 'project_url': 'http://dash.localhost:8000/'}, ) - configure(send_to_logfire='if-token-present') - wait_for_check_token_thread() + configure(send_to_logfire='if-token-present', data_dir=tmp_path) assert len(request_mocker.request_history) == 1 - assert capsys.readouterr().err == 'Logfire project URL: fake_project_url\n' + assert capsys.readouterr().err == 'Logfire project URL: http://dash.localhost:8000/\n' def test_load_creds_file_invalid_json_content(tmp_path: Path): From 0a509d2e987f170c9e3cbe1ec8f07fd7c442129f Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Wed, 30 Oct 2024 22:31:55 +0200 Subject: [PATCH 04/17] wait_for_check_token_thread --- tests/test_configure.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_configure.py b/tests/test_configure.py index 3ab29a157..e5b7c38bf 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1315,6 +1315,7 @@ def test_send_to_logfire_if_token_present_in_logfire_dir(tmp_path: Path, capsys: json={'project_name': 'myproject', 'project_url': 'http://dash.localhost:8000/'}, ) configure(send_to_logfire='if-token-present', data_dir=tmp_path) + wait_for_check_token_thread() assert len(request_mocker.request_history) == 1 assert capsys.readouterr().err == 'Logfire project URL: http://dash.localhost:8000/\n' From 5c0d7e78e679b3729a25f58a416bc7ffef18b72c Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Thu, 31 Oct 2024 08:42:08 -0400 Subject: [PATCH 05/17] Update logfire/_internal/config.py Co-authored-by: Alex Hall --- logfire/_internal/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 2f9b06f48..e4e9f4a76 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -801,7 +801,7 @@ def add_span_processor(span_processor: SpanProcessor) -> None: if isinstance(self.metrics, MetricsOptions): metric_readers = list(self.metrics.additional_readers) - credentials = LogfireCredentials.load_creds_file(self.data_dir) # pragma: no branch + credentials = LogfireCredentials.load_creds_file(self.data_dir) token_present = (self.token is not None) or (credentials is not None) if (self.send_to_logfire == 'if-token-present' and token_present) or self.send_to_logfire is True: From cce5d11863a0c12b0e9f32d8767277cbf7636e03 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Thu, 31 Oct 2024 09:33:44 -0400 Subject: [PATCH 06/17] init creds from token unconditionally --- logfire/_internal/config.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 2f9b06f48..2d11c68b7 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -801,35 +801,35 @@ def add_span_processor(span_processor: SpanProcessor) -> None: if isinstance(self.metrics, MetricsOptions): metric_readers = list(self.metrics.additional_readers) - credentials = LogfireCredentials.load_creds_file(self.data_dir) # pragma: no branch - token_present = (self.token is not None) or (credentials is not None) + creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) # pragma: no branch + if creds_from_file: + self.token = creds_from_file.token + self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url - if (self.send_to_logfire == 'if-token-present' and token_present) or self.send_to_logfire is True: + if (self.send_to_logfire == 'if-token-present' and self.token is not None) or self.send_to_logfire is True: show_project_link = self.console and self.console.show_project_link if self.token is None: - if credentials is None: - credentials = LogfireCredentials.initialize_project( - logfire_api_url=self.advanced.base_url, - session=requests.Session(), - ) - credentials.write_creds_file(self.data_dir) + credentials = LogfireCredentials.initialize_project( + logfire_api_url=self.advanced.base_url, + session=requests.Session(), + ) + credentials.write_creds_file(self.data_dir) self.token = credentials.token self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url + if show_project_link: # pragma: no branch + credentials.print_token_summary() else: def check_token(): - nonlocal credentials - assert self.token is not None - credentials = credentials or self._initialize_credentials_from_token(self.token) + creds = self._initialize_credentials_from_token(self.token) + if show_project_link and creds is not None: # pragma: no branch + creds.print_token_summary() thread = Thread(target=check_token, name='check_logfire_token') thread.start() - if show_project_link and credentials is not None: # pragma: no branch - credentials.print_token_summary() - headers = {'User-Agent': f'logfire/{VERSION}', 'Authorization': self.token} session = OTLPExporterHttpSession(max_body_size=OTLP_MAX_BODY_SIZE) session.headers.update(headers) From ea48a5e11fd196e300143f398836020cdf173c6e Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Thu, 31 Oct 2024 09:36:05 -0400 Subject: [PATCH 07/17] remove pragma --- logfire/_internal/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 2d11c68b7..d105a86df 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -801,7 +801,7 @@ def add_span_processor(span_processor: SpanProcessor) -> None: if isinstance(self.metrics, MetricsOptions): metric_readers = list(self.metrics.additional_readers) - creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) # pragma: no branch + creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) if creds_from_file: self.token = creds_from_file.token self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url From 8f849e3ba9931ad6d4ed4f7d0fca82bc92b2e556 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Thu, 31 Oct 2024 09:57:05 -0400 Subject: [PATCH 08/17] low prio for creds file token --- logfire/_internal/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index d105a86df..3a935a774 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -802,7 +802,8 @@ def add_span_processor(span_processor: SpanProcessor) -> None: metric_readers = list(self.metrics.additional_readers) creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) - if creds_from_file: + # token from creds file takes the lowest priority + if self.token is None and creds_from_file is not None: self.token = creds_from_file.token self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url From 6097773a6e906798f4b29e12126e106ef1bc07ec Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:50:51 -0400 Subject: [PATCH 09/17] Update logfire/_internal/config.py Co-authored-by: Alex Hall --- logfire/_internal/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 3a935a774..c5520d00c 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -803,7 +803,7 @@ def add_span_processor(span_processor: SpanProcessor) -> None: creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) # token from creds file takes the lowest priority - if self.token is None and creds_from_file is not None: + if not self.token and creds_from_file is not None: self.token = creds_from_file.token self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url From 6f116e4922d2715efabd9a7c15fcc0071c5eee4e Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Fri, 1 Nov 2024 07:54:08 -0400 Subject: [PATCH 10/17] avoid creds check if self.send_to_logfire is False --- logfire/_internal/config.py | 61 +++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index c5520d00c..f535b4541 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -801,35 +801,38 @@ def add_span_processor(span_processor: SpanProcessor) -> None: if isinstance(self.metrics, MetricsOptions): metric_readers = list(self.metrics.additional_readers) - creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) - # token from creds file takes the lowest priority - if not self.token and creds_from_file is not None: - self.token = creds_from_file.token - self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url - - if (self.send_to_logfire == 'if-token-present' and self.token is not None) or self.send_to_logfire is True: - show_project_link = self.console and self.console.show_project_link - - if self.token is None: - credentials = LogfireCredentials.initialize_project( - logfire_api_url=self.advanced.base_url, - session=requests.Session(), - ) - credentials.write_creds_file(self.data_dir) - self.token = credentials.token - self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url - if show_project_link: # pragma: no branch - credentials.print_token_summary() - else: - - def check_token(): - assert self.token is not None - creds = self._initialize_credentials_from_token(self.token) - if show_project_link and creds is not None: # pragma: no branch - creds.print_token_summary() - - thread = Thread(target=check_token, name='check_logfire_token') - thread.start() + if self.send_to_logfire: + creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) + # token from creds file takes the lowest priority + if not self.token and creds_from_file is not None: + self.token = creds_from_file.token + self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url + + if ( + self.send_to_logfire == 'if-token-present' and self.token is not None + ) or self.send_to_logfire is True: + show_project_link = self.console and self.console.show_project_link + + if self.token is None: + credentials = LogfireCredentials.initialize_project( + logfire_api_url=self.advanced.base_url, + session=requests.Session(), + ) + credentials.write_creds_file(self.data_dir) + self.token = credentials.token + self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url + if show_project_link: # pragma: no branch + credentials.print_token_summary() + else: + + def check_token(): + assert self.token is not None + creds = self._initialize_credentials_from_token(self.token) + if show_project_link and creds is not None: # pragma: no branch + creds.print_token_summary() + + thread = Thread(target=check_token, name='check_logfire_token') + thread.start() headers = {'User-Agent': f'logfire/{VERSION}', 'Authorization': self.token} session = OTLPExporterHttpSession(max_body_size=OTLP_MAX_BODY_SIZE) From 24d54c843135da6a94a71663aa860807c12e2cc3 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Mon, 4 Nov 2024 12:57:35 -0500 Subject: [PATCH 11/17] making logical pattern more explicit --- logfire/_internal/config.py | 131 ++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index f535b4541..9b0a6f017 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -802,72 +802,75 @@ def add_span_processor(span_processor: SpanProcessor) -> None: metric_readers = list(self.metrics.additional_readers) if self.send_to_logfire: - creds_from_file = LogfireCredentials.load_creds_file(self.data_dir) - # token from creds file takes the lowest priority - if not self.token and creds_from_file is not None: - self.token = creds_from_file.token - self.advanced.base_url = self.advanced.base_url or creds_from_file.logfire_api_url - - if ( - self.send_to_logfire == 'if-token-present' and self.token is not None - ) or self.send_to_logfire is True: - show_project_link = self.console and self.console.show_project_link - - if self.token is None: - credentials = LogfireCredentials.initialize_project( - logfire_api_url=self.advanced.base_url, - session=requests.Session(), - ) - credentials.write_creds_file(self.data_dir) - self.token = credentials.token - self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url - if show_project_link: # pragma: no branch - credentials.print_token_summary() - else: - - def check_token(): - assert self.token is not None - creds = self._initialize_credentials_from_token(self.token) - if show_project_link and creds is not None: # pragma: no branch - creds.print_token_summary() - - thread = Thread(target=check_token, name='check_logfire_token') - thread.start() - - headers = {'User-Agent': f'logfire/{VERSION}', 'Authorization': self.token} - session = OTLPExporterHttpSession(max_body_size=OTLP_MAX_BODY_SIZE) - session.headers.update(headers) - span_exporter = OTLPSpanExporter( - endpoint=urljoin(self.advanced.base_url, '/v1/traces'), - session=session, - compression=Compression.Gzip, - ) - span_exporter = RetryFewerSpansSpanExporter(span_exporter) - span_exporter = FallbackSpanExporter( - span_exporter, FileSpanExporter(self.data_dir / DEFAULT_FALLBACK_FILE_NAME, warn=True) - ) - span_exporter = RemovePendingSpansExporter(span_exporter) - schedule_delay_millis = _get_int_from_env(OTEL_BSP_SCHEDULE_DELAY) or 500 - add_span_processor(BatchSpanProcessor(span_exporter, schedule_delay_millis=schedule_delay_millis)) - - if metric_readers is not None: - metric_readers += [ - PeriodicExportingMetricReader( - QuietMetricExporter( - OTLPMetricExporter( - endpoint=urljoin(self.advanced.base_url, '/v1/metrics'), - headers=headers, - session=session, - compression=Compression.Gzip, - # I'm pretty sure that this line here is redundant, - # and that passing it to the QuietMetricExporter is what matters - # because the PeriodicExportingMetricReader will read it from there. + credentials: LogfireCredentials | None = None + show_project_link: bool = self.console and self.console.show_project_link or False + + # try loading credentials (and thus token) from file if a token is not already available + # this takes the lowest priority, behind the token passed to `configure` and the environment variable + if self.token is None: + credentials = LogfireCredentials.load_creds_file(self.data_dir) + + # if we still don't have a token, try initializing a new project and writing a new creds file + # note, we only do this if `send_to_logfire` is explicitly `True` + if self.send_to_logfire is True and self.token is None: + credentials = LogfireCredentials.initialize_project( + logfire_api_url=self.advanced.base_url, + session=requests.Session(), + ) + credentials.write_creds_file(self.data_dir) + + if credentials is not None and self.token is None: + self.token = credentials.token + self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url + + if show_project_link and credentials is not None: + credentials.print_token_summary() + + if self.token is not None: + + def check_token(): + assert self.token is not None + creds = self._initialize_credentials_from_token(self.token) + if show_project_link and creds is not None: + creds.print_token_summary() + + thread = Thread(target=check_token, name='check_logfire_token') + thread.start() + + headers = {'User-Agent': f'logfire/{VERSION}', 'Authorization': self.token} + session = OTLPExporterHttpSession(max_body_size=OTLP_MAX_BODY_SIZE) + session.headers.update(headers) + span_exporter = OTLPSpanExporter( + endpoint=urljoin(self.advanced.base_url, '/v1/traces'), + session=session, + compression=Compression.Gzip, + ) + span_exporter = RetryFewerSpansSpanExporter(span_exporter) + span_exporter = FallbackSpanExporter( + span_exporter, FileSpanExporter(self.data_dir / DEFAULT_FALLBACK_FILE_NAME, warn=True) + ) + span_exporter = RemovePendingSpansExporter(span_exporter) + schedule_delay_millis = _get_int_from_env(OTEL_BSP_SCHEDULE_DELAY) or 500 + add_span_processor(BatchSpanProcessor(span_exporter, schedule_delay_millis=schedule_delay_millis)) + + if metric_readers is not None: + metric_readers += [ + PeriodicExportingMetricReader( + QuietMetricExporter( + OTLPMetricExporter( + endpoint=urljoin(self.advanced.base_url, '/v1/metrics'), + headers=headers, + session=session, + compression=Compression.Gzip, + # I'm pretty sure that this line here is redundant, + # and that passing it to the QuietMetricExporter is what matters + # because the PeriodicExportingMetricReader will read it from there. + preferred_temporality=METRICS_PREFERRED_TEMPORALITY, + ), preferred_temporality=METRICS_PREFERRED_TEMPORALITY, - ), - preferred_temporality=METRICS_PREFERRED_TEMPORALITY, + ) ) - ) - ] + ] if processors_with_pending_spans: tracer_provider.add_span_processor( From 15c40f1a4c94ce5ff0ab4490d359c9902a3d4d40 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Mon, 4 Nov 2024 13:44:57 -0500 Subject: [PATCH 12/17] more unconditionally check token --- logfire/_internal/config.py | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index 9b0a6f017..ee5dbf042 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -810,29 +810,26 @@ def add_span_processor(span_processor: SpanProcessor) -> None: if self.token is None: credentials = LogfireCredentials.load_creds_file(self.data_dir) - # if we still don't have a token, try initializing a new project and writing a new creds file - # note, we only do this if `send_to_logfire` is explicitly `True` - if self.send_to_logfire is True and self.token is None: - credentials = LogfireCredentials.initialize_project( - logfire_api_url=self.advanced.base_url, - session=requests.Session(), - ) - credentials.write_creds_file(self.data_dir) - - if credentials is not None and self.token is None: - self.token = credentials.token - self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url + # if we still don't have a token, try initializing a new project and writing a new creds file + # note, we only do this if `send_to_logfire` is explicitly `True` + if self.send_to_logfire is True and credentials is None: + credentials = LogfireCredentials.initialize_project( + logfire_api_url=self.advanced.base_url, + session=requests.Session(), + ) + credentials.write_creds_file(self.data_dir) - if show_project_link and credentials is not None: - credentials.print_token_summary() + if credentials is not None: + self.token = credentials.token + self.advanced.base_url = self.advanced.base_url or credentials.logfire_api_url if self.token is not None: def check_token(): assert self.token is not None - creds = self._initialize_credentials_from_token(self.token) - if show_project_link and creds is not None: - creds.print_token_summary() + validated_credentials = self._initialize_credentials_from_token(self.token) + if show_project_link and validated_credentials is not None: + validated_credentials.print_token_summary() thread = Thread(target=check_token, name='check_logfire_token') thread.start() From 72a07a6031a2644d7290fb1ce0cdcf804d35506a Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Mon, 4 Nov 2024 13:57:06 -0500 Subject: [PATCH 13/17] maybe fixing tests? --- tests/test_configure.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_configure.py b/tests/test_configure.py index e5b7c38bf..5147db1e4 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -902,6 +902,10 @@ def test_initialize_project_use_existing_project_no_projects(tmp_dir_cwd: Path, request_mocker.get( 'https://logfire-api.pydantic.dev/v1/organizations/', json=[{'organization_name': 'fake_org'}] ) + request_mocker.get( + 'https://logfire-api.pydantic.dev/v1/info', + json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + ) create_project_response = { 'json': { 'project_name': 'myproject', @@ -934,6 +938,10 @@ def test_initialize_project_use_existing_project(tmp_dir_cwd: Path, tmp_path: Pa 'https://logfire-api.pydantic.dev/v1/projects/', json=[{'organization_name': 'fake_org', 'project_name': 'fake_project'}], ) + request_mocker.get( + 'https://logfire-api.pydantic.dev/v1/info', + json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + ) create_project_response = { 'json': { 'project_name': 'myproject', @@ -986,6 +994,10 @@ def test_initialize_project_not_using_existing_project( request_mocker.get( 'https://logfire-api.pydantic.dev/v1/organizations/', json=[{'organization_name': 'fake_org'}] ) + request_mocker.get( + 'https://logfire-api.pydantic.dev/v1/info', + json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + ) request_mocker.get( 'https://logfire-api.pydantic.dev/v1/projects/', json=[{'organization_name': 'fake_org', 'project_name': 'fake_project'}], @@ -1078,6 +1090,10 @@ def test_initialize_project_create_project(tmp_dir_cwd: Path, tmp_path: Path, ca request_mocker.get( 'https://logfire-api.pydantic.dev/v1/organizations/', json=[{'organization_name': 'fake_org'}] ) + request_mocker.get( + 'https://logfire-api.pydantic.dev/v1/info', + json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + ) create_existing_project_request_json = { 'project_name': 'existingprojectname', @@ -1186,6 +1202,10 @@ def test_initialize_project_create_project_default_organization(tmp_dir_cwd: Pat 'https://logfire-api.pydantic.dev/v1/organizations/', json=[{'organization_name': 'fake_org'}, {'organization_name': 'fake_org1'}], ) + request_mocker.get( + 'https://logfire-api.pydantic.dev/v1/info', + json={'project_name': 'myproject', 'project_url': 'fake_project_url'}, + ) request_mocker.get( 'https://logfire-api.pydantic.dev/v1/account/me', json={'default_organization': {'organization_name': 'fake_org1'}}, From 68fd5fbd185d5fb510049b662de3875fbeec1877 Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:02:38 -0500 Subject: [PATCH 14/17] Update logfire/_internal/config.py Co-authored-by: Alex Hall --- logfire/_internal/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logfire/_internal/config.py b/logfire/_internal/config.py index ee5dbf042..b79c44133 100644 --- a/logfire/_internal/config.py +++ b/logfire/_internal/config.py @@ -811,7 +811,7 @@ def add_span_processor(span_processor: SpanProcessor) -> None: credentials = LogfireCredentials.load_creds_file(self.data_dir) # if we still don't have a token, try initializing a new project and writing a new creds file - # note, we only do this if `send_to_logfire` is explicitly `True` + # note, we only do this if `send_to_logfire` is explicitly `True`, not 'if-token-present' if self.send_to_logfire is True and credentials is None: credentials = LogfireCredentials.initialize_project( logfire_api_url=self.advanced.base_url, From c02bf766ece7b54cc90db16cbefb7a7106b173a1 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Mon, 4 Nov 2024 15:06:08 -0500 Subject: [PATCH 15/17] tweak test --- tests/test_configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_configure.py b/tests/test_configure.py index 5147db1e4..5cb9032b0 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1139,7 +1139,7 @@ def test_initialize_project_create_project(tmp_dir_cwd: Path, tmp_path: Path, ca logfire.configure(send_to_logfire=True) for request in request_mocker.request_history: - assert request.headers['Authorization'] == 'fake_user_token' + assert request.headers['Authorization'] in ['fake_user_token', 'fake_token'] assert request_mocker.request_history[2].json() == create_existing_project_request_json assert request_mocker.request_history[3].json() == create_reserved_project_request_json From d0c8f2664719933dfbe03577d4414415af77c60f Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Mon, 4 Nov 2024 15:13:47 -0500 Subject: [PATCH 16/17] more helpful test / explanation --- tests/test_configure.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_configure.py b/tests/test_configure.py index 5cb9032b0..8b43a0eb7 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1138,8 +1138,11 @@ def test_initialize_project_create_project(tmp_dir_cwd: Path, tmp_path: Path, ca logfire.configure(send_to_logfire=True) - for request in request_mocker.request_history: - assert request.headers['Authorization'] in ['fake_user_token', 'fake_token'] + for request in request_mocker.request_history[:-1]: + assert request.headers['Authorization'] == 'fake_user_token' + + # we check that fake_token is valid now when we configure the project + assert request_mocker.request_history[-1].headers['Authorization'] == 'fake_token' assert request_mocker.request_history[2].json() == create_existing_project_request_json assert request_mocker.request_history[3].json() == create_reserved_project_request_json From 848b07bb3e483271680ae66e4d9dc69d90abe5e1 Mon Sep 17 00:00:00 2001 From: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:22:54 -0500 Subject: [PATCH 17/17] Update tests/test_configure.py Co-authored-by: Alex Hall --- tests/test_configure.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_configure.py b/tests/test_configure.py index 8b43a0eb7..8d659a0f7 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1142,6 +1142,7 @@ def test_initialize_project_create_project(tmp_dir_cwd: Path, tmp_path: Path, ca assert request.headers['Authorization'] == 'fake_user_token' # we check that fake_token is valid now when we configure the project + wait_for_check_token_thread() assert request_mocker.request_history[-1].headers['Authorization'] == 'fake_token' assert request_mocker.request_history[2].json() == create_existing_project_request_json