@@ -158,7 +158,7 @@ class ConsoleOptions:
158
158
class AdvancedOptions :
159
159
"""Options primarily used for testing by Logfire developers."""
160
160
161
- base_url : str = 'https://logfire-api.pydantic.dev'
161
+ base_url : str | None = None
162
162
"""Root URL for the Logfire API."""
163
163
164
164
id_generator : IdGenerator = dataclasses .field (default_factory = lambda : SeededRandomIdGenerator (None ))
@@ -173,6 +173,19 @@ class AdvancedOptions:
173
173
log_record_processors : Sequence [LogRecordProcessor ] = ()
174
174
"""Configuration for OpenTelemetry logging. This is experimental and may be removed."""
175
175
176
+ def generate_base_url (self , token : str | None ) -> str :
177
+ if token and '-' in token :
178
+ region , _ = token .split ('-' , maxsplit = 1 )
179
+ else :
180
+ region = None
181
+ if self .base_url is not None :
182
+ return self .base_url
183
+ if region :
184
+ return f'https://api-{ region } .pydantic.dev'
185
+ else :
186
+ # default to us region for tokens that were created before regions were added
187
+ return 'https://logfire-api.pydantic.dev'
188
+
176
189
177
190
@dataclass
178
191
class PydanticPlugin :
@@ -864,7 +877,9 @@ def add_span_processor(span_processor: SpanProcessor) -> None:
864
877
# note, we only do this if `send_to_logfire` is explicitly `True`, not 'if-token-present'
865
878
if self .send_to_logfire is True and credentials is None :
866
879
credentials = LogfireCredentials .initialize_project (
867
- logfire_api_url = self .advanced .base_url ,
880
+ # TODO: what happens here? Seems like we need to assume a region to create the new project?
881
+ # Should the SDK have the region from when the user logged in to the SDK?
882
+ logfire_api_url = self .advanced .generate_base_url (None ),
868
883
session = requests .Session (),
869
884
)
870
885
credentials .write_creds_file (self .data_dir )
@@ -891,7 +906,7 @@ def check_token():
891
906
session = OTLPExporterHttpSession (max_body_size = OTLP_MAX_BODY_SIZE )
892
907
session .headers .update (headers )
893
908
span_exporter = OTLPSpanExporter (
894
- endpoint = urljoin (self .advanced .base_url , '/v1/traces' ),
909
+ endpoint = urljoin (self .advanced .generate_base_url ( self . token ) , '/v1/traces' ),
895
910
session = session ,
896
911
compression = Compression .Gzip ,
897
912
)
@@ -915,7 +930,7 @@ def check_token():
915
930
PeriodicExportingMetricReader (
916
931
QuietMetricExporter (
917
932
OTLPMetricExporter (
918
- endpoint = urljoin (self .advanced .base_url , '/v1/metrics' ),
933
+ endpoint = urljoin (self .advanced .generate_base_url ( self . token ) , '/v1/metrics' ),
919
934
headers = headers ,
920
935
session = session ,
921
936
compression = Compression .Gzip ,
@@ -930,7 +945,7 @@ def check_token():
930
945
)
931
946
932
947
log_exporter = OTLPLogExporter (
933
- endpoint = urljoin (self .advanced .base_url , '/v1/logs' ),
948
+ endpoint = urljoin (self .advanced .generate_base_url ( self . token ) , '/v1/logs' ),
934
949
session = session ,
935
950
compression = Compression .Gzip ,
936
951
)
@@ -1151,7 +1166,7 @@ def warn_if_not_initialized(self, message: str):
1151
1166
)
1152
1167
1153
1168
def _initialize_credentials_from_token (self , token : str ) -> LogfireCredentials | None :
1154
- return LogfireCredentials .from_token (token , requests .Session (), self .advanced .base_url )
1169
+ return LogfireCredentials .from_token (token , requests .Session (), self .advanced .generate_base_url ( token ) )
1155
1170
1156
1171
def _ensure_flush_after_aws_lambda (self ):
1157
1172
"""Ensure that `force_flush` is called after an AWS Lambda invocation.
0 commit comments