chalkpy 2.98.6__py3-none-any.whl → 2.99.1__py3-none-any.whl

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.
chalk/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.98.6"
1
+ __version__ = "2.99.1"
@@ -1033,6 +1033,10 @@ class ChalkAPIClientImpl(ChalkClient):
1033
1033
  self._branch: str | None = branch
1034
1034
  self._skip_token_cache: bool = _skip_cache
1035
1035
  self._api_server: str | None = api_server
1036
+ self._env_id_to_engine_url_map: Mapping[str, str] | None = None
1037
+ self._env_id_to_env_name_map: Mapping[str, str] | None = None
1038
+ self._env_name_to_env_id_map: Mapping[str, str] | None = None
1039
+ self._access_token: str | None = None
1036
1040
 
1037
1041
  self._default_headers = {
1038
1042
  "Accept": "application/json",
@@ -1043,7 +1047,7 @@ class ChalkAPIClientImpl(ChalkClient):
1043
1047
  if additional_headers:
1044
1048
  self._default_headers.update(additional_headers)
1045
1049
 
1046
- self._primary_environment = environment
1050
+ self._primary_environment: EnvironmentId | None = environment
1047
1051
 
1048
1052
  self.__class__.latest_client = self
1049
1053
  if notebook.is_notebook():
@@ -1116,11 +1120,21 @@ class ChalkAPIClientImpl(ChalkClient):
1116
1120
  creds = ExchangeCredentialsResponse(**response_json)
1117
1121
  except ValidationError:
1118
1122
  raise HTTPError(response=resp)
1119
- self._default_headers["Authorization"] = f"Bearer {creds.access_token}"
1123
+
1124
+ self._save_credentials_response(creds)
1125
+
1120
1126
  # FIXME: We should NOT be using the X-Chalk-Client-Id for anything, as it is NOT authenticated
1121
1127
  self._default_headers["X-Chalk-Client-Id"] = self._client_id
1128
+
1129
+ def _save_credentials_response(self, creds: ExchangeCredentialsResponse):
1130
+ self._access_token = creds.access_token
1131
+ self._default_headers["Authorization"] = f"Bearer {creds.access_token}"
1122
1132
  if self._primary_environment is None:
1123
1133
  self._primary_environment = creds.primary_environment
1134
+ self._env_id_to_engine_url_map = creds.engines
1135
+ self._env_id_to_env_name_map = creds.environment_id_to_name
1136
+ if self._env_id_to_env_name_map is not None:
1137
+ self._env_name_to_env_id_map = {v: k for k, v in self._env_id_to_env_name_map.items()}
1124
1138
 
1125
1139
  def _get_headers(
1126
1140
  self,
@@ -1383,6 +1397,53 @@ https://docs.chalk.ai/docs/debugging-queries#resolver-replay
1383
1397
  method=method, headers=headers, url=url, json=json_body, data=data, timeout=timeout_value
1384
1398
  )
1385
1399
 
1400
+ def _get_engine_host(self, environment_override: Optional[str]) -> str | None:
1401
+ """
1402
+ Returns the host to use for data-plane requests to the engine. May fall back to
1403
+ the metadata plane api server host if no engine host can be determined.
1404
+ :param environment_override: Optional user-provided environment name or id.
1405
+ :return: Host for direct engine (data-plane) requests
1406
+ """
1407
+
1408
+ # always respect user-provided query_server override
1409
+ if self._query_server is not None:
1410
+ return self._query_server
1411
+
1412
+ # if we have no environment information, we likely have not done creds exchange yet.
1413
+ # there's no way to determine an engine host here, so just fall back to api server
1414
+ env_id_or_name: str | None = environment_override or self._primary_environment
1415
+ if env_id_or_name is None:
1416
+ return self._api_server
1417
+
1418
+ # get the correct engine url given a valid env id or env name
1419
+ if self._env_id_to_engine_url_map is not None:
1420
+ if env_id_or_name in self._env_id_to_engine_url_map:
1421
+ return self._env_id_to_engine_url_map[env_id_or_name]
1422
+ elif self._env_name_to_env_id_map is not None and env_id_or_name in self._env_name_to_env_id_map:
1423
+ env_id = self._env_name_to_env_id_map[env_id_or_name]
1424
+ return self._env_id_to_engine_url_map.get(env_id, self._api_server)
1425
+
1426
+ # env name or id is invalid, or we failed to auth, so fall back to api server
1427
+ return self._api_server
1428
+
1429
+ def _get_request_host(self, metadata_request: bool, environment_override: Optional[str]) -> str:
1430
+ """
1431
+ Returns the hostname to use for any requests made by the Chalk Client, whether they are
1432
+ metadata-plane-only requests or data-plane requests (to the engine).
1433
+ :param metadata_request: Is this a metadata-plane-only request? If so, we always use the API server.
1434
+ :param environment_override: Optional user-provided environment name or id.
1435
+ :return: Host to use for any request made by the Chalk Client
1436
+ """
1437
+ if metadata_request:
1438
+ host = self._api_server
1439
+ else:
1440
+ host = self._get_engine_host(environment_override)
1441
+
1442
+ return host or "https://api.chalk.ai"
1443
+
1444
+ def _has_authorization_header(self) -> bool:
1445
+ return "Authorization" in self._default_headers or "authorization" in self._default_headers
1446
+
1386
1447
  def _request(
1387
1448
  self,
1388
1449
  method: str,
@@ -1399,25 +1460,18 @@ https://docs.chalk.ai/docs/debugging-queries#resolver-replay
1399
1460
  timeout: float | None | ellipsis = ...,
1400
1461
  connect_timeout: float | None | ellipsis = ...,
1401
1462
  ) -> T | requests.Response:
1463
+ # If we don't have an access token, we cannot make a request.
1464
+ # Always fetch an access token if we do not have one before making a request.
1465
+ # If we fetched an access token during this call and we get 401/403 on this request,
1466
+ # then do not retry the credential exchange again.
1467
+ # Additional Note: if the user has explicitly provided an Authorization header, we should
1468
+ # not attempt to exchange credentials, as they are explicitly managing auth themselves.
1402
1469
  allow_credential_exchange: bool = True
1403
-
1404
- if metadata_request or self._query_server is None:
1405
- host = self._api_server
1406
- else:
1407
- host = self._query_server
1408
-
1409
- if host is None:
1410
- # We definitively need to exchange credentials to get a host
1470
+ if self._access_token is None and not self._has_authorization_header():
1411
1471
  self._exchange_credentials()
1412
1472
  allow_credential_exchange = False
1413
1473
 
1414
- # After exchanging credentials, the api server is never none
1415
- assert self._api_server is not None
1416
-
1417
- if metadata_request or self._query_server is None:
1418
- host = self._api_server
1419
- else:
1420
- host = self._query_server
1474
+ host = self._get_request_host(metadata_request, environment_override)
1421
1475
 
1422
1476
  r = self._do_request_inner(
1423
1477
  method=method,
@@ -1438,14 +1492,7 @@ https://docs.chalk.ai/docs/debugging-queries#resolver-replay
1438
1492
  # It is possible that credentials expired, or that we changed permissions since we last
1439
1493
  # got a token. Exchange them and try again
1440
1494
  self._exchange_credentials()
1441
-
1442
- # After exchanging credentials, the api server is never null
1443
- assert self._api_server is not None
1444
-
1445
- if metadata_request or self._query_server is None:
1446
- host = self._api_server
1447
- else:
1448
- host = self._query_server
1495
+ host = self._get_request_host(metadata_request, environment_override)
1449
1496
 
1450
1497
  r = self._do_request_inner(
1451
1498
  method=method,
@@ -3987,9 +4034,8 @@ https://docs.chalk.ai/cli/apply
3987
4034
  environment_override=context.environment,
3988
4035
  preview_deployment_id=preview_deployment_id,
3989
4036
  branch=branch,
3990
- # If using multiple computers, then we must route through the metadata server
3991
- # So we can actually spin up multiple pods
3992
- metadata_request=request.use_multiple_computers,
4037
+ # all offline query requests should be routed through api server
4038
+ metadata_request=True,
3993
4039
  )
3994
4040
  return response
3995
4041
 
@@ -4065,19 +4111,6 @@ https://docs.chalk.ai/cli/apply
4065
4111
  branch=None,
4066
4112
  )
4067
4113
 
4068
- def _get_query_inputs(
4069
- self, job_id: uuid.UUID, environment: Optional[EnvironmentId], branch: Optional[BranchId]
4070
- ) -> GetOfflineQueryJobResponse:
4071
- return self._request(
4072
- method="GET",
4073
- uri=f"/v2/offline_query_inputs/{job_id}",
4074
- response=GetOfflineQueryJobResponse,
4075
- environment_override=environment,
4076
- json=None,
4077
- preview_deployment_id=None,
4078
- branch=branch,
4079
- )
4080
-
4081
4114
  def _get_dataset_from_name_or_id(
4082
4115
  self,
4083
4116
  *,
chalk/client/models.py CHANGED
@@ -454,6 +454,8 @@ class ExchangeCredentialsResponse(BaseModel):
454
454
  api_server: str
455
455
  primary_environment: Optional[str] = None
456
456
  engines: Optional[Mapping[str, str]] = None
457
+ grpc_engines: Optional[Mapping[str, str]] = None
458
+ environment_id_to_name: Optional[Mapping[str, str]] = None
457
459
 
458
460
 
459
461
  class OfflineQueryInput(BaseModel):
@@ -4541,7 +4541,14 @@ def validate_underscore_expression(
4541
4541
  name: str,
4542
4542
  ) -> None:
4543
4543
  """Main entry point for validating a single underscore expression."""
4544
- from chalk.features.underscore import Underscore, UnderscoreAttr, UnderscoreCall, UnderscoreCast, UnderscoreFunction
4544
+ from chalk.features.underscore import (
4545
+ Underscore,
4546
+ UnderscoreAttr,
4547
+ UnderscoreCall,
4548
+ UnderscoreCast,
4549
+ UnderscoreFunction,
4550
+ UnderscoreRoot,
4551
+ )
4545
4552
 
4546
4553
  # First validate it's an underscore
4547
4554
  if not isinstance(expression, Underscore): # pyright: ignore[reportUnnecessaryIsInstance]
@@ -4562,6 +4569,8 @@ def validate_underscore_expression(
4562
4569
  validate_underscore_call(expression, message_type, error_builder, name)
4563
4570
  elif isinstance(expression, UnderscoreCast):
4564
4571
  validate_underscore_cast(expression, message_type, error_builder, name)
4572
+ elif isinstance(expression, UnderscoreRoot):
4573
+ pass
4565
4574
  else:
4566
4575
  # Catch-all for any other underscore types
4567
4576
  error_builder.add_diagnostic(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chalkpy
3
- Version: 2.98.6
3
+ Version: 2.99.1
4
4
  Summary: Python SDK for Chalk
5
5
  Author: Chalk AI, Inc.
6
6
  Project-URL: Homepage, https://chalk.ai
@@ -1,5 +1,5 @@
1
1
  chalk/__init__.py,sha256=vKsx9-cl5kImlVWGHVRYO6bweBm79NAzGs3l36u71wM,2657
2
- chalk/_version.py,sha256=lCU8-hElWBDbqghv9vMcFvFH7YnIyamLkmO8KLLgp4g,23
2
+ chalk/_version.py,sha256=veq7UDoQd0z2ACc6n5r66tpMpzpZd-wj3jbKxjfT1KQ,23
3
3
  chalk/cli.py,sha256=ckqqfOI-A2mT23-rnZzDMmblYj-2x1VBX8ebHlIEn9A,5873
4
4
  chalk/importer.py,sha256=m4lMn1lSYj_euDq8CS7LYTBnek9JOcjGJf9-82dJHbA,64441
5
5
  chalk/prompts.py,sha256=2H9UomLAamdfRTNUdKs9i3VTpiossuyRhntqsAXUhhg,16117
@@ -616,10 +616,10 @@ chalk/client/client.py,sha256=VfaLfbWyk-VaImPLNrNeAP4FvuJwQ5yEtJrkLST_-H4,104808
616
616
  chalk/client/client_async.py,sha256=YmuExumlDkenlGc8ROtmPjUE2m6nQUZisUDvJmwTRdk,51546
617
617
  chalk/client/client_async_impl.py,sha256=ZphhgTB49JBWHCGXe-dI0wWWKc9zPcOczy02q_gFy50,6925
618
618
  chalk/client/client_grpc.py,sha256=z1WeFWjmKKCU8dK7fdvWEOsCUlBi-v_2-HijC2_oIVs,108854
619
- chalk/client/client_impl.py,sha256=L0qE7Gr5MTMv71lg7-HkoPS672eERGVsfu8FObM_ZyQ,213759
619
+ chalk/client/client_impl.py,sha256=Izb7a1sOLLI3vK8_Mi51iPZc5kmaqPxAhbqjHvzRF90,216305
620
620
  chalk/client/dataset.py,sha256=LneWwaAOHCjtj7gaJjsSeVNruj-QJ51hjRi62zrFNVE,77561
621
621
  chalk/client/exc.py,sha256=kZJ80YbSeSRDmTLTh240j_eRdJFZBa7IaDsNSRoDroU,4145
622
- chalk/client/models.py,sha256=TWiRHDMP_9NUqlCAGaw2RI2UlFI5ED1BCBM1rZRK72k,67482
622
+ chalk/client/models.py,sha256=ApXv28A44dNXUULKFkG5L6e48vDscZyFGenaXItxL94,67598
623
623
  chalk/client/response.py,sha256=m8sQCOj7YVv3mZSZMIC1rIMzFMQ9rfMdBRLg5NRmOOE,53257
624
624
  chalk/client/_internal_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
625
625
  chalk/client/_internal_models/check.py,sha256=3Xfo4Ws4rvwjeVg0-5-kejfRfRBJeqHmnRhW-WEz784,917
@@ -660,7 +660,7 @@ chalk/features/live_updates.py,sha256=8ZbiDjcLqfFruSL15_aycwzSqJ0TbKNhas06KfZLyL
660
660
  chalk/features/namespace_context.py,sha256=fL-nPohqtNiyPDS1uQTAaHLns4aivuBL2Flf50DajU4,1813
661
661
  chalk/features/primary.py,sha256=BZ8mrMmKfRNy_wnKGDJt2cdnejP_CZb6xBsD9Ljgajc,5209
662
662
  chalk/features/pseudofeatures.py,sha256=50Pe_Xi8ttYWtgNNRpgkhBxP8xoCZCYwyLb0aWUQ-PI,2147
663
- chalk/features/resolver.py,sha256=Et-cngxAjqbstJC5lBD3AhMwzXvUjQ6Tj8FnnW5bACU,193610
663
+ chalk/features/resolver.py,sha256=-VU7027xob5StsHC4_UlR1AhH_uxcW_jiwznKHHIMNw,193745
664
664
  chalk/features/tag.py,sha256=LRmKRA8ANCOvmaIAk-L5j1QW2U0aah2SeASy8Uydkmk,2675
665
665
  chalk/features/underscore.py,sha256=4xnfQV3bfvVn0PNEtkT4J-k7hW4ebtH9KBe4_BvGjY4,26763
666
666
  chalk/features/underscore_features.py,sha256=PlVCoaDDffOgtiSMaxPSWCoj8IjscbkOzDLA471HsJ4,13005
@@ -827,8 +827,8 @@ chalk/utils/tracing.py,sha256=NiiM-9dbuJhSCv6R1npR1uYNKWlkqTR6Ygm0Voi2NrY,13078
827
827
  chalk/utils/weak_set_by_identity.py,sha256=VmikA_laYwFeOphCwXJIuyOIkrdlQe0bSzaXq7onoQw,953
828
828
  chalk/utils/pydanticutil/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
829
829
  chalk/utils/pydanticutil/pydantic_compat.py,sha256=O575lLYJ5GvZC4HMzR9yATxf9XwjC6NrDUXbNwZidlE,3031
830
- chalkpy-2.98.6.dist-info/METADATA,sha256=_FtE0_mtvo_reEoEYa0_LgLU4Dn5-3vO0Y20jvu-4sU,27754
831
- chalkpy-2.98.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
832
- chalkpy-2.98.6.dist-info/entry_points.txt,sha256=Vg23sd8icwq-morJrljVFr-kQnMbm95rZfZj5wsZGis,42
833
- chalkpy-2.98.6.dist-info/top_level.txt,sha256=1Q6_19IGYfNxSw50W8tYKEJ2t5HKQ3W9Wiw4ia5yg2c,6
834
- chalkpy-2.98.6.dist-info/RECORD,,
830
+ chalkpy-2.99.1.dist-info/METADATA,sha256=0h_o7NzQ0REbB61J16f_NpXpes2lu_0S-trfMzb5ZdQ,27754
831
+ chalkpy-2.99.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
832
+ chalkpy-2.99.1.dist-info/entry_points.txt,sha256=Vg23sd8icwq-morJrljVFr-kQnMbm95rZfZj5wsZGis,42
833
+ chalkpy-2.99.1.dist-info/top_level.txt,sha256=1Q6_19IGYfNxSw50W8tYKEJ2t5HKQ3W9Wiw4ia5yg2c,6
834
+ chalkpy-2.99.1.dist-info/RECORD,,