polars-runtime-compat 1.34.0b2__cp39-abi3-win_amd64.whl → 1.34.0b4__cp39-abi3-win_amd64.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.
Potentially problematic release.
This version of polars-runtime-compat might be problematic. Click here for more details.
- _polars_runtime_compat/_polars_runtime_compat.pyd +0 -0
- {polars_runtime_compat-1.34.0b2.dist-info → polars_runtime_compat-1.34.0b4.dist-info}/METADATA +1 -1
- polars_runtime_compat-1.34.0b4.dist-info/RECORD +6 -0
- polars/__init__.py +0 -528
- polars/_cpu_check.py +0 -265
- polars/_dependencies.py +0 -355
- polars/_plr.py +0 -99
- polars/_plr.pyi +0 -2496
- polars/_reexport.py +0 -23
- polars/_typing.py +0 -478
- polars/_utils/__init__.py +0 -37
- polars/_utils/async_.py +0 -102
- polars/_utils/cache.py +0 -176
- polars/_utils/cloud.py +0 -40
- polars/_utils/constants.py +0 -29
- polars/_utils/construction/__init__.py +0 -46
- polars/_utils/construction/dataframe.py +0 -1397
- polars/_utils/construction/other.py +0 -72
- polars/_utils/construction/series.py +0 -560
- polars/_utils/construction/utils.py +0 -118
- polars/_utils/convert.py +0 -224
- polars/_utils/deprecation.py +0 -406
- polars/_utils/getitem.py +0 -457
- polars/_utils/logging.py +0 -11
- polars/_utils/nest_asyncio.py +0 -264
- polars/_utils/parquet.py +0 -15
- polars/_utils/parse/__init__.py +0 -12
- polars/_utils/parse/expr.py +0 -242
- polars/_utils/polars_version.py +0 -19
- polars/_utils/pycapsule.py +0 -53
- polars/_utils/scan.py +0 -27
- polars/_utils/serde.py +0 -63
- polars/_utils/slice.py +0 -215
- polars/_utils/udfs.py +0 -1251
- polars/_utils/unstable.py +0 -63
- polars/_utils/various.py +0 -782
- polars/_utils/wrap.py +0 -25
- polars/api.py +0 -370
- polars/catalog/__init__.py +0 -0
- polars/catalog/unity/__init__.py +0 -19
- polars/catalog/unity/client.py +0 -733
- polars/catalog/unity/models.py +0 -152
- polars/config.py +0 -1571
- polars/convert/__init__.py +0 -25
- polars/convert/general.py +0 -1046
- polars/convert/normalize.py +0 -261
- polars/dataframe/__init__.py +0 -5
- polars/dataframe/_html.py +0 -186
- polars/dataframe/frame.py +0 -12582
- polars/dataframe/group_by.py +0 -1067
- polars/dataframe/plotting.py +0 -257
- polars/datatype_expr/__init__.py +0 -5
- polars/datatype_expr/array.py +0 -56
- polars/datatype_expr/datatype_expr.py +0 -304
- polars/datatype_expr/list.py +0 -18
- polars/datatype_expr/struct.py +0 -69
- polars/datatypes/__init__.py +0 -122
- polars/datatypes/_parse.py +0 -195
- polars/datatypes/_utils.py +0 -48
- polars/datatypes/classes.py +0 -1213
- polars/datatypes/constants.py +0 -11
- polars/datatypes/constructor.py +0 -172
- polars/datatypes/convert.py +0 -366
- polars/datatypes/group.py +0 -130
- polars/exceptions.py +0 -230
- polars/expr/__init__.py +0 -7
- polars/expr/array.py +0 -964
- polars/expr/binary.py +0 -346
- polars/expr/categorical.py +0 -306
- polars/expr/datetime.py +0 -2620
- polars/expr/expr.py +0 -11272
- polars/expr/list.py +0 -1408
- polars/expr/meta.py +0 -444
- polars/expr/name.py +0 -321
- polars/expr/string.py +0 -3045
- polars/expr/struct.py +0 -357
- polars/expr/whenthen.py +0 -185
- polars/functions/__init__.py +0 -193
- polars/functions/aggregation/__init__.py +0 -33
- polars/functions/aggregation/horizontal.py +0 -298
- polars/functions/aggregation/vertical.py +0 -341
- polars/functions/as_datatype.py +0 -848
- polars/functions/business.py +0 -138
- polars/functions/col.py +0 -384
- polars/functions/datatype.py +0 -121
- polars/functions/eager.py +0 -524
- polars/functions/escape_regex.py +0 -29
- polars/functions/lazy.py +0 -2751
- polars/functions/len.py +0 -68
- polars/functions/lit.py +0 -210
- polars/functions/random.py +0 -22
- polars/functions/range/__init__.py +0 -19
- polars/functions/range/_utils.py +0 -15
- polars/functions/range/date_range.py +0 -303
- polars/functions/range/datetime_range.py +0 -370
- polars/functions/range/int_range.py +0 -348
- polars/functions/range/linear_space.py +0 -311
- polars/functions/range/time_range.py +0 -287
- polars/functions/repeat.py +0 -301
- polars/functions/whenthen.py +0 -353
- polars/interchange/__init__.py +0 -10
- polars/interchange/buffer.py +0 -77
- polars/interchange/column.py +0 -190
- polars/interchange/dataframe.py +0 -230
- polars/interchange/from_dataframe.py +0 -328
- polars/interchange/protocol.py +0 -303
- polars/interchange/utils.py +0 -170
- polars/io/__init__.py +0 -64
- polars/io/_utils.py +0 -317
- polars/io/avro.py +0 -49
- polars/io/clipboard.py +0 -36
- polars/io/cloud/__init__.py +0 -17
- polars/io/cloud/_utils.py +0 -80
- polars/io/cloud/credential_provider/__init__.py +0 -17
- polars/io/cloud/credential_provider/_builder.py +0 -520
- polars/io/cloud/credential_provider/_providers.py +0 -618
- polars/io/csv/__init__.py +0 -9
- polars/io/csv/_utils.py +0 -38
- polars/io/csv/batched_reader.py +0 -142
- polars/io/csv/functions.py +0 -1495
- polars/io/database/__init__.py +0 -6
- polars/io/database/_arrow_registry.py +0 -70
- polars/io/database/_cursor_proxies.py +0 -147
- polars/io/database/_executor.py +0 -578
- polars/io/database/_inference.py +0 -314
- polars/io/database/_utils.py +0 -144
- polars/io/database/functions.py +0 -516
- polars/io/delta.py +0 -499
- polars/io/iceberg/__init__.py +0 -3
- polars/io/iceberg/_utils.py +0 -697
- polars/io/iceberg/dataset.py +0 -556
- polars/io/iceberg/functions.py +0 -151
- polars/io/ipc/__init__.py +0 -8
- polars/io/ipc/functions.py +0 -514
- polars/io/json/__init__.py +0 -3
- polars/io/json/read.py +0 -101
- polars/io/ndjson.py +0 -332
- polars/io/parquet/__init__.py +0 -17
- polars/io/parquet/field_overwrites.py +0 -140
- polars/io/parquet/functions.py +0 -722
- polars/io/partition.py +0 -491
- polars/io/plugins.py +0 -187
- polars/io/pyarrow_dataset/__init__.py +0 -5
- polars/io/pyarrow_dataset/anonymous_scan.py +0 -109
- polars/io/pyarrow_dataset/functions.py +0 -79
- polars/io/scan_options/__init__.py +0 -5
- polars/io/scan_options/_options.py +0 -59
- polars/io/scan_options/cast_options.py +0 -126
- polars/io/spreadsheet/__init__.py +0 -6
- polars/io/spreadsheet/_utils.py +0 -52
- polars/io/spreadsheet/_write_utils.py +0 -647
- polars/io/spreadsheet/functions.py +0 -1323
- polars/lazyframe/__init__.py +0 -9
- polars/lazyframe/engine_config.py +0 -61
- polars/lazyframe/frame.py +0 -8564
- polars/lazyframe/group_by.py +0 -669
- polars/lazyframe/in_process.py +0 -42
- polars/lazyframe/opt_flags.py +0 -333
- polars/meta/__init__.py +0 -14
- polars/meta/build.py +0 -33
- polars/meta/index_type.py +0 -27
- polars/meta/thread_pool.py +0 -50
- polars/meta/versions.py +0 -120
- polars/ml/__init__.py +0 -0
- polars/ml/torch.py +0 -213
- polars/ml/utilities.py +0 -30
- polars/plugins.py +0 -155
- polars/py.typed +0 -0
- polars/pyproject.toml +0 -96
- polars/schema.py +0 -265
- polars/selectors.py +0 -3117
- polars/series/__init__.py +0 -5
- polars/series/array.py +0 -776
- polars/series/binary.py +0 -254
- polars/series/categorical.py +0 -246
- polars/series/datetime.py +0 -2275
- polars/series/list.py +0 -1087
- polars/series/plotting.py +0 -191
- polars/series/series.py +0 -9197
- polars/series/string.py +0 -2367
- polars/series/struct.py +0 -154
- polars/series/utils.py +0 -191
- polars/sql/__init__.py +0 -7
- polars/sql/context.py +0 -677
- polars/sql/functions.py +0 -139
- polars/string_cache.py +0 -185
- polars/testing/__init__.py +0 -13
- polars/testing/asserts/__init__.py +0 -9
- polars/testing/asserts/frame.py +0 -231
- polars/testing/asserts/series.py +0 -219
- polars/testing/asserts/utils.py +0 -12
- polars/testing/parametric/__init__.py +0 -33
- polars/testing/parametric/profiles.py +0 -107
- polars/testing/parametric/strategies/__init__.py +0 -22
- polars/testing/parametric/strategies/_utils.py +0 -14
- polars/testing/parametric/strategies/core.py +0 -615
- polars/testing/parametric/strategies/data.py +0 -452
- polars/testing/parametric/strategies/dtype.py +0 -436
- polars/testing/parametric/strategies/legacy.py +0 -169
- polars/type_aliases.py +0 -24
- polars_runtime_compat-1.34.0b2.dist-info/RECORD +0 -203
- {polars_runtime_compat-1.34.0b2.dist-info → polars_runtime_compat-1.34.0b4.dist-info}/WHEEL +0 -0
- {polars_runtime_compat-1.34.0b2.dist-info → polars_runtime_compat-1.34.0b4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import abc
|
|
4
|
-
import importlib.util
|
|
5
|
-
import json
|
|
6
|
-
import os
|
|
7
|
-
import subprocess
|
|
8
|
-
import sys
|
|
9
|
-
import zoneinfo
|
|
10
|
-
from datetime import datetime
|
|
11
|
-
from functools import partial
|
|
12
|
-
from typing import (
|
|
13
|
-
TYPE_CHECKING,
|
|
14
|
-
Any,
|
|
15
|
-
Callable,
|
|
16
|
-
Optional,
|
|
17
|
-
TypedDict,
|
|
18
|
-
Union,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
import polars._utils.logging
|
|
22
|
-
from polars._utils.logging import eprint, verbose
|
|
23
|
-
from polars.io.cloud._utils import NoPickleOption
|
|
24
|
-
|
|
25
|
-
if TYPE_CHECKING:
|
|
26
|
-
from polars._dependencies import boto3
|
|
27
|
-
|
|
28
|
-
if sys.version_info >= (3, 10):
|
|
29
|
-
from typing import TypeAlias
|
|
30
|
-
else:
|
|
31
|
-
from typing_extensions import TypeAlias
|
|
32
|
-
|
|
33
|
-
from polars._utils.unstable import issue_unstable_warning
|
|
34
|
-
|
|
35
|
-
# These typedefs are here to avoid circular import issues, as
|
|
36
|
-
# `CredentialProviderFunction` specifies "CredentialProvider"
|
|
37
|
-
CredentialProviderFunctionReturn: TypeAlias = tuple[dict[str, str], Optional[int]]
|
|
38
|
-
|
|
39
|
-
CredentialProviderFunction: TypeAlias = Union[
|
|
40
|
-
Callable[[], CredentialProviderFunctionReturn], "CredentialProvider"
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class AWSAssumeRoleKWArgs(TypedDict):
|
|
45
|
-
"""Parameters for [STS.Client.assume_role()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts/client/assume_role.html#STS.Client.assume_role)."""
|
|
46
|
-
|
|
47
|
-
RoleArn: str
|
|
48
|
-
RoleSessionName: str
|
|
49
|
-
PolicyArns: list[dict[str, str]]
|
|
50
|
-
Policy: str
|
|
51
|
-
DurationSeconds: int
|
|
52
|
-
Tags: list[dict[str, str]]
|
|
53
|
-
TransitiveTagKeys: list[str]
|
|
54
|
-
ExternalId: str
|
|
55
|
-
SerialNumber: str
|
|
56
|
-
TokenCode: str
|
|
57
|
-
SourceIdentity: str
|
|
58
|
-
ProvidedContexts: list[dict[str, str]]
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class CredentialProvider(abc.ABC):
|
|
62
|
-
"""
|
|
63
|
-
Base class for credential providers.
|
|
64
|
-
|
|
65
|
-
.. warning::
|
|
66
|
-
This functionality is considered **unstable**. It may be changed
|
|
67
|
-
at any point without it being considered a breaking change.
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
@abc.abstractmethod
|
|
71
|
-
def __call__(self) -> CredentialProviderFunctionReturn:
|
|
72
|
-
"""Fetches the credentials."""
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class CachingCredentialProvider(CredentialProvider, abc.ABC):
|
|
76
|
-
"""
|
|
77
|
-
Base class for credential providers that has built-in caching.
|
|
78
|
-
|
|
79
|
-
.. warning::
|
|
80
|
-
This functionality is considered **unstable**. It may be changed
|
|
81
|
-
at any point without it being considered a breaking change.
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
def __init__(self) -> None:
|
|
85
|
-
self._cached_credentials: NoPickleOption[CredentialProviderFunctionReturn] = (
|
|
86
|
-
NoPickleOption()
|
|
87
|
-
)
|
|
88
|
-
self._has_logged_use_cache = False
|
|
89
|
-
|
|
90
|
-
def __call__(self) -> CredentialProviderFunctionReturn:
|
|
91
|
-
if os.getenv("POLARS_DISABLE_PYTHON_CREDENTIAL_CACHING") == "1":
|
|
92
|
-
self._cached_credentials.set(None)
|
|
93
|
-
|
|
94
|
-
return self.retrieve_credentials_impl()
|
|
95
|
-
|
|
96
|
-
credentials = self._cached_credentials.get()
|
|
97
|
-
|
|
98
|
-
if credentials is None or (
|
|
99
|
-
(expiry := credentials[1]) is not None
|
|
100
|
-
and expiry <= int(datetime.now().timestamp())
|
|
101
|
-
):
|
|
102
|
-
credentials = self.retrieve_credentials_impl()
|
|
103
|
-
self._cached_credentials.set(credentials)
|
|
104
|
-
self._has_logged_use_cache = False
|
|
105
|
-
|
|
106
|
-
elif verbose() and not self._has_logged_use_cache:
|
|
107
|
-
expiry = credentials[1]
|
|
108
|
-
eprint(
|
|
109
|
-
f"[{CachingCredentialProvider.__repr__(self)}]: "
|
|
110
|
-
f"Using cached credentials ({expiry = })"
|
|
111
|
-
)
|
|
112
|
-
self._has_logged_use_cache = True
|
|
113
|
-
|
|
114
|
-
creds, expiry = credentials
|
|
115
|
-
|
|
116
|
-
return {**creds}, expiry
|
|
117
|
-
|
|
118
|
-
@abc.abstractmethod
|
|
119
|
-
def retrieve_credentials_impl(self) -> CredentialProviderFunctionReturn: ...
|
|
120
|
-
|
|
121
|
-
def clear_cached_credentials(self) -> None:
|
|
122
|
-
self._cached_credentials.set(None)
|
|
123
|
-
|
|
124
|
-
def __repr__(self) -> str:
|
|
125
|
-
return f"CachingCredentialProvider[{type(self).__name__} @ {hex(id(self))}]"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
class CachedCredentialProvider(CachingCredentialProvider):
|
|
129
|
-
"""
|
|
130
|
-
Wrapper that adds caching on top of a credential provider.
|
|
131
|
-
|
|
132
|
-
.. warning::
|
|
133
|
-
This functionality is considered **unstable**. It may be changed
|
|
134
|
-
at any point without it being considered a breaking change.
|
|
135
|
-
"""
|
|
136
|
-
|
|
137
|
-
def __init__(
|
|
138
|
-
self, provider: CredentialProvider | CredentialProviderFunction
|
|
139
|
-
) -> None:
|
|
140
|
-
self._provider = provider
|
|
141
|
-
|
|
142
|
-
super().__init__()
|
|
143
|
-
|
|
144
|
-
def retrieve_credentials_impl(self) -> CredentialProviderFunctionReturn:
|
|
145
|
-
return self._provider()
|
|
146
|
-
|
|
147
|
-
def __repr__(self) -> str:
|
|
148
|
-
return f"CachedCredentialProvider[{self._provider!r}]"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
class CredentialProviderAWS(CachingCredentialProvider):
|
|
152
|
-
"""
|
|
153
|
-
AWS Credential Provider.
|
|
154
|
-
|
|
155
|
-
Using this requires the `boto3` Python package to be installed.
|
|
156
|
-
|
|
157
|
-
.. warning::
|
|
158
|
-
This functionality is considered **unstable**. It may be changed
|
|
159
|
-
at any point without it being considered a breaking change.
|
|
160
|
-
"""
|
|
161
|
-
|
|
162
|
-
def __init__(
|
|
163
|
-
self,
|
|
164
|
-
*,
|
|
165
|
-
profile_name: str | None = None,
|
|
166
|
-
region_name: str | None = None,
|
|
167
|
-
assume_role: AWSAssumeRoleKWArgs | None = None,
|
|
168
|
-
_auto_init_unhandled_key: str | None = None,
|
|
169
|
-
_storage_options_has_endpoint_url: bool = False,
|
|
170
|
-
) -> None:
|
|
171
|
-
"""
|
|
172
|
-
Initialize a credential provider for AWS.
|
|
173
|
-
|
|
174
|
-
Parameters
|
|
175
|
-
----------
|
|
176
|
-
profile_name : str
|
|
177
|
-
Profile name to use from credentials file.
|
|
178
|
-
assume_role : AWSAssumeRoleKWArgs | None
|
|
179
|
-
Configure a role to assume. These are passed as kwarg parameters to
|
|
180
|
-
[STS.client.assume_role()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts/client/assume_role.html#STS.Client.assume_role)
|
|
181
|
-
"""
|
|
182
|
-
msg = "`CredentialProviderAWS` functionality is considered unstable"
|
|
183
|
-
issue_unstable_warning(msg)
|
|
184
|
-
|
|
185
|
-
self._ensure_module_availability()
|
|
186
|
-
|
|
187
|
-
self.profile_name = profile_name
|
|
188
|
-
self.region_name = region_name
|
|
189
|
-
self.assume_role = assume_role
|
|
190
|
-
self._auto_init_unhandled_key = _auto_init_unhandled_key
|
|
191
|
-
self._storage_options_has_endpoint_url = _storage_options_has_endpoint_url
|
|
192
|
-
|
|
193
|
-
super().__init__()
|
|
194
|
-
|
|
195
|
-
def retrieve_credentials_impl(self) -> CredentialProviderFunctionReturn:
|
|
196
|
-
"""Fetch the credentials for the configured profile name."""
|
|
197
|
-
assert not self._auto_init_unhandled_key
|
|
198
|
-
|
|
199
|
-
session = self._session()
|
|
200
|
-
|
|
201
|
-
if self.assume_role is not None:
|
|
202
|
-
return self._finish_assume_role(session)
|
|
203
|
-
|
|
204
|
-
creds = session.get_credentials()
|
|
205
|
-
|
|
206
|
-
if creds is None:
|
|
207
|
-
msg = "did not receive any credentials from boto3.Session.get_credentials()"
|
|
208
|
-
raise self.EmptyCredentialError(msg)
|
|
209
|
-
|
|
210
|
-
expiry = (
|
|
211
|
-
int(expiry.timestamp())
|
|
212
|
-
if isinstance(expiry := getattr(creds, "_expiry_time", None), datetime)
|
|
213
|
-
else None
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
return {
|
|
217
|
-
"aws_access_key_id": creds.access_key,
|
|
218
|
-
"aws_secret_access_key": creds.secret_key,
|
|
219
|
-
**({"aws_session_token": creds.token} if creds.token is not None else {}),
|
|
220
|
-
}, expiry
|
|
221
|
-
|
|
222
|
-
def _finish_assume_role(self, session: Any) -> CredentialProviderFunctionReturn:
|
|
223
|
-
client = session.client("sts")
|
|
224
|
-
|
|
225
|
-
sts_response = client.assume_role(**self.assume_role)
|
|
226
|
-
creds = sts_response["Credentials"]
|
|
227
|
-
|
|
228
|
-
expiry = creds["Expiration"]
|
|
229
|
-
|
|
230
|
-
if expiry.tzinfo is None:
|
|
231
|
-
msg = "expiration time in STS response did not contain timezone information"
|
|
232
|
-
raise ValueError(msg)
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
"aws_access_key_id": creds["AccessKeyId"],
|
|
236
|
-
"aws_secret_access_key": creds["SecretAccessKey"],
|
|
237
|
-
"aws_session_token": creds["SessionToken"],
|
|
238
|
-
}, int(expiry.timestamp())
|
|
239
|
-
|
|
240
|
-
# Called from Rust, mainly for AWS endpoint_url
|
|
241
|
-
def _storage_update_options(self) -> dict[str, str]:
|
|
242
|
-
if self._storage_options_has_endpoint_url:
|
|
243
|
-
return {}
|
|
244
|
-
|
|
245
|
-
try:
|
|
246
|
-
config = self._session()._session.get_scoped_config()
|
|
247
|
-
except ImportError:
|
|
248
|
-
return {}
|
|
249
|
-
|
|
250
|
-
if endpoint_url := config.get("endpoint_url"):
|
|
251
|
-
if verbose():
|
|
252
|
-
eprint(f"[CredentialProviderAWS]: Loaded endpoint_url: {endpoint_url}")
|
|
253
|
-
|
|
254
|
-
return {"endpoint_url": endpoint_url}
|
|
255
|
-
|
|
256
|
-
return {}
|
|
257
|
-
|
|
258
|
-
# Called from Rust
|
|
259
|
-
def _can_use_as_provider(self) -> bool:
|
|
260
|
-
if self._auto_init_unhandled_key:
|
|
261
|
-
if verbose():
|
|
262
|
-
eprint(
|
|
263
|
-
"[CredentialProviderAWS]: Will not be used as a provider: "
|
|
264
|
-
f"unhandled key in storage_options: '{self._auto_init_unhandled_key}'"
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
return False
|
|
268
|
-
|
|
269
|
-
try:
|
|
270
|
-
self()
|
|
271
|
-
|
|
272
|
-
except ImportError as e:
|
|
273
|
-
if self.profile_name:
|
|
274
|
-
msg = (
|
|
275
|
-
"cannot load requested aws_profile "
|
|
276
|
-
f"'{self.profile_name}': {type(e).__name__}: {e}"
|
|
277
|
-
)
|
|
278
|
-
raise polars.exceptions.ComputeError(msg) from e
|
|
279
|
-
|
|
280
|
-
return False
|
|
281
|
-
|
|
282
|
-
except self.EmptyCredentialError:
|
|
283
|
-
if verbose():
|
|
284
|
-
eprint("[CredentialProviderAWS]: Did not find any credentials")
|
|
285
|
-
|
|
286
|
-
return False
|
|
287
|
-
|
|
288
|
-
return True
|
|
289
|
-
|
|
290
|
-
def _session(self) -> boto3.Session:
|
|
291
|
-
# Note: boto3 automatically sources the AWS_PROFILE env var
|
|
292
|
-
import boto3
|
|
293
|
-
|
|
294
|
-
return boto3.Session(
|
|
295
|
-
profile_name=self.profile_name,
|
|
296
|
-
region_name=self.region_name,
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
@classmethod
|
|
300
|
-
def _ensure_module_availability(cls) -> None:
|
|
301
|
-
if importlib.util.find_spec("boto3") is None:
|
|
302
|
-
msg = "boto3 must be installed to use `CredentialProviderAWS`"
|
|
303
|
-
raise ImportError(msg)
|
|
304
|
-
|
|
305
|
-
class EmptyCredentialError(Exception):
|
|
306
|
-
"""
|
|
307
|
-
Raised when boto3 returns empty credentials.
|
|
308
|
-
|
|
309
|
-
This generally indicates that no credentials could be found in the
|
|
310
|
-
environment.
|
|
311
|
-
"""
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
class CredentialProviderAzure(CachingCredentialProvider):
|
|
315
|
-
"""
|
|
316
|
-
Azure Credential Provider.
|
|
317
|
-
|
|
318
|
-
Using this requires the `azure-identity` Python package to be installed.
|
|
319
|
-
|
|
320
|
-
.. warning::
|
|
321
|
-
This functionality is considered **unstable**. It may be changed
|
|
322
|
-
at any point without it being considered a breaking change.
|
|
323
|
-
"""
|
|
324
|
-
|
|
325
|
-
def __init__(
|
|
326
|
-
self,
|
|
327
|
-
*,
|
|
328
|
-
scopes: list[str] | None = None,
|
|
329
|
-
tenant_id: str | None = None,
|
|
330
|
-
credential: Any | None = None,
|
|
331
|
-
_storage_account: str | None = None,
|
|
332
|
-
) -> None:
|
|
333
|
-
"""
|
|
334
|
-
Initialize a credential provider for Microsoft Azure.
|
|
335
|
-
|
|
336
|
-
By default, this uses `azure.identity.DefaultAzureCredential()`.
|
|
337
|
-
|
|
338
|
-
Parameters
|
|
339
|
-
----------
|
|
340
|
-
scopes
|
|
341
|
-
Scopes to pass to `get_token`
|
|
342
|
-
tenant_id
|
|
343
|
-
Azure tenant ID.
|
|
344
|
-
credential
|
|
345
|
-
Optionally pass an instantiated Azure credential class to use (e.g.
|
|
346
|
-
`azure.identity.DefaultAzureCredential`). The credential class must
|
|
347
|
-
have a `get_token()` method.
|
|
348
|
-
"""
|
|
349
|
-
msg = "`CredentialProviderAzure` functionality is considered unstable"
|
|
350
|
-
issue_unstable_warning(msg)
|
|
351
|
-
|
|
352
|
-
self.account_name = _storage_account
|
|
353
|
-
self.scopes = (
|
|
354
|
-
scopes if scopes is not None else ["https://storage.azure.com/.default"]
|
|
355
|
-
)
|
|
356
|
-
self.tenant_id = tenant_id
|
|
357
|
-
self.credential = credential
|
|
358
|
-
|
|
359
|
-
if credential is not None:
|
|
360
|
-
# If the user passes a credential class, we just need to ensure it
|
|
361
|
-
# has a `get_token()` method.
|
|
362
|
-
if not hasattr(credential, "get_token"):
|
|
363
|
-
msg = (
|
|
364
|
-
f"the provided `credential` object {credential!r} does "
|
|
365
|
-
"not have a `get_token()` method."
|
|
366
|
-
)
|
|
367
|
-
raise ValueError(msg)
|
|
368
|
-
|
|
369
|
-
# We don't need the module if we are permitted and able to retrieve the
|
|
370
|
-
# account key from the Azure CLI.
|
|
371
|
-
elif self._try_get_azure_storage_account_credential_if_permitted() is None:
|
|
372
|
-
self._ensure_module_availability()
|
|
373
|
-
|
|
374
|
-
if verbose():
|
|
375
|
-
eprint(
|
|
376
|
-
"[CredentialProviderAzure]: "
|
|
377
|
-
f"{self.account_name = } "
|
|
378
|
-
f"{self.tenant_id = } "
|
|
379
|
-
f"{self.scopes = } "
|
|
380
|
-
)
|
|
381
|
-
|
|
382
|
-
super().__init__()
|
|
383
|
-
|
|
384
|
-
def retrieve_credentials_impl(self) -> CredentialProviderFunctionReturn:
|
|
385
|
-
"""Fetch the credentials."""
|
|
386
|
-
if (
|
|
387
|
-
v := self._try_get_azure_storage_account_credential_if_permitted()
|
|
388
|
-
) is not None:
|
|
389
|
-
return v
|
|
390
|
-
|
|
391
|
-
import azure.identity
|
|
392
|
-
|
|
393
|
-
credential = self.credential or azure.identity.DefaultAzureCredential()
|
|
394
|
-
token = credential.get_token(*self.scopes, tenant_id=self.tenant_id)
|
|
395
|
-
|
|
396
|
-
return {
|
|
397
|
-
"bearer_token": token.token,
|
|
398
|
-
}, token.expires_on
|
|
399
|
-
|
|
400
|
-
def _try_get_azure_storage_account_credential_if_permitted(
|
|
401
|
-
self,
|
|
402
|
-
) -> CredentialProviderFunctionReturn | None:
|
|
403
|
-
POLARS_AUTO_USE_AZURE_STORAGE_ACCOUNT_KEY = os.getenv(
|
|
404
|
-
"POLARS_AUTO_USE_AZURE_STORAGE_ACCOUNT_KEY"
|
|
405
|
-
)
|
|
406
|
-
|
|
407
|
-
verbose = polars._utils.logging.verbose()
|
|
408
|
-
|
|
409
|
-
if verbose:
|
|
410
|
-
eprint(
|
|
411
|
-
"[CredentialProviderAzure]: "
|
|
412
|
-
f"{self.account_name = } "
|
|
413
|
-
f"{POLARS_AUTO_USE_AZURE_STORAGE_ACCOUNT_KEY = }"
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
if (
|
|
417
|
-
self.account_name is not None
|
|
418
|
-
and POLARS_AUTO_USE_AZURE_STORAGE_ACCOUNT_KEY == "1"
|
|
419
|
-
):
|
|
420
|
-
try:
|
|
421
|
-
creds = {
|
|
422
|
-
"account_key": self._get_azure_storage_account_key_az_cli(
|
|
423
|
-
self.account_name
|
|
424
|
-
)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
if verbose:
|
|
428
|
-
eprint(
|
|
429
|
-
"[CredentialProviderAzure]: Retrieved account key from Azure CLI"
|
|
430
|
-
)
|
|
431
|
-
except Exception as e:
|
|
432
|
-
if verbose:
|
|
433
|
-
eprint(
|
|
434
|
-
f"[CredentialProviderAzure]: Could not retrieve account key from Azure CLI: {e}"
|
|
435
|
-
)
|
|
436
|
-
else:
|
|
437
|
-
return creds, None
|
|
438
|
-
|
|
439
|
-
return None
|
|
440
|
-
|
|
441
|
-
@classmethod
|
|
442
|
-
def _ensure_module_availability(cls) -> None:
|
|
443
|
-
if importlib.util.find_spec("azure.identity") is None:
|
|
444
|
-
msg = "azure-identity must be installed to use `CredentialProviderAzure`"
|
|
445
|
-
raise ImportError(msg)
|
|
446
|
-
|
|
447
|
-
@staticmethod
|
|
448
|
-
def _extract_adls_uri_storage_account(uri: str) -> str | None:
|
|
449
|
-
# "abfss://{CONTAINER}@{STORAGE_ACCOUNT}.dfs.core.windows.net/"
|
|
450
|
-
# ^^^^^^^^^^^^^^^^^
|
|
451
|
-
try:
|
|
452
|
-
return (
|
|
453
|
-
uri.split("://", 1)[1]
|
|
454
|
-
.split("/", 1)[0]
|
|
455
|
-
.split("@", 1)[1]
|
|
456
|
-
.split(".dfs.core.windows.net", 1)[0]
|
|
457
|
-
)
|
|
458
|
-
|
|
459
|
-
except IndexError:
|
|
460
|
-
return None
|
|
461
|
-
|
|
462
|
-
@classmethod
|
|
463
|
-
def _get_azure_storage_account_key_az_cli(cls, account_name: str) -> str:
|
|
464
|
-
# [
|
|
465
|
-
# {
|
|
466
|
-
# "creationTime": "1970-01-01T00:00:00.000000+00:00",
|
|
467
|
-
# "keyName": "key1",
|
|
468
|
-
# "permissions": "FULL",
|
|
469
|
-
# "value": "..."
|
|
470
|
-
# },
|
|
471
|
-
# {
|
|
472
|
-
# "creationTime": "1970-01-01T00:00:00.000000+00:00",
|
|
473
|
-
# "keyName": "key2",
|
|
474
|
-
# "permissions": "FULL",
|
|
475
|
-
# "value": "..."
|
|
476
|
-
# }
|
|
477
|
-
# ]
|
|
478
|
-
|
|
479
|
-
return json.loads(
|
|
480
|
-
cls._azcli(
|
|
481
|
-
"storage",
|
|
482
|
-
"account",
|
|
483
|
-
"keys",
|
|
484
|
-
"list",
|
|
485
|
-
"--output",
|
|
486
|
-
"json",
|
|
487
|
-
"--account-name",
|
|
488
|
-
account_name,
|
|
489
|
-
)
|
|
490
|
-
)[0]["value"]
|
|
491
|
-
|
|
492
|
-
@classmethod
|
|
493
|
-
def _azcli_version(cls) -> str | None:
|
|
494
|
-
try:
|
|
495
|
-
return json.loads(cls._azcli("version"))["azure-cli"]
|
|
496
|
-
except Exception:
|
|
497
|
-
return None
|
|
498
|
-
|
|
499
|
-
@staticmethod
|
|
500
|
-
def _azcli(*args: str) -> bytes:
|
|
501
|
-
return subprocess.check_output(
|
|
502
|
-
["az", *args] if sys.platform != "win32" else ["cmd", "/C", "az", *args]
|
|
503
|
-
)
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
class CredentialProviderGCP(CachingCredentialProvider):
|
|
507
|
-
"""
|
|
508
|
-
GCP Credential Provider.
|
|
509
|
-
|
|
510
|
-
Using this requires the `google-auth` Python package to be installed.
|
|
511
|
-
|
|
512
|
-
.. warning::
|
|
513
|
-
This functionality is considered **unstable**. It may be changed
|
|
514
|
-
at any point without it being considered a breaking change.
|
|
515
|
-
"""
|
|
516
|
-
|
|
517
|
-
def __init__(
|
|
518
|
-
self,
|
|
519
|
-
*,
|
|
520
|
-
scopes: Any | None = None,
|
|
521
|
-
request: Any | None = None,
|
|
522
|
-
quota_project_id: Any | None = None,
|
|
523
|
-
default_scopes: Any | None = None,
|
|
524
|
-
) -> None:
|
|
525
|
-
"""
|
|
526
|
-
Initialize a credential provider for Google Cloud (GCP).
|
|
527
|
-
|
|
528
|
-
Parameters
|
|
529
|
-
----------
|
|
530
|
-
Parameters are passed to `google.auth.default()`
|
|
531
|
-
"""
|
|
532
|
-
msg = "`CredentialProviderGCP` functionality is considered unstable"
|
|
533
|
-
issue_unstable_warning(msg)
|
|
534
|
-
|
|
535
|
-
self._ensure_module_availability()
|
|
536
|
-
|
|
537
|
-
import google.auth
|
|
538
|
-
|
|
539
|
-
self._init_creds = partial(
|
|
540
|
-
google.auth.default,
|
|
541
|
-
scopes=(
|
|
542
|
-
scopes
|
|
543
|
-
if scopes is not None
|
|
544
|
-
else ["https://www.googleapis.com/auth/cloud-platform"]
|
|
545
|
-
),
|
|
546
|
-
request=request,
|
|
547
|
-
quota_project_id=quota_project_id,
|
|
548
|
-
default_scopes=default_scopes,
|
|
549
|
-
)
|
|
550
|
-
|
|
551
|
-
super().__init__()
|
|
552
|
-
|
|
553
|
-
def retrieve_credentials_impl(self) -> CredentialProviderFunctionReturn:
|
|
554
|
-
"""Fetch the credentials."""
|
|
555
|
-
import google.auth.transport.requests
|
|
556
|
-
|
|
557
|
-
creds, _project_id = self._init_creds()
|
|
558
|
-
creds.refresh(google.auth.transport.requests.Request()) # type: ignore[no-untyped-call, unused-ignore]
|
|
559
|
-
|
|
560
|
-
return {"bearer_token": creds.token}, (
|
|
561
|
-
int(
|
|
562
|
-
(
|
|
563
|
-
expiry.replace(tzinfo=zoneinfo.ZoneInfo("UTC"))
|
|
564
|
-
if expiry.tzinfo is None
|
|
565
|
-
else expiry
|
|
566
|
-
).timestamp()
|
|
567
|
-
)
|
|
568
|
-
if (expiry := creds.expiry) is not None
|
|
569
|
-
else None
|
|
570
|
-
)
|
|
571
|
-
|
|
572
|
-
@classmethod
|
|
573
|
-
def _ensure_module_availability(cls) -> None:
|
|
574
|
-
if importlib.util.find_spec("google.auth") is None:
|
|
575
|
-
msg = "google-auth must be installed to use `CredentialProviderGCP`"
|
|
576
|
-
raise ImportError(msg)
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
class UserProvidedGCPToken(CredentialProvider):
|
|
580
|
-
"""User-provided GCP token in storage_options."""
|
|
581
|
-
|
|
582
|
-
def __init__(self, token: str) -> None:
|
|
583
|
-
self.token = token
|
|
584
|
-
|
|
585
|
-
def __call__(self) -> CredentialProviderFunctionReturn:
|
|
586
|
-
return {"bearer_token": self.token}, None
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
def _get_credentials_from_provider_expiry_aware(
|
|
590
|
-
credential_provider: CredentialProviderFunction,
|
|
591
|
-
) -> dict[str, str] | None:
|
|
592
|
-
if (
|
|
593
|
-
isinstance(credential_provider, CredentialProviderAWS)
|
|
594
|
-
and not credential_provider._can_use_as_provider()
|
|
595
|
-
):
|
|
596
|
-
return None
|
|
597
|
-
|
|
598
|
-
creds, opt_expiry = credential_provider()
|
|
599
|
-
|
|
600
|
-
if (
|
|
601
|
-
opt_expiry is not None
|
|
602
|
-
and (expires_in := opt_expiry - int(datetime.now().timestamp())) < 7
|
|
603
|
-
):
|
|
604
|
-
from time import sleep
|
|
605
|
-
|
|
606
|
-
if verbose():
|
|
607
|
-
eprint(f"waiting for {expires_in} seconds for refreshed credentials")
|
|
608
|
-
|
|
609
|
-
sleep(1 + expires_in)
|
|
610
|
-
creds, _ = credential_provider()
|
|
611
|
-
|
|
612
|
-
# Loads the endpoint_url
|
|
613
|
-
if isinstance(credential_provider, CredentialProviderAWS) and (
|
|
614
|
-
v := credential_provider._storage_update_options()
|
|
615
|
-
):
|
|
616
|
-
creds = {**creds, **v}
|
|
617
|
-
|
|
618
|
-
return creds
|
polars/io/csv/__init__.py
DELETED
polars/io/csv/_utils.py
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
|
-
|
|
5
|
-
if TYPE_CHECKING:
|
|
6
|
-
from collections.abc import Sequence
|
|
7
|
-
|
|
8
|
-
from polars import DataFrame
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def _check_arg_is_1byte(
|
|
12
|
-
arg_name: str, arg: str | None, *, can_be_empty: bool = False
|
|
13
|
-
) -> None:
|
|
14
|
-
if isinstance(arg, str):
|
|
15
|
-
arg_byte_length = len(arg.encode("utf-8"))
|
|
16
|
-
if can_be_empty:
|
|
17
|
-
if arg_byte_length > 1:
|
|
18
|
-
msg = (
|
|
19
|
-
f'{arg_name}="{arg}" should be a single byte character or empty,'
|
|
20
|
-
f" but is {arg_byte_length} bytes long"
|
|
21
|
-
)
|
|
22
|
-
raise ValueError(msg)
|
|
23
|
-
elif arg_byte_length != 1:
|
|
24
|
-
msg = (
|
|
25
|
-
f'{arg_name}="{arg}" should be a single byte character, but is'
|
|
26
|
-
f" {arg_byte_length} bytes long"
|
|
27
|
-
)
|
|
28
|
-
raise ValueError(msg)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def _update_columns(df: DataFrame, new_columns: Sequence[str]) -> DataFrame:
|
|
32
|
-
if df.width > len(new_columns):
|
|
33
|
-
cols = df.columns
|
|
34
|
-
for i, name in enumerate(new_columns):
|
|
35
|
-
cols[i] = name
|
|
36
|
-
new_columns = cols
|
|
37
|
-
df.columns = list(new_columns)
|
|
38
|
-
return df
|