asanypath-native 2.1.0__tar.gz → 2.3.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.
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/Cargo.lock +118 -8
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/Cargo.toml +5 -3
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/PKG-INFO +1 -1
- asanypath_native-2.3.0/asanypath_native.pyi +146 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/artifactory.rs +39 -1
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/azure.rs +91 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/backend.rs +33 -9
- asanypath_native-2.3.0/src/cache.rs +198 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/gcs.rs +112 -4
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/http.rs +40 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/lib.rs +12 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/s3.rs +277 -13
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/ssh.rs +48 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/pyproject.toml +0 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/src/xml.rs +0 -0
- {asanypath_native-2.1.0 → asanypath_native-2.3.0}/uv.lock +0 -0
|
@@ -96,7 +96,7 @@ dependencies = [
|
|
|
96
96
|
|
|
97
97
|
[[package]]
|
|
98
98
|
name = "asanypath-native"
|
|
99
|
-
version = "2.
|
|
99
|
+
version = "2.3.0"
|
|
100
100
|
dependencies = [
|
|
101
101
|
"anyhow",
|
|
102
102
|
"aws-config",
|
|
@@ -114,6 +114,7 @@ dependencies = [
|
|
|
114
114
|
"quick-xml",
|
|
115
115
|
"reqwest",
|
|
116
116
|
"ring",
|
|
117
|
+
"rusqlite",
|
|
117
118
|
"russh",
|
|
118
119
|
"russh-sftp",
|
|
119
120
|
"scraper",
|
|
@@ -122,6 +123,7 @@ dependencies = [
|
|
|
122
123
|
"sonic-rs",
|
|
123
124
|
"ssh2-config",
|
|
124
125
|
"tokio",
|
|
126
|
+
"tokio-util",
|
|
125
127
|
"url",
|
|
126
128
|
"urlencoding",
|
|
127
129
|
]
|
|
@@ -311,9 +313,9 @@ dependencies = [
|
|
|
311
313
|
|
|
312
314
|
[[package]]
|
|
313
315
|
name = "aws-sigv4"
|
|
314
|
-
version = "1.
|
|
316
|
+
version = "1.6.0"
|
|
315
317
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
316
|
-
checksum = "
|
|
318
|
+
checksum = "2312577f088c9fbf4206dfdb884cf1de9407b43e1a923cbed5237775116fc24b"
|
|
317
319
|
dependencies = [
|
|
318
320
|
"aws-credential-types",
|
|
319
321
|
"aws-smithy-http",
|
|
@@ -448,15 +450,14 @@ dependencies = [
|
|
|
448
450
|
|
|
449
451
|
[[package]]
|
|
450
452
|
name = "aws-smithy-runtime-api"
|
|
451
|
-
version = "1.
|
|
453
|
+
version = "1.19.0"
|
|
452
454
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
453
|
-
checksum = "
|
|
455
|
+
checksum = "c0730c16f91124c6a2abb4932c77e299288b3dd9f967ea2e9ec48cc6731e87a4"
|
|
454
456
|
dependencies = [
|
|
455
457
|
"aws-smithy-async",
|
|
456
458
|
"aws-smithy-runtime-api-macros",
|
|
457
459
|
"aws-smithy-types",
|
|
458
460
|
"bytes",
|
|
459
|
-
"http 0.2.12",
|
|
460
461
|
"http 1.5.0",
|
|
461
462
|
"pin-project-lite",
|
|
462
463
|
"tokio",
|
|
@@ -488,9 +489,9 @@ dependencies = [
|
|
|
488
489
|
|
|
489
490
|
[[package]]
|
|
490
491
|
name = "aws-smithy-types"
|
|
491
|
-
version = "1.
|
|
492
|
+
version = "1.8.1"
|
|
492
493
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
493
|
-
checksum = "
|
|
494
|
+
checksum = "69bb407740a197147da48238ecc94498493c9e85445732360cec180296ca45f1"
|
|
494
495
|
dependencies = [
|
|
495
496
|
"base64-simd",
|
|
496
497
|
"bytes",
|
|
@@ -1197,6 +1198,18 @@ dependencies = [
|
|
|
1197
1198
|
"windows-sys 0.61.2",
|
|
1198
1199
|
]
|
|
1199
1200
|
|
|
1201
|
+
[[package]]
|
|
1202
|
+
name = "fallible-iterator"
|
|
1203
|
+
version = "0.3.0"
|
|
1204
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1205
|
+
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
|
1206
|
+
|
|
1207
|
+
[[package]]
|
|
1208
|
+
name = "fallible-streaming-iterator"
|
|
1209
|
+
version = "0.1.9"
|
|
1210
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1211
|
+
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
|
1212
|
+
|
|
1200
1213
|
[[package]]
|
|
1201
1214
|
name = "fastrand"
|
|
1202
1215
|
version = "2.5.0"
|
|
@@ -1254,6 +1267,12 @@ version = "1.0.7"
|
|
|
1254
1267
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1255
1268
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|
1256
1269
|
|
|
1270
|
+
[[package]]
|
|
1271
|
+
name = "foldhash"
|
|
1272
|
+
version = "0.2.0"
|
|
1273
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1274
|
+
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
|
1275
|
+
|
|
1257
1276
|
[[package]]
|
|
1258
1277
|
name = "form_urlencoded"
|
|
1259
1278
|
version = "1.2.2"
|
|
@@ -1493,11 +1512,32 @@ version = "0.14.5"
|
|
|
1493
1512
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1494
1513
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
|
1495
1514
|
|
|
1515
|
+
[[package]]
|
|
1516
|
+
name = "hashbrown"
|
|
1517
|
+
version = "0.16.1"
|
|
1518
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1519
|
+
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
|
1520
|
+
dependencies = [
|
|
1521
|
+
"foldhash",
|
|
1522
|
+
]
|
|
1523
|
+
|
|
1496
1524
|
[[package]]
|
|
1497
1525
|
name = "hashbrown"
|
|
1498
1526
|
version = "0.17.1"
|
|
1499
1527
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1500
1528
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|
1529
|
+
dependencies = [
|
|
1530
|
+
"foldhash",
|
|
1531
|
+
]
|
|
1532
|
+
|
|
1533
|
+
[[package]]
|
|
1534
|
+
name = "hashlink"
|
|
1535
|
+
version = "0.12.2"
|
|
1536
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1537
|
+
checksum = "a596f1b20ed2cc5ecac41a164aaebc7258057060f06c0cf7a2ba3991ee7990fb"
|
|
1538
|
+
dependencies = [
|
|
1539
|
+
"hashbrown 0.17.1",
|
|
1540
|
+
]
|
|
1501
1541
|
|
|
1502
1542
|
[[package]]
|
|
1503
1543
|
name = "heck"
|
|
@@ -1895,6 +1935,17 @@ dependencies = [
|
|
|
1895
1935
|
"libc",
|
|
1896
1936
|
]
|
|
1897
1937
|
|
|
1938
|
+
[[package]]
|
|
1939
|
+
name = "libsqlite3-sys"
|
|
1940
|
+
version = "0.38.2"
|
|
1941
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1942
|
+
checksum = "f1d20bef17f513b9b3004532233187769cd072d790971f4e4da0e346eb6401e8"
|
|
1943
|
+
dependencies = [
|
|
1944
|
+
"cc",
|
|
1945
|
+
"pkg-config",
|
|
1946
|
+
"vcpkg",
|
|
1947
|
+
]
|
|
1948
|
+
|
|
1898
1949
|
[[package]]
|
|
1899
1950
|
name = "litemap"
|
|
1900
1951
|
version = "0.8.3"
|
|
@@ -2695,6 +2746,7 @@ dependencies = [
|
|
|
2695
2746
|
"base64 0.22.1",
|
|
2696
2747
|
"bytes",
|
|
2697
2748
|
"futures-core",
|
|
2749
|
+
"futures-util",
|
|
2698
2750
|
"h2",
|
|
2699
2751
|
"http 1.5.0",
|
|
2700
2752
|
"http-body 1.1.0",
|
|
@@ -2715,12 +2767,14 @@ dependencies = [
|
|
|
2715
2767
|
"sync_wrapper",
|
|
2716
2768
|
"tokio",
|
|
2717
2769
|
"tokio-rustls",
|
|
2770
|
+
"tokio-util",
|
|
2718
2771
|
"tower",
|
|
2719
2772
|
"tower-http",
|
|
2720
2773
|
"tower-service",
|
|
2721
2774
|
"url",
|
|
2722
2775
|
"wasm-bindgen",
|
|
2723
2776
|
"wasm-bindgen-futures",
|
|
2777
|
+
"wasm-streams",
|
|
2724
2778
|
"web-sys",
|
|
2725
2779
|
"webpki-roots",
|
|
2726
2780
|
]
|
|
@@ -2797,6 +2851,31 @@ dependencies = [
|
|
|
2797
2851
|
"zeroize",
|
|
2798
2852
|
]
|
|
2799
2853
|
|
|
2854
|
+
[[package]]
|
|
2855
|
+
name = "rsqlite-vfs"
|
|
2856
|
+
version = "0.1.1"
|
|
2857
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2858
|
+
checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c"
|
|
2859
|
+
dependencies = [
|
|
2860
|
+
"hashbrown 0.16.1",
|
|
2861
|
+
"thiserror",
|
|
2862
|
+
]
|
|
2863
|
+
|
|
2864
|
+
[[package]]
|
|
2865
|
+
name = "rusqlite"
|
|
2866
|
+
version = "0.40.2"
|
|
2867
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2868
|
+
checksum = "23f2a97da3e3873c73cb2a2e71b35c40ff95e0b1eefa8d72d8499a6928c3b5b3"
|
|
2869
|
+
dependencies = [
|
|
2870
|
+
"bitflags",
|
|
2871
|
+
"fallible-iterator",
|
|
2872
|
+
"fallible-streaming-iterator",
|
|
2873
|
+
"hashlink",
|
|
2874
|
+
"libsqlite3-sys",
|
|
2875
|
+
"smallvec",
|
|
2876
|
+
"sqlite-wasm-rs",
|
|
2877
|
+
]
|
|
2878
|
+
|
|
2800
2879
|
[[package]]
|
|
2801
2880
|
name = "russh"
|
|
2802
2881
|
version = "0.63.3"
|
|
@@ -3360,6 +3439,18 @@ version = "0.1.0"
|
|
|
3360
3439
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3361
3440
|
checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620"
|
|
3362
3441
|
|
|
3442
|
+
[[package]]
|
|
3443
|
+
name = "sqlite-wasm-rs"
|
|
3444
|
+
version = "0.5.5"
|
|
3445
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3446
|
+
checksum = "dc3efc0da82635d7e1ced0053bbbfa8c7ab9645d0bf36ceb4f7127bb85315d75"
|
|
3447
|
+
dependencies = [
|
|
3448
|
+
"cc",
|
|
3449
|
+
"js-sys",
|
|
3450
|
+
"rsqlite-vfs",
|
|
3451
|
+
"wasm-bindgen",
|
|
3452
|
+
]
|
|
3453
|
+
|
|
3363
3454
|
[[package]]
|
|
3364
3455
|
name = "ssh-cipher"
|
|
3365
3456
|
version = "0.3.0"
|
|
@@ -3794,6 +3885,12 @@ dependencies = [
|
|
|
3794
3885
|
"wasm-bindgen",
|
|
3795
3886
|
]
|
|
3796
3887
|
|
|
3888
|
+
[[package]]
|
|
3889
|
+
name = "vcpkg"
|
|
3890
|
+
version = "0.2.15"
|
|
3891
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3892
|
+
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|
3893
|
+
|
|
3797
3894
|
[[package]]
|
|
3798
3895
|
name = "version_check"
|
|
3799
3896
|
version = "0.9.5"
|
|
@@ -3885,6 +3982,19 @@ dependencies = [
|
|
|
3885
3982
|
"unicode-ident",
|
|
3886
3983
|
]
|
|
3887
3984
|
|
|
3985
|
+
[[package]]
|
|
3986
|
+
name = "wasm-streams"
|
|
3987
|
+
version = "0.4.2"
|
|
3988
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3989
|
+
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
|
|
3990
|
+
dependencies = [
|
|
3991
|
+
"futures-util",
|
|
3992
|
+
"js-sys",
|
|
3993
|
+
"wasm-bindgen",
|
|
3994
|
+
"wasm-bindgen-futures",
|
|
3995
|
+
"web-sys",
|
|
3996
|
+
]
|
|
3997
|
+
|
|
3888
3998
|
[[package]]
|
|
3889
3999
|
name = "web-sys"
|
|
3890
4000
|
version = "0.3.105"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "asanypath-native"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.3.0"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
publish = false
|
|
@@ -12,9 +12,9 @@ crate-type = ["cdylib"]
|
|
|
12
12
|
[dependencies]
|
|
13
13
|
pyo3 = { version = "0.29", features = ["extension-module"] }
|
|
14
14
|
pyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] }
|
|
15
|
-
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
|
|
15
|
+
tokio = { version = "1", features = ["rt-multi-thread", "macros", "fs"] }
|
|
16
16
|
aws-config = { version = "1", features = ["behavior-version-latest"] }
|
|
17
|
-
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "http2"] }
|
|
17
|
+
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "http2", "stream"] }
|
|
18
18
|
futures = "0.3"
|
|
19
19
|
aws-sigv4 = "1"
|
|
20
20
|
aws-credential-types = { version = "1", features = ["hardcoded-credentials"] }
|
|
@@ -34,8 +34,10 @@ scraper = { version = "0.27", default-features = false }
|
|
|
34
34
|
url = "2"
|
|
35
35
|
russh = "0.63"
|
|
36
36
|
russh-sftp = "3"
|
|
37
|
+
tokio-util = { version = "0.7", features = ["io"] }
|
|
37
38
|
anyhow = "1"
|
|
38
39
|
ssh2-config = { version = "0.8", default-features = false, features = ["nolog"] }
|
|
40
|
+
rusqlite = { version = "0.40", features = ["bundled"] }
|
|
39
41
|
|
|
40
42
|
[profile.release]
|
|
41
43
|
strip = "symbols"
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Copyright (C) 2026 Axis Communications AB, Lund, Sweden
|
|
2
|
+
#
|
|
3
|
+
# Use of this source code is governed by an MIT-style
|
|
4
|
+
# license that can be found in the LICENSE file or at
|
|
5
|
+
# https://opensource.org/licenses/MIT.
|
|
6
|
+
|
|
7
|
+
"""Type stub for the Rust-native asanypath_native extension module."""
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
class DownloadCache:
|
|
12
|
+
def __init__(self, directory: str, size_limit: int) -> None: ...
|
|
13
|
+
@property
|
|
14
|
+
def size_limit(self) -> int: ...
|
|
15
|
+
def get(self, key: str) -> bytes | None: ...
|
|
16
|
+
def set(self, key: str, value: bytes, expire: float | None = None) -> None: ...
|
|
17
|
+
def delete(self, key: str) -> None: ...
|
|
18
|
+
def clear(self) -> None: ...
|
|
19
|
+
def close(self) -> None: ...
|
|
20
|
+
|
|
21
|
+
# -- S3 --
|
|
22
|
+
async def s3_get_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
23
|
+
async def s3_put_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
24
|
+
async def s3_create_multipart(*args: Any, **kwargs: Any) -> Any: ...
|
|
25
|
+
async def s3_upload_part(*args: Any, **kwargs: Any) -> Any: ...
|
|
26
|
+
async def s3_complete_multipart(*args: Any, **kwargs: Any) -> Any: ...
|
|
27
|
+
async def s3_abort_multipart(*args: Any, **kwargs: Any) -> Any: ...
|
|
28
|
+
async def s3_copy_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
29
|
+
async def s3_delete_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
30
|
+
async def s3_exists_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
31
|
+
async def s3_list_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
32
|
+
async def s3_head_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
33
|
+
async def s3_is_dir(*args: Any, **kwargs: Any) -> Any: ...
|
|
34
|
+
async def s3_is_dir_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
35
|
+
async def s3_list_buckets(*args: Any, **kwargs: Any) -> Any: ...
|
|
36
|
+
async def s3_get_acl(*args: Any, **kwargs: Any) -> Any: ...
|
|
37
|
+
async def s3_put_acl(*args: Any, **kwargs: Any) -> Any: ...
|
|
38
|
+
async def s3_get_credentials(
|
|
39
|
+
region_override: str | None,
|
|
40
|
+
access_key: str | None,
|
|
41
|
+
secret_key: str | None,
|
|
42
|
+
session_token: str | None,
|
|
43
|
+
profile: str | None = None,
|
|
44
|
+
) -> tuple[str, str, str | None, str, str | None]: ...
|
|
45
|
+
def s3_presign(
|
|
46
|
+
endpoint: str,
|
|
47
|
+
bucket: str,
|
|
48
|
+
key: str,
|
|
49
|
+
region: str,
|
|
50
|
+
access_key: str,
|
|
51
|
+
secret_key: str,
|
|
52
|
+
session_token: str | None = None,
|
|
53
|
+
method: str | None = None,
|
|
54
|
+
expires: int | None = None,
|
|
55
|
+
) -> str: ...
|
|
56
|
+
|
|
57
|
+
# -- GCS --
|
|
58
|
+
async def gcs_get_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
59
|
+
async def gcs_put_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
60
|
+
async def gcs_start_resumable(*args: Any, **kwargs: Any) -> Any: ...
|
|
61
|
+
async def gcs_upload_chunk(*args: Any, **kwargs: Any) -> Any: ...
|
|
62
|
+
async def gcs_copy_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
63
|
+
async def gcs_delete_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
64
|
+
async def gcs_exists_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
65
|
+
async def gcs_list_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
66
|
+
async def gcs_head(*args: Any, **kwargs: Any) -> Any: ...
|
|
67
|
+
async def gcs_head_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
68
|
+
async def gcs_is_dir(*args: Any, **kwargs: Any) -> Any: ...
|
|
69
|
+
async def gcs_is_dir_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
70
|
+
async def gcs_list_buckets(*args: Any, **kwargs: Any) -> Any: ...
|
|
71
|
+
def gcs_presign(
|
|
72
|
+
bucket: str,
|
|
73
|
+
object_path: str,
|
|
74
|
+
service_account_json: str,
|
|
75
|
+
method: str | None = None,
|
|
76
|
+
expires: int | None = None,
|
|
77
|
+
) -> str: ...
|
|
78
|
+
|
|
79
|
+
# -- Azure --
|
|
80
|
+
async def az_get_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
81
|
+
async def az_put_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
82
|
+
async def az_put_block(*args: Any, **kwargs: Any) -> Any: ...
|
|
83
|
+
async def az_put_block_list(*args: Any, **kwargs: Any) -> Any: ...
|
|
84
|
+
async def az_copy_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
85
|
+
async def az_delete_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
86
|
+
async def az_exists_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
87
|
+
async def az_list_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
88
|
+
async def az_head_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
89
|
+
async def az_is_dir(*args: Any, **kwargs: Any) -> Any: ...
|
|
90
|
+
async def az_is_dir_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
91
|
+
async def az_list_containers(*args: Any, **kwargs: Any) -> Any: ...
|
|
92
|
+
def az_presign(
|
|
93
|
+
endpoint: str,
|
|
94
|
+
container: str,
|
|
95
|
+
blob_path: str,
|
|
96
|
+
account_name: str,
|
|
97
|
+
account_key: str | None = None,
|
|
98
|
+
sas_token: str | None = None,
|
|
99
|
+
method: str | None = None,
|
|
100
|
+
expires: int | None = None,
|
|
101
|
+
) -> str: ...
|
|
102
|
+
|
|
103
|
+
# -- Artifactory --
|
|
104
|
+
async def art_get_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
105
|
+
async def art_put_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
106
|
+
async def art_put_stream(*args: Any, **kwargs: Any) -> Any: ...
|
|
107
|
+
async def art_copy_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
108
|
+
async def art_delete_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
109
|
+
async def art_exists_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
110
|
+
async def art_list_batch(*args: Any, **kwargs: Any) -> Any: ...
|
|
111
|
+
async def art_list_repos(*args: Any, **kwargs: Any) -> Any: ...
|
|
112
|
+
async def art_storage_info(*args: Any, **kwargs: Any) -> Any: ...
|
|
113
|
+
|
|
114
|
+
# -- HTTP --
|
|
115
|
+
async def http_get(*args: Any, **kwargs: Any) -> Any: ...
|
|
116
|
+
async def http_put(*args: Any, **kwargs: Any) -> Any: ...
|
|
117
|
+
async def http_post(*args: Any, **kwargs: Any) -> Any: ...
|
|
118
|
+
async def http_delete(*args: Any, **kwargs: Any) -> Any: ...
|
|
119
|
+
async def http_head(*args: Any, **kwargs: Any) -> Any: ...
|
|
120
|
+
async def http_patch(*args: Any, **kwargs: Any) -> Any: ...
|
|
121
|
+
async def http_options(*args: Any, **kwargs: Any) -> Any: ...
|
|
122
|
+
async def http_exists(*args: Any, **kwargs: Any) -> Any: ...
|
|
123
|
+
async def http_scrape_links(*args: Any, **kwargs: Any) -> Any: ...
|
|
124
|
+
async def http_request(*args: Any, **kwargs: Any) -> Any: ...
|
|
125
|
+
|
|
126
|
+
# -- Unified --
|
|
127
|
+
async def range_read(path: str, start: int, end: int, **kwargs: Any) -> bytes: ...
|
|
128
|
+
|
|
129
|
+
# -- SSH / SFTP --
|
|
130
|
+
async def ssh_read(*args: Any, **kwargs: Any) -> bytes: ...
|
|
131
|
+
async def ssh_read_range(*args: Any, **kwargs: Any) -> bytes: ...
|
|
132
|
+
async def ssh_write(*args: Any, **kwargs: Any) -> int: ...
|
|
133
|
+
async def ssh_write_chunk(*args: Any, **kwargs: Any) -> int: ...
|
|
134
|
+
async def ssh_exists(*args: Any, **kwargs: Any) -> bool: ...
|
|
135
|
+
async def ssh_stat(*args: Any, **kwargs: Any) -> Any: ...
|
|
136
|
+
async def ssh_lstat(*args: Any, **kwargs: Any) -> Any: ...
|
|
137
|
+
async def ssh_setstat(*args: Any, **kwargs: Any) -> None: ...
|
|
138
|
+
async def ssh_list(*args: Any, **kwargs: Any) -> Any: ...
|
|
139
|
+
async def ssh_mkdir(*args: Any, **kwargs: Any) -> None: ...
|
|
140
|
+
async def ssh_rmdir(*args: Any, **kwargs: Any) -> None: ...
|
|
141
|
+
async def ssh_unlink(*args: Any, **kwargs: Any) -> None: ...
|
|
142
|
+
async def ssh_rename(*args: Any, **kwargs: Any) -> None: ...
|
|
143
|
+
def ssh_resolve_config(
|
|
144
|
+
host: str, config_paths: list[str]
|
|
145
|
+
) -> tuple[str | None, int | None, str | None, str | None]: ...
|
|
146
|
+
def ssh_disconnect_all() -> None: ...
|
|
@@ -19,7 +19,7 @@ use pyo3::prelude::*;
|
|
|
19
19
|
use serde::Deserialize;
|
|
20
20
|
use std::collections::HashMap;
|
|
21
21
|
|
|
22
|
-
use crate::http::{bearer_headers, do_request_light, status_to_pyerr};
|
|
22
|
+
use crate::http::{bearer_headers, do_request_light, do_request_stream_file, status_to_pyerr};
|
|
23
23
|
|
|
24
24
|
// ---------------------------------------------------------------------------
|
|
25
25
|
// JSON response types for Artifactory Storage API
|
|
@@ -465,6 +465,44 @@ pub fn art_put_batch<'py>(
|
|
|
465
465
|
})
|
|
466
466
|
}
|
|
467
467
|
|
|
468
|
+
/// Stream-upload a single file by PUT (body framed from disk; bounded memory).
|
|
469
|
+
/// Artifactory has no multipart API, so a large object is sent as one streamed PUT.
|
|
470
|
+
#[pyfunction]
|
|
471
|
+
#[pyo3(signature = (base_url, key, file_path, size, token, options_json=None, use_h2=None))]
|
|
472
|
+
pub fn art_put_stream<'py>(
|
|
473
|
+
py: Python<'py>,
|
|
474
|
+
base_url: String,
|
|
475
|
+
key: String,
|
|
476
|
+
file_path: String,
|
|
477
|
+
size: u64,
|
|
478
|
+
token: String,
|
|
479
|
+
options_json: Option<String>,
|
|
480
|
+
use_h2: Option<bool>,
|
|
481
|
+
) -> PyResult<Bound<'py, PyAny>> {
|
|
482
|
+
let h2 = use_h2.unwrap_or(false);
|
|
483
|
+
pyo3_async_runtimes::tokio::future_into_py(py, async move {
|
|
484
|
+
let options: crate::backend::UploadOptions =
|
|
485
|
+
sonic_rs::from_str(&options_json.unwrap_or_else(|| "{}".to_string()))
|
|
486
|
+
.map_err(|e| PyValueError::new_err(format!("invalid backend_options: {e}")))?;
|
|
487
|
+
crate::backend::require_empty_provider(&options)?;
|
|
488
|
+
let creds = art_creds!(base_url, token);
|
|
489
|
+
let url = crate::backend::append_query(&creds.content_url(&key), &options.query);
|
|
490
|
+
let mut headers = creds.auth_headers();
|
|
491
|
+
headers.push((
|
|
492
|
+
"content-type".to_string(),
|
|
493
|
+
"application/octet-stream".to_string(),
|
|
494
|
+
));
|
|
495
|
+
crate::backend::merge_user_headers(&mut headers, &options)?;
|
|
496
|
+
let (status, body) = do_request_stream_file("PUT", &url, &headers, &file_path, size, h2)
|
|
497
|
+
.await
|
|
498
|
+
.map_err(PyRuntimeError::new_err)?;
|
|
499
|
+
if !status.is_success() {
|
|
500
|
+
return Err(status_to_pyerr(status, &creds.error_path(&key), &body));
|
|
501
|
+
}
|
|
502
|
+
Ok(())
|
|
503
|
+
})
|
|
504
|
+
}
|
|
505
|
+
|
|
468
506
|
/// Copy multiple files concurrently (server-side). Pairs are `(src, dst)`.
|
|
469
507
|
#[pyfunction]
|
|
470
508
|
pub fn art_copy_batch<'py>(
|
|
@@ -943,6 +943,97 @@ pub fn az_put_batch<'py>(
|
|
|
943
943
|
})
|
|
944
944
|
}
|
|
945
945
|
|
|
946
|
+
// ---------------------------------------------------------------------------
|
|
947
|
+
// Block blob upload (orchestrated from Python): stage blocks, then commit list
|
|
948
|
+
// ---------------------------------------------------------------------------
|
|
949
|
+
|
|
950
|
+
/// Stage one block for a block blob. `block_id` is the raw (pre-URL-encode) id.
|
|
951
|
+
#[pyfunction]
|
|
952
|
+
#[pyo3(signature = (endpoint, container, blob, block_id, data, account_name, account_key=None, sas_token=None, use_h2=None))]
|
|
953
|
+
pub fn az_put_block<'py>(
|
|
954
|
+
py: Python<'py>,
|
|
955
|
+
endpoint: String,
|
|
956
|
+
container: String,
|
|
957
|
+
blob: String,
|
|
958
|
+
block_id: String,
|
|
959
|
+
data: Vec<u8>,
|
|
960
|
+
account_name: String,
|
|
961
|
+
account_key: Option<String>,
|
|
962
|
+
sas_token: Option<String>,
|
|
963
|
+
use_h2: Option<bool>,
|
|
964
|
+
) -> PyResult<Bound<'py, PyAny>> {
|
|
965
|
+
let h2 = use_h2.unwrap_or(false);
|
|
966
|
+
pyo3_async_runtimes::tokio::future_into_py(py, async move {
|
|
967
|
+
let creds = az_creds!(endpoint, container, account_name, account_key, sas_token);
|
|
968
|
+
let base = creds.blob_url(&blob);
|
|
969
|
+
let sep = if base.contains('?') { "&" } else { "?" };
|
|
970
|
+
let url = format!(
|
|
971
|
+
"{}{}comp=block&blockid={}",
|
|
972
|
+
base,
|
|
973
|
+
sep,
|
|
974
|
+
urlencoding::encode(&block_id)
|
|
975
|
+
);
|
|
976
|
+
let mut headers = vec![("content-length".to_string(), data.len().to_string())];
|
|
977
|
+
let params = [("blockid", block_id.as_str()), ("comp", "block")];
|
|
978
|
+
creds.sign("PUT", &url, &mut headers, Some(¶ms));
|
|
979
|
+
let (status, body) = do_request_light("PUT", &url, &headers, Some(Bytes::from(data)), h2)
|
|
980
|
+
.await
|
|
981
|
+
.map_err(PyRuntimeError::new_err)?;
|
|
982
|
+
if !status.is_success() {
|
|
983
|
+
return Err(status_to_pyerr(status, &creds.error_path(&blob), &body));
|
|
984
|
+
}
|
|
985
|
+
Ok(())
|
|
986
|
+
})
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/// Commit a block blob from the staged block ids (in order).
|
|
990
|
+
#[pyfunction]
|
|
991
|
+
#[pyo3(signature = (endpoint, container, blob, block_ids, account_name, account_key=None, sas_token=None, options_json=None, use_h2=None))]
|
|
992
|
+
pub fn az_put_block_list<'py>(
|
|
993
|
+
py: Python<'py>,
|
|
994
|
+
endpoint: String,
|
|
995
|
+
container: String,
|
|
996
|
+
blob: String,
|
|
997
|
+
block_ids: Vec<String>,
|
|
998
|
+
account_name: String,
|
|
999
|
+
account_key: Option<String>,
|
|
1000
|
+
sas_token: Option<String>,
|
|
1001
|
+
options_json: Option<String>,
|
|
1002
|
+
use_h2: Option<bool>,
|
|
1003
|
+
) -> PyResult<Bound<'py, PyAny>> {
|
|
1004
|
+
let h2 = use_h2.unwrap_or(false);
|
|
1005
|
+
pyo3_async_runtimes::tokio::future_into_py(py, async move {
|
|
1006
|
+
let options: crate::backend::UploadOptions =
|
|
1007
|
+
sonic_rs::from_str(&options_json.unwrap_or_else(|| "{}".to_string()))
|
|
1008
|
+
.map_err(|e| PyValueError::new_err(format!("invalid backend_options: {e}")))?;
|
|
1009
|
+
crate::backend::require_empty_provider(&options)?;
|
|
1010
|
+
let creds = az_creds!(endpoint, container, account_name, account_key, sas_token);
|
|
1011
|
+
let base = creds.blob_url(&blob);
|
|
1012
|
+
let sep = if base.contains('?') { "&" } else { "?" };
|
|
1013
|
+
let url = format!("{}{}comp=blocklist", base, sep);
|
|
1014
|
+
let mut xml = String::from("<?xml version=\"1.0\" encoding=\"utf-8\"?><BlockList>");
|
|
1015
|
+
for id in &block_ids {
|
|
1016
|
+
xml.push_str(&format!("<Latest>{}</Latest>", id));
|
|
1017
|
+
}
|
|
1018
|
+
xml.push_str("</BlockList>");
|
|
1019
|
+
let body = Bytes::from(xml.into_bytes());
|
|
1020
|
+
let mut headers = vec![
|
|
1021
|
+
("content-length".to_string(), body.len().to_string()),
|
|
1022
|
+
("content-type".to_string(), "application/xml".to_string()),
|
|
1023
|
+
];
|
|
1024
|
+
crate::backend::merge_user_headers(&mut headers, &options)?;
|
|
1025
|
+
let params = [("comp", "blocklist")];
|
|
1026
|
+
creds.sign("PUT", &url, &mut headers, Some(¶ms));
|
|
1027
|
+
let (status, resp) = do_request_light("PUT", &url, &headers, Some(body), h2)
|
|
1028
|
+
.await
|
|
1029
|
+
.map_err(PyRuntimeError::new_err)?;
|
|
1030
|
+
if !status.is_success() {
|
|
1031
|
+
return Err(status_to_pyerr(status, &creds.error_path(&blob), &resp));
|
|
1032
|
+
}
|
|
1033
|
+
Ok(())
|
|
1034
|
+
})
|
|
1035
|
+
}
|
|
1036
|
+
|
|
946
1037
|
#[pyfunction]
|
|
947
1038
|
pub fn az_copy_batch<'py>(
|
|
948
1039
|
py: Python<'py>,
|