fallbacks3 0.1.0__tar.gz → 0.2.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.
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/PKG-INFO +30 -2
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/README.md +28 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/storage.py +24 -3
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3.egg-info/PKG-INFO +30 -2
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/pyproject.toml +4 -4
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/__init__.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/config.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/provider/__init__.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/provider/config_credentials.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/provider/provider.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/utils/__init__.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3/utils/uri.py +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3.egg-info/SOURCES.txt +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3.egg-info/dependency_links.txt +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3.egg-info/requires.txt +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/fallbacks3.egg-info/top_level.txt +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/setup.cfg +0 -0
- {fallbacks3-0.1.0 → fallbacks3-0.2.0}/tests/test_fallbacks3.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fallbacks3
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: S3-compatible storage library with automatic fallback support
|
|
5
5
|
Author-email: Mila de Oliveira <mila.oliveira@palver.com.br>
|
|
6
6
|
Project-URL: Homepage, https://github.com/palverdata/fallbacks3
|
|
7
7
|
Project-URL: Repository, https://github.com/palverdata/fallbacks3
|
|
8
8
|
Project-URL: Issues, https://github.com/palverdata/fallbacks3/issues
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
Requires-Dist: boto3>=1.26.0
|
|
12
12
|
Requires-Dist: pydantic-settings>=2.0.0
|
|
@@ -85,6 +85,12 @@ stored_file_uri = storage.upload_file(
|
|
|
85
85
|
)
|
|
86
86
|
print(uri) # "ps3://palver-whatsapp/audio.mp3"
|
|
87
87
|
|
|
88
|
+
# Async upload (for async environments)
|
|
89
|
+
stored_file_uri = await storage.upload_file_async(
|
|
90
|
+
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
91
|
+
local_file_path="/local/path/audio.mp3"
|
|
92
|
+
)
|
|
93
|
+
|
|
88
94
|
# Download a file
|
|
89
95
|
downloaded_file_path = storage.download_file(
|
|
90
96
|
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
@@ -115,6 +121,28 @@ stored_file_path = storage.upload_file(
|
|
|
115
121
|
|
|
116
122
|
Raises an exception if both primary and fallback providers fail.
|
|
117
123
|
|
|
124
|
+
#### Async Upload
|
|
125
|
+
|
|
126
|
+
For async environments, use `upload_file_async()`:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import asyncio
|
|
130
|
+
from fallbacks3 import Storage
|
|
131
|
+
|
|
132
|
+
storage = Storage()
|
|
133
|
+
|
|
134
|
+
async def upload():
|
|
135
|
+
stored_file_uri = await storage.upload_file_async(
|
|
136
|
+
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
137
|
+
local_file_path="/local/path/audio.mp3"
|
|
138
|
+
)
|
|
139
|
+
print(stored_file_uri) # "ps3://palver-whatsapp/audio.mp3"
|
|
140
|
+
|
|
141
|
+
asyncio.run(upload())
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The async method also supports automatic fallback, just like the synchronous version.
|
|
145
|
+
|
|
118
146
|
### Download and Signed URLs
|
|
119
147
|
|
|
120
148
|
Download and signed URL generation use the provider specified in the remote file URI.
|
|
@@ -64,6 +64,12 @@ stored_file_uri = storage.upload_file(
|
|
|
64
64
|
)
|
|
65
65
|
print(uri) # "ps3://palver-whatsapp/audio.mp3"
|
|
66
66
|
|
|
67
|
+
# Async upload (for async environments)
|
|
68
|
+
stored_file_uri = await storage.upload_file_async(
|
|
69
|
+
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
70
|
+
local_file_path="/local/path/audio.mp3"
|
|
71
|
+
)
|
|
72
|
+
|
|
67
73
|
# Download a file
|
|
68
74
|
downloaded_file_path = storage.download_file(
|
|
69
75
|
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
@@ -94,6 +100,28 @@ stored_file_path = storage.upload_file(
|
|
|
94
100
|
|
|
95
101
|
Raises an exception if both primary and fallback providers fail.
|
|
96
102
|
|
|
103
|
+
#### Async Upload
|
|
104
|
+
|
|
105
|
+
For async environments, use `upload_file_async()`:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import asyncio
|
|
109
|
+
from fallbacks3 import Storage
|
|
110
|
+
|
|
111
|
+
storage = Storage()
|
|
112
|
+
|
|
113
|
+
async def upload():
|
|
114
|
+
stored_file_uri = await storage.upload_file_async(
|
|
115
|
+
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
116
|
+
local_file_path="/local/path/audio.mp3"
|
|
117
|
+
)
|
|
118
|
+
print(stored_file_uri) # "ps3://palver-whatsapp/audio.mp3"
|
|
119
|
+
|
|
120
|
+
asyncio.run(upload())
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The async method also supports automatic fallback, just like the synchronous version.
|
|
124
|
+
|
|
97
125
|
### Download and Signed URLs
|
|
98
126
|
|
|
99
127
|
Download and signed URL generation use the provider specified in the remote file URI.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
from fallbacks3.config import config
|
|
2
3
|
from fallbacks3.provider import S3Provider
|
|
3
4
|
from fallbacks3.utils.uri import build_provider_credentials, parse_uri
|
|
4
|
-
from typing import Dict, Tuple
|
|
5
5
|
from urllib.parse import ParseResult
|
|
6
6
|
|
|
7
7
|
|
|
@@ -27,7 +27,7 @@ class Storage:
|
|
|
27
27
|
Raises:
|
|
28
28
|
ValueError: If fallback_provider not found in providers
|
|
29
29
|
"""
|
|
30
|
-
self.providers:
|
|
30
|
+
self.providers: dict[str, S3Provider] = {}
|
|
31
31
|
|
|
32
32
|
# Parse and initialize all providers
|
|
33
33
|
for provider in providers.split(","):
|
|
@@ -89,6 +89,27 @@ class Storage:
|
|
|
89
89
|
)
|
|
90
90
|
raise
|
|
91
91
|
|
|
92
|
+
async def upload_file_async(
|
|
93
|
+
self, remote_file_uri: str, local_file_path: str
|
|
94
|
+
) -> str:
|
|
95
|
+
"""Upload a file asynchronously with automatic fallback on failure.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
remote_file_uri: Remote file URI in format <provider>://<bucket>/<file_path>
|
|
99
|
+
Example: "ps3://palver-whatsapp/file.mp4"
|
|
100
|
+
local_file_path: Local path to the file to upload
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
URI of uploaded file in format: <provider>://<bucket>/<file_path>
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
ValueError: If provider is not configured
|
|
107
|
+
Exception: If upload fails on both primary and fallback providers
|
|
108
|
+
"""
|
|
109
|
+
return await asyncio.to_thread(
|
|
110
|
+
self.upload_file, remote_file_uri, local_file_path
|
|
111
|
+
)
|
|
112
|
+
|
|
92
113
|
def download_file(self, remote_file_uri: str, local_file_path: str) -> str:
|
|
93
114
|
"""Download a file from storage.
|
|
94
115
|
|
|
@@ -133,7 +154,7 @@ class Storage:
|
|
|
133
154
|
expiration=expiration,
|
|
134
155
|
)
|
|
135
156
|
|
|
136
|
-
def _resolve_uri(self, uri: str) ->
|
|
157
|
+
def _resolve_uri(self, uri: str) -> tuple[ParseResult, S3Provider]:
|
|
137
158
|
"""Parse and validate URI, then return parsed URI and provider.
|
|
138
159
|
|
|
139
160
|
Args:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fallbacks3
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: S3-compatible storage library with automatic fallback support
|
|
5
5
|
Author-email: Mila de Oliveira <mila.oliveira@palver.com.br>
|
|
6
6
|
Project-URL: Homepage, https://github.com/palverdata/fallbacks3
|
|
7
7
|
Project-URL: Repository, https://github.com/palverdata/fallbacks3
|
|
8
8
|
Project-URL: Issues, https://github.com/palverdata/fallbacks3/issues
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
Requires-Dist: boto3>=1.26.0
|
|
12
12
|
Requires-Dist: pydantic-settings>=2.0.0
|
|
@@ -85,6 +85,12 @@ stored_file_uri = storage.upload_file(
|
|
|
85
85
|
)
|
|
86
86
|
print(uri) # "ps3://palver-whatsapp/audio.mp3"
|
|
87
87
|
|
|
88
|
+
# Async upload (for async environments)
|
|
89
|
+
stored_file_uri = await storage.upload_file_async(
|
|
90
|
+
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
91
|
+
local_file_path="/local/path/audio.mp3"
|
|
92
|
+
)
|
|
93
|
+
|
|
88
94
|
# Download a file
|
|
89
95
|
downloaded_file_path = storage.download_file(
|
|
90
96
|
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
@@ -115,6 +121,28 @@ stored_file_path = storage.upload_file(
|
|
|
115
121
|
|
|
116
122
|
Raises an exception if both primary and fallback providers fail.
|
|
117
123
|
|
|
124
|
+
#### Async Upload
|
|
125
|
+
|
|
126
|
+
For async environments, use `upload_file_async()`:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import asyncio
|
|
130
|
+
from fallbacks3 import Storage
|
|
131
|
+
|
|
132
|
+
storage = Storage()
|
|
133
|
+
|
|
134
|
+
async def upload():
|
|
135
|
+
stored_file_uri = await storage.upload_file_async(
|
|
136
|
+
remote_file_uri="ps3://palver-whatsapp/audio.mp3",
|
|
137
|
+
local_file_path="/local/path/audio.mp3"
|
|
138
|
+
)
|
|
139
|
+
print(stored_file_uri) # "ps3://palver-whatsapp/audio.mp3"
|
|
140
|
+
|
|
141
|
+
asyncio.run(upload())
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The async method also supports automatic fallback, just like the synchronous version.
|
|
145
|
+
|
|
118
146
|
### Download and Signed URLs
|
|
119
147
|
|
|
120
148
|
Download and signed URL generation use the provider specified in the remote file URI.
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "fallbacks3"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "S3-compatible storage library with automatic fallback support"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
11
|
authors = [
|
|
12
12
|
{name = "Mila de Oliveira", email = "mila.oliveira@palver.com.br"}
|
|
13
13
|
]
|
|
@@ -45,8 +45,8 @@ python_functions = ["test_*"]
|
|
|
45
45
|
|
|
46
46
|
[tool.black]
|
|
47
47
|
line-length = 88
|
|
48
|
-
target-version = ["
|
|
48
|
+
target-version = ["py39"]
|
|
49
49
|
|
|
50
50
|
[tool.ruff]
|
|
51
51
|
line-length = 88
|
|
52
|
-
target-version = "
|
|
52
|
+
target-version = "py39"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|