external-systems 0.103.0rc3__tar.gz → 0.104.0__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.

Potentially problematic release.


This version of external-systems might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: external-systems
3
- Version: 0.103.0rc3
3
+ Version: 0.104.0
4
4
  Summary: A Python library for interacting with Foundry Sources
5
5
  License: Apache-2.0
6
6
  Keywords: Palantir,Foundry,Sources,Compute Modules,Python Functions,Transforms
@@ -16,4 +16,4 @@
16
16
  # The version is set during the publishing step (since we can't know the version in advance)
17
17
  # using the autorelease bot
18
18
 
19
- __version__ = "0.103.0-rc3"
19
+ __version__ = "0.104.0"
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import os
15
16
  from functools import cache
16
17
  from typing import Any, Mapping, Optional, Union
17
18
 
@@ -25,12 +26,24 @@ class CustomCaBundleSession(Session):
25
26
  A wrapper for requests.Session to override 'verify' property, ignoring REQUESTS_CA_BUNDLE environment variable.
26
27
 
27
28
  This is a workaround for https://github.com/psf/requests/issues/3829 (will be fixed in requests 3.0.0)
29
+
30
+ The standard behavior of requests is to ALWAYS use the REQUESTS_CA_BUNDLE environment variable here if "verify" is not set on
31
+ the request (even if it's set on the session level).
28
32
  """
29
33
 
30
34
  def merge_environment_settings(self, url, proxies, stream, verify, *args, **kwargs): # type: ignore[no-untyped-def]
31
- if isinstance(self.verify, str):
35
+ user_has_manually_overridden_verify = verify is not None
36
+
37
+ # The source certs will not exist, for example, if the client is passed to a spark UDF that runs in a different environment.
38
+ # In this case, the verify path does not exist on the new environment, so we should not try use it and instead default to standard behavior.
39
+ source_certs_exist = isinstance(self.verify, str) and os.path.exists(self.verify)
40
+
41
+ if not user_has_manually_overridden_verify and source_certs_exist:
32
42
  verify = self.verify
33
43
 
44
+ # else (override exists or the source certs do not exist):
45
+ # Use the override. If there is no override (verify=None), then this will default to REQUESTS_CA_BUNDLE.
46
+
34
47
  return super(CustomCaBundleSession, self).merge_environment_settings(
35
48
  url, proxies, stream, verify, *args, **kwargs
36
49
  )
@@ -29,6 +29,7 @@ from ._connections import HttpsConnection
29
29
  from ._proxies import create_proxy_session
30
30
  from ._refreshable import DefaultSessionCredentialsManager, Refreshable, RefreshHandler
31
31
  from ._sockets import create_socket
32
+ from ._utils import read_file
32
33
 
33
34
  log = logging.getLogger(__name__)
34
35
 
@@ -81,43 +82,24 @@ class Source:
81
82
 
82
83
  @cached_property
83
84
  def _ca_bundle_path(self) -> Optional[str]:
84
- """
85
- Returns the path to the CA bundle file with all custom CA certificates defined in the Source.
86
-
87
- Precedence of which CA bundle to use:
88
- 1. Custom CA bundle path (if provided assumes PEM format)
89
- 2. Requests CA bundle path
90
- 3. Temporary file
91
- """
92
-
93
- provided_ca_bundle_path = self._custom_ca_bundle_path or os.environ.get("REQUESTS_CA_BUNDLE")
94
-
95
- if not self._source_parameters.server_certificates:
96
- return provided_ca_bundle_path
97
-
98
- # Certificates from the Source to add to the CA bundle
99
- server_certificates = list(self._source_parameters.server_certificates.values())
85
+ if self._source_parameters.server_certificates is None:
86
+ return None
100
87
 
101
- # If no provided CA bundle path, create a temporary file with only the server certificates
102
- if not provided_ca_bundle_path:
103
- with NamedTemporaryFile(delete=False, mode="w") as ca_bundle_file:
104
- ca_bundle_file.write(os.linesep.join(server_certificates) + os.linesep)
105
- return ca_bundle_file.name
88
+ new_ca_contents = []
106
89
 
107
- # See https://docs.python.org/3/library/os.html#os.access for why we don't use os.access
108
- # First try appending the server certificates to the provided CA bundle path
109
- try:
110
- with open(provided_ca_bundle_path, "a") as provided_ca_bundle_file:
111
- provided_ca_bundle_file.write(os.linesep.join(server_certificates) + os.linesep)
112
- return provided_ca_bundle_path
113
- except PermissionError:
114
- log.warning("PermissionError when writing to provided CA bundle path, falling back to temporary file.")
90
+ # If a custom CA bundle path is provided, use it.
91
+ # Otherwise, use the requests CA bundle path if it is set.
92
+ ca_bundle_path = (
93
+ self._custom_ca_bundle_path
94
+ if self._custom_ca_bundle_path is not None
95
+ else os.environ.get("REQUESTS_CA_BUNDLE")
96
+ )
115
97
 
116
- # Finally, try reading the provided CA bundle path and appending all content to the new CA bundle
117
- new_ca_contents = []
118
- with open(provided_ca_bundle_path) as provided_ca_bundle_file:
119
- new_ca_contents.append(provided_ca_bundle_file.read())
98
+ # Copy the CA bundle contents to the new CA bundle file.
99
+ if ca_bundle_path:
100
+ new_ca_contents.append(read_file(ca_bundle_path))
120
101
 
102
+ # Add all CAs for the source
121
103
  for required_ca in self._source_parameters.server_certificates.values():
122
104
  new_ca_contents.append(required_ca)
123
105
 
@@ -23,3 +23,8 @@ def has_expiration_property(source_credentials: SourceCredentials) -> bool:
23
23
  """
24
24
 
25
25
  return hasattr(source_credentials, "expiration")
26
+
27
+
28
+ def read_file(path: str) -> str:
29
+ with open(path) as file:
30
+ return file.read()
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "external-systems"
3
- version = "0.103.0-rc3"
3
+ version = "0.104.0"
4
4
  description = "A Python library for interacting with Foundry Sources"
5
5
  authors = ["Palantir Technologies, Inc."]
6
6
  license = "Apache-2.0"