lsst-resources 29.2025.1900__py3-none-any.whl → 29.2025.2000__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.
- lsst/resources/_resourceHandles/_davResourceHandle.py +190 -0
- lsst/resources/_resourcePath.py +2 -2
- lsst/resources/dav.py +896 -0
- lsst/resources/davutils.py +2584 -0
- lsst/resources/http.py +10 -18
- lsst/resources/s3.py +8 -1
- lsst/resources/version.py +1 -1
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/METADATA +1 -1
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/RECORD +14 -11
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/WHEEL +1 -1
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/licenses/COPYRIGHT +0 -0
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/licenses/LICENSE +0 -0
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/top_level.txt +0 -0
- {lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/zip-safe +0 -0
lsst/resources/http.py
CHANGED
|
@@ -112,13 +112,6 @@ def _calc_tmpdir_buffer_size(tmpdir: str) -> int:
|
|
|
112
112
|
return max(10 * fsstats.f_bsize, 256 * 4096)
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
def _dav_to_http(url: str) -> str:
|
|
116
|
-
"""Convert dav scheme in URL to http scheme."""
|
|
117
|
-
if url.startswith("dav"):
|
|
118
|
-
url = "http" + url.removeprefix("dav")
|
|
119
|
-
return url
|
|
120
|
-
|
|
121
|
-
|
|
122
115
|
class HttpResourcePathConfig:
|
|
123
116
|
"""Configuration class to encapsulate the configurable items used by class
|
|
124
117
|
HttpResourcePath.
|
|
@@ -437,7 +430,7 @@ def _get_dav_and_server_headers(path: ResourcePath | str) -> tuple[str | None, s
|
|
|
437
430
|
config = HttpResourcePathConfig()
|
|
438
431
|
with SessionStore(config=config).get(path) as session:
|
|
439
432
|
resp = session.options(
|
|
440
|
-
|
|
433
|
+
str(path),
|
|
441
434
|
stream=False,
|
|
442
435
|
timeout=config.timeout,
|
|
443
436
|
)
|
|
@@ -587,7 +580,7 @@ class SessionStore:
|
|
|
587
580
|
Note that "https://www.example.org" and "https://www.example.org:12345"
|
|
588
581
|
will have different sessions since the port number is not identical.
|
|
589
582
|
"""
|
|
590
|
-
root_uri =
|
|
583
|
+
root_uri = str(rpath.root_uri())
|
|
591
584
|
if root_uri not in self._sessions:
|
|
592
585
|
# We don't have yet a session for this endpoint: create a new one.
|
|
593
586
|
self._sessions[root_uri] = self._make_session(rpath)
|
|
@@ -597,7 +590,7 @@ class SessionStore:
|
|
|
597
590
|
def _make_session(self, rpath: ResourcePath) -> requests.Session:
|
|
598
591
|
"""Make a new session configured from values from the environment."""
|
|
599
592
|
session = requests.Session()
|
|
600
|
-
root_uri =
|
|
593
|
+
root_uri = str(rpath.root_uri())
|
|
601
594
|
log.debug("Creating new HTTP session for endpoint %s ...", root_uri)
|
|
602
595
|
retries = Retry(
|
|
603
596
|
# Total number of retries to allow. Takes precedence over other
|
|
@@ -657,9 +650,8 @@ class SessionStore:
|
|
|
657
650
|
# from request to request. Systematically persisting connections to
|
|
658
651
|
# those servers may exhaust their capabilities when there are thousands
|
|
659
652
|
# of simultaneous clients.
|
|
660
|
-
scheme = _dav_to_http(rpath.scheme)
|
|
661
653
|
session.mount(
|
|
662
|
-
f"{scheme}://",
|
|
654
|
+
f"{rpath.scheme}://",
|
|
663
655
|
HTTPAdapter(
|
|
664
656
|
pool_connections=self._num_pools,
|
|
665
657
|
pool_maxsize=0,
|
|
@@ -1127,7 +1119,7 @@ class HttpResourcePath(ResourcePath):
|
|
|
1127
1119
|
stream = size > 0
|
|
1128
1120
|
with self.data_session as session:
|
|
1129
1121
|
with time_this(log, msg="GET %s", args=(self,)):
|
|
1130
|
-
resp = session.get(
|
|
1122
|
+
resp = session.get(self.geturl(), stream=stream, timeout=self._config.timeout)
|
|
1131
1123
|
|
|
1132
1124
|
if resp.status_code != requests.codes.ok: # 200
|
|
1133
1125
|
raise FileNotFoundError(
|
|
@@ -1350,7 +1342,7 @@ class HttpResourcePath(ResourcePath):
|
|
|
1350
1342
|
):
|
|
1351
1343
|
if self.scheme.startswith("dav") and fsspec:
|
|
1352
1344
|
# Not webdav so convert to http.
|
|
1353
|
-
return fsspec.url_to_fs(
|
|
1345
|
+
return fsspec.url_to_fs(self.geturl())
|
|
1354
1346
|
return super().to_fsspec()
|
|
1355
1347
|
|
|
1356
1348
|
if self.isdir():
|
|
@@ -1520,7 +1512,7 @@ class HttpResourcePath(ResourcePath):
|
|
|
1520
1512
|
# to both the front end and back end servers are closed after the
|
|
1521
1513
|
# download operation is finished.
|
|
1522
1514
|
with self.data_session as session:
|
|
1523
|
-
resp = session.get(
|
|
1515
|
+
resp = session.get(self.geturl(), stream=True, timeout=self._config.timeout)
|
|
1524
1516
|
if resp.status_code != requests.codes.ok:
|
|
1525
1517
|
raise FileNotFoundError(
|
|
1526
1518
|
f"Unable to download resource {self}; status: {resp.status_code} {resp.reason}"
|
|
@@ -1633,7 +1625,7 @@ class HttpResourcePath(ResourcePath):
|
|
|
1633
1625
|
for _ in range(max_redirects := 5):
|
|
1634
1626
|
resp = session.request(
|
|
1635
1627
|
method,
|
|
1636
|
-
|
|
1628
|
+
url,
|
|
1637
1629
|
data=body,
|
|
1638
1630
|
headers=headers,
|
|
1639
1631
|
stream=False,
|
|
@@ -1791,7 +1783,7 @@ class HttpResourcePath(ResourcePath):
|
|
|
1791
1783
|
src : `HttpResourcePath`
|
|
1792
1784
|
The source of the contents to move to `self`.
|
|
1793
1785
|
"""
|
|
1794
|
-
headers = {"Destination":
|
|
1786
|
+
headers = {"Destination": self.geturl()}
|
|
1795
1787
|
resp = self._send_webdav_request(method, url=src.geturl(), headers=headers, session=self.data_session)
|
|
1796
1788
|
if resp.status_code in (requests.codes.created, requests.codes.no_content):
|
|
1797
1789
|
return
|
|
@@ -1898,7 +1890,7 @@ class HttpResourcePath(ResourcePath):
|
|
|
1898
1890
|
if self._config.send_expect_on_put or self.server == "dcache":
|
|
1899
1891
|
headers["Expect"] = "100-continue"
|
|
1900
1892
|
|
|
1901
|
-
url =
|
|
1893
|
+
url = self.geturl()
|
|
1902
1894
|
|
|
1903
1895
|
# Use the session as a context manager to ensure the underlying
|
|
1904
1896
|
# connections are closed after finishing uploading the data.
|
lsst/resources/s3.py
CHANGED
|
@@ -251,6 +251,7 @@ class S3ResourcePath(ResourcePath):
|
|
|
251
251
|
# URIs.
|
|
252
252
|
first_uri = related_uris[0]
|
|
253
253
|
# API requires no more than 1000 per call.
|
|
254
|
+
chunk_num = 0
|
|
254
255
|
for chunk in chunk_iterable(related_uris, chunk_size=1_000):
|
|
255
256
|
key_to_uri: dict[str, ResourcePath] = {}
|
|
256
257
|
keys: list[dict[str, str]] = []
|
|
@@ -260,7 +261,13 @@ class S3ResourcePath(ResourcePath):
|
|
|
260
261
|
keys.append({"Key": key})
|
|
261
262
|
# Default to assuming everything worked.
|
|
262
263
|
results[uri] = MBulkResult(True, None)
|
|
263
|
-
|
|
264
|
+
chunk_num += 1
|
|
265
|
+
with time_this(
|
|
266
|
+
log,
|
|
267
|
+
msg="Bulk delete; chunk number %d; %d dataset%s",
|
|
268
|
+
args=(chunk_num, len(chunk), "s" if len(chunk) != 1 else ""),
|
|
269
|
+
):
|
|
270
|
+
errored = cls._delete_related_objects(first_uri.client, first_uri._bucket, keys)
|
|
264
271
|
|
|
265
272
|
# Update with error information.
|
|
266
273
|
for key, bulk_result in errored.items():
|
lsst/resources/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__all__ = ["__version__"]
|
|
2
|
-
__version__ = "29.2025.
|
|
2
|
+
__version__ = "29.2025.2000"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-resources
|
|
3
|
-
Version: 29.2025.
|
|
3
|
+
Version: 29.2025.2000
|
|
4
4
|
Summary: An abstraction layer for reading and writing from URI file resources.
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
lsst/__init__.py,sha256=9I6UQ9gj-ZcPlvsa0OPBo76UujxXVehVzw9yMAOQvyM,466
|
|
2
2
|
lsst/resources/__init__.py,sha256=BDj6uokvd0ZQNGl-Xgz5gZd83Z0L2gFqGSk0KJpylP8,778
|
|
3
|
-
lsst/resources/_resourcePath.py,sha256=
|
|
3
|
+
lsst/resources/_resourcePath.py,sha256=neuZ-QNGIqwBavEq4xEBUnQveHeqACIuhVi4COhJI0A,73902
|
|
4
|
+
lsst/resources/dav.py,sha256=XQMAZgthvtJ4hUXZ0avBAHnAYjMYU3m2DPHDyQVT7a8,31547
|
|
5
|
+
lsst/resources/davutils.py,sha256=xALuMRSvYroqn_Jz6bjnj43b4OgOgCJtNW49kyTtuiw,97983
|
|
4
6
|
lsst/resources/file.py,sha256=-jPuoHvTEtx5tnDyNkfwhWAyX0cTwkuMd-JvJn9EGdE,23226
|
|
5
7
|
lsst/resources/gs.py,sha256=Lpo5GAzH7R7HG8E5RMGOdP4j4hjWJn-k6M3OXj0nHQM,12783
|
|
6
|
-
lsst/resources/http.py,sha256=
|
|
8
|
+
lsst/resources/http.py,sha256=Oa6YlTnHLd0ifkvBNhduI67oiRHE-iQupAL9TEbxyQo,87930
|
|
7
9
|
lsst/resources/location.py,sha256=x3Tq0x5o1OXYmZDxYBenUG1N71wtDhnjVAr3s2ZEiu8,7937
|
|
8
10
|
lsst/resources/mem.py,sha256=VOWh7XxJPfqKcFdLZSjKEAfORQ2AHZHpxmjT8LniV60,1008
|
|
9
11
|
lsst/resources/packageresource.py,sha256=vnfeRlpVwpC5cDQZE6Lnh8EH6oZy1sH2vLz9ONYjJ4k,6817
|
|
10
12
|
lsst/resources/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
lsst/resources/s3.py,sha256=
|
|
13
|
+
lsst/resources/s3.py,sha256=n9m4BHEVJgj2_4yAMydwX-w5hmnOPZTihWEItHi0kQI,26923
|
|
12
14
|
lsst/resources/s3utils.py,sha256=ojWf9BPrK9mhGQ8jvs4_8Nsqf9360e79U5FnPTxe24A,14576
|
|
13
15
|
lsst/resources/schemeless.py,sha256=GfJcKzZ0XIeepfQdW4HPZWiZlSp_ej0SEtSiJTrDUQs,10666
|
|
14
16
|
lsst/resources/tests.py,sha256=SqYLbDG6QkZTB-0UvrsiPtfmdL1TcglGeqBTPQxu9GE,44027
|
|
15
17
|
lsst/resources/utils.py,sha256=6O3Mq7JbPEtqyD2lM77pRpwcPMfV5SxiNMknw-F2vNs,8097
|
|
16
|
-
lsst/resources/version.py,sha256=
|
|
18
|
+
lsst/resources/version.py,sha256=bT9RvvieKvOl5VImh838xbe0jWwzezTNwq19FWhF5NU,55
|
|
17
19
|
lsst/resources/_resourceHandles/__init__.py,sha256=zOcZ8gVEBdAWcHJaZabA8Vdq-wAVcxjbmA_1b1IWM6M,76
|
|
18
20
|
lsst/resources/_resourceHandles/_baseResourceHandle.py,sha256=lQwxDOmFUNJndTxsjpz-HxrQBL0L-z4aXQocHdOEI7c,4676
|
|
21
|
+
lsst/resources/_resourceHandles/_davResourceHandle.py,sha256=12X5-K5KqzG4EV78ZkIIrjcZcFroXy3Y2JQ_N-SDqF0,6616
|
|
19
22
|
lsst/resources/_resourceHandles/_fileResourceHandle.py,sha256=A7_WQPzD0ZlOzNmaI_TPdZybrNxrXPkNHWVla3UFxfs,3676
|
|
20
23
|
lsst/resources/_resourceHandles/_httpResourceHandle.py,sha256=Yami8IVGeru4bLQCag-OvGG0ltz1qyEg57FY4IEB87Y,10995
|
|
21
24
|
lsst/resources/_resourceHandles/_s3ResourceHandle.py,sha256=NkDmPb9bm_zMvr6mMnb-tBmqJDt0yUJrt2gZXR8l7ok,12923
|
|
22
|
-
lsst_resources-29.2025.
|
|
23
|
-
lsst_resources-29.2025.
|
|
24
|
-
lsst_resources-29.2025.
|
|
25
|
-
lsst_resources-29.2025.
|
|
26
|
-
lsst_resources-29.2025.
|
|
27
|
-
lsst_resources-29.2025.
|
|
28
|
-
lsst_resources-29.2025.
|
|
25
|
+
lsst_resources-29.2025.2000.dist-info/licenses/COPYRIGHT,sha256=yazVsoMmFwhiw5itGrdT4YPmXbpsQyUFjlpOyZIa77M,148
|
|
26
|
+
lsst_resources-29.2025.2000.dist-info/licenses/LICENSE,sha256=7wrtgl8meQ0_RIuv2TjIKpAnNrl-ODH-QLwyHe9citI,1516
|
|
27
|
+
lsst_resources-29.2025.2000.dist-info/METADATA,sha256=47lnuHxjeCYuBH9Kj_2545yFIgE5DkwUy6AWnUox_ws,2237
|
|
28
|
+
lsst_resources-29.2025.2000.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
|
29
|
+
lsst_resources-29.2025.2000.dist-info/top_level.txt,sha256=eUWiOuVVm9wwTrnAgiJT6tp6HQHXxIhj2QSZ7NYZH80,5
|
|
30
|
+
lsst_resources-29.2025.2000.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
31
|
+
lsst_resources-29.2025.2000.dist-info/RECORD,,
|
{lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/licenses/COPYRIGHT
RENAMED
|
File without changes
|
{lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{lsst_resources-29.2025.1900.dist-info → lsst_resources-29.2025.2000.dist-info}/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|