vaultsens-sdk 0.1.1__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.
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: vaultsens-sdk
3
+ Version: 0.1.1
4
+ Summary: VaultSens SDK for API key uploads and file management
5
+ Author: VaultSens
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://vaultsens.com/
8
+ Project-URL: Repository, https://github.com/vaultsens/vaultsens-sdk-python
9
+ Keywords: vaultsens,sdk,storage,upload
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: requests>=2.31
15
+
16
+ # vaultsens-sdk
17
+
18
+ Python SDK for VaultSens. API key + secret authentication with file upload and management helpers.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install vaultsens-sdk
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ from vaultsens_sdk import VaultSensClient
30
+
31
+ client = VaultSensClient(
32
+ base_url="https://api.vaultsens.com",
33
+ api_key="fs_xxx",
34
+ api_secret="sk_xxx",
35
+ )
36
+
37
+ response = client.upload_file("./photo.png", name="marketing-hero", transform=True)
38
+ print(response)
39
+ ```
40
+
41
+ ## API
42
+
43
+ - `upload_file(path, name=None, transform=None)`
44
+ - `upload_files(paths, name=None, transform=None)`
45
+ - `list_files()`
46
+ - `get_file_metadata(file_id)`
47
+ - `update_file(file_id, path, name=None, transform=None)`
48
+ - `delete_file(file_id)`
49
+ - `get_metrics()`
50
+ - `build_file_url(file_id, **options)`
51
+
52
+ ## Docs
53
+
54
+ https://vaultsens.com/
@@ -0,0 +1,39 @@
1
+ # vaultsens-sdk
2
+
3
+ Python SDK for VaultSens. API key + secret authentication with file upload and management helpers.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install vaultsens-sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from vaultsens_sdk import VaultSensClient
15
+
16
+ client = VaultSensClient(
17
+ base_url="https://api.vaultsens.com",
18
+ api_key="fs_xxx",
19
+ api_secret="sk_xxx",
20
+ )
21
+
22
+ response = client.upload_file("./photo.png", name="marketing-hero", transform=True)
23
+ print(response)
24
+ ```
25
+
26
+ ## API
27
+
28
+ - `upload_file(path, name=None, transform=None)`
29
+ - `upload_files(paths, name=None, transform=None)`
30
+ - `list_files()`
31
+ - `get_file_metadata(file_id)`
32
+ - `update_file(file_id, path, name=None, transform=None)`
33
+ - `delete_file(file_id)`
34
+ - `get_metrics()`
35
+ - `build_file_url(file_id, **options)`
36
+
37
+ ## Docs
38
+
39
+ https://vaultsens.com/
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "vaultsens-sdk"
7
+ version = "0.1.1"
8
+ description = "VaultSens SDK for API key uploads and file management"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "VaultSens" }
14
+ ]
15
+ keywords = ["vaultsens", "sdk", "storage", "upload"]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "Operating System :: OS Independent"
19
+ ]
20
+ dependencies = ["requests>=2.31"]
21
+
22
+ [project.urls]
23
+ Homepage = "https://vaultsens.com/"
24
+ Repository = "https://github.com/vaultsens/vaultsens-sdk-python"
25
+
26
+ [tool.setuptools.packages.find]
27
+ include = ["vaultsens_sdk*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from .client import VaultSensClient, VaultSensError
2
+
3
+ __all__ = ["VaultSensClient", "VaultSensError"]
@@ -0,0 +1,199 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Any, Dict, Optional
5
+
6
+ import requests
7
+
8
+
9
+ def _resolve_error_code(status: int, message: str) -> str:
10
+ m = message.lower()
11
+ if status == 413 and "storage limit" in m:
12
+ return "STORAGE_LIMIT"
13
+ if status == 413:
14
+ return "FILE_TOO_LARGE"
15
+ if status == 415:
16
+ return "MIME_TYPE_NOT_ALLOWED"
17
+ if status == 402:
18
+ return "SUBSCRIPTION_INACTIVE"
19
+ if status == 403 and "compression" in m:
20
+ return "COMPRESSION_NOT_ALLOWED"
21
+ if status == 403 and "folder" in m:
22
+ return "FOLDER_COUNT_LIMIT"
23
+ if status == 403 and ("file" in m or "maximum" in m):
24
+ return "FILE_COUNT_LIMIT"
25
+ if status == 403 and "email" in m:
26
+ return "EMAIL_NOT_VERIFIED"
27
+ if status == 400 and "already registered" in m:
28
+ return "EMAIL_ALREADY_REGISTERED"
29
+ if status == 400 and ("invalid email or password" in m or "invalid credentials" in m):
30
+ return "INVALID_CREDENTIALS"
31
+ if status == 400 and "otp" in m:
32
+ return "INVALID_OTP"
33
+ if status == 401:
34
+ return "UNAUTHORIZED"
35
+ if status == 404:
36
+ return "NOT_FOUND"
37
+ return "UNKNOWN"
38
+
39
+
40
+ @dataclass
41
+ class VaultSensError(Exception):
42
+ """
43
+ Raised when the VaultSens API returns an error response.
44
+
45
+ Attributes:
46
+ message: Human-readable error description from the API.
47
+ status: HTTP status code.
48
+ code: Machine-readable error code (e.g. ``"FILE_TOO_LARGE"``).
49
+ data: Raw response payload, if any.
50
+
51
+ Error codes:
52
+ FILE_TOO_LARGE – 413: file exceeds plan's maxFileSizeBytes
53
+ STORAGE_LIMIT – 413: total storage quota exceeded
54
+ FILE_COUNT_LIMIT – 403: plan's maxFilesCount reached
55
+ MIME_TYPE_NOT_ALLOWED – 415: file type blocked by plan
56
+ COMPRESSION_NOT_ALLOWED – 403: compression level not permitted by plan
57
+ SUBSCRIPTION_INACTIVE – 402: user subscription is not active
58
+ FOLDER_COUNT_LIMIT – 403: plan's maxFoldersCount reached
59
+ EMAIL_ALREADY_REGISTERED – 400: duplicate email on register
60
+ EMAIL_NOT_VERIFIED – 403: login before verifying email
61
+ INVALID_CREDENTIALS – 400: wrong email or password
62
+ INVALID_OTP – 400: bad/expired verification code
63
+ UNAUTHORIZED – 401
64
+ NOT_FOUND – 404
65
+ UNKNOWN – anything else
66
+ """
67
+
68
+ message: str
69
+ status: int
70
+ data: Optional[Any] = None
71
+ code: str = field(init=False)
72
+
73
+ def __post_init__(self) -> None:
74
+ self.code = _resolve_error_code(self.status, self.message)
75
+
76
+ def __str__(self) -> str:
77
+ return f"{self.status} [{self.code}]: {self.message}"
78
+
79
+
80
+ class VaultSensClient:
81
+ def __init__(
82
+ self,
83
+ base_url: str,
84
+ api_key: Optional[str] = None,
85
+ api_secret: Optional[str] = None,
86
+ timeout: int = 30,
87
+ ) -> None:
88
+ self.base_url = base_url.rstrip("/")
89
+ self.api_key = api_key
90
+ self.api_secret = api_secret
91
+ self.timeout = timeout
92
+
93
+ def set_auth(self, api_key: str, api_secret: str) -> None:
94
+ self.api_key = api_key
95
+ self.api_secret = api_secret
96
+
97
+ def _headers(self) -> Dict[str, str]:
98
+ if not self.api_key or not self.api_secret:
99
+ raise VaultSensError("API key and secret are required", 401)
100
+ return {
101
+ "x-api-key": self.api_key,
102
+ "x-api-secret": self.api_secret,
103
+ }
104
+
105
+ def _request(self, method: str, path: str, **kwargs: Any) -> Any:
106
+ url = f"{self.base_url}{path}"
107
+ response = requests.request(method, url, headers=self._headers(), timeout=self.timeout, **kwargs)
108
+ try:
109
+ payload = response.json()
110
+ except ValueError:
111
+ payload = response.text
112
+
113
+ if not response.ok:
114
+ message = payload.get("message") if isinstance(payload, dict) else response.reason
115
+ raise VaultSensError(message or response.reason, response.status_code, payload)
116
+
117
+ return payload
118
+
119
+ def upload_file(self, file_path: str, name: Optional[str] = None, compression: Optional[str] = None, folder_id: Optional[str] = None) -> Any:
120
+ files = {"file": open(file_path, "rb")}
121
+ data: Dict[str, Any] = {}
122
+ if name:
123
+ data["name"] = name
124
+ if compression is not None:
125
+ data["compression"] = compression
126
+ if folder_id is not None:
127
+ data["folderId"] = folder_id
128
+ try:
129
+ return self._request("POST", "/api/v1/files/upload", files=files, data=data)
130
+ finally:
131
+ files["file"].close()
132
+
133
+ def upload_files(self, file_paths: list[str], name: Optional[str] = None, compression: Optional[str] = None, folder_id: Optional[str] = None) -> Any:
134
+ files = [("files", open(path, "rb")) for path in file_paths]
135
+ data: Dict[str, Any] = {}
136
+ if name:
137
+ data["name"] = name
138
+ if compression is not None:
139
+ data["compression"] = compression
140
+ if folder_id is not None:
141
+ data["folderId"] = folder_id
142
+ try:
143
+ return self._request("POST", "/api/v1/files/upload", files=files, data=data)
144
+ finally:
145
+ for _, fh in files:
146
+ fh.close()
147
+
148
+ def list_files(self, folder_id: Optional[str] = None) -> Any:
149
+ path = f"/api/v1/files?folderId={folder_id}" if folder_id else "/api/v1/files"
150
+ return self._request("GET", path)
151
+
152
+ def list_folders(self) -> Any:
153
+ return self._request("GET", "/api/v1/folders")
154
+
155
+ def create_folder(self, name: str, parent_id: Optional[str] = None) -> Any:
156
+ data: Dict[str, Any] = {"name": name}
157
+ if parent_id is not None:
158
+ data["parentId"] = parent_id
159
+ return self._request("POST", "/api/v1/folders", json=data)
160
+
161
+ def rename_folder(self, folder_id: str, name: str) -> Any:
162
+ return self._request("PATCH", f"/api/v1/folders/{folder_id}", json={"name": name})
163
+
164
+ def delete_folder(self, folder_id: str) -> Any:
165
+ return self._request("DELETE", f"/api/v1/folders/{folder_id}")
166
+
167
+ def get_file_metadata(self, file_id: str) -> Any:
168
+ return self._request("GET", f"/api/v1/files/metadata/{file_id}")
169
+
170
+ def update_file(
171
+ self,
172
+ file_id: str,
173
+ file_path: str,
174
+ name: Optional[str] = None,
175
+ compression: Optional[str] = None,
176
+ ) -> Any:
177
+ files = {"file": open(file_path, "rb")}
178
+ data: Dict[str, Any] = {}
179
+ if name:
180
+ data["name"] = name
181
+ if compression is not None:
182
+ data["compression"] = compression
183
+ try:
184
+ return self._request("PUT", f"/api/v1/files/{file_id}", files=files, data=data)
185
+ finally:
186
+ files["file"].close()
187
+
188
+ def delete_file(self, file_id: str) -> Any:
189
+ return self._request("DELETE", f"/api/v1/files/{file_id}")
190
+
191
+ def get_metrics(self) -> Any:
192
+ return self._request("GET", "/api/v1/metrics")
193
+
194
+ def build_file_url(self, file_id: str, **options: Any) -> str:
195
+ url = f"{self.base_url}/api/v1/files/{file_id}"
196
+ if options:
197
+ query = "&".join(f"{k}={v}" for k, v in options.items())
198
+ return f"{url}?{query}"
199
+ return url
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: vaultsens-sdk
3
+ Version: 0.1.1
4
+ Summary: VaultSens SDK for API key uploads and file management
5
+ Author: VaultSens
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://vaultsens.com/
8
+ Project-URL: Repository, https://github.com/vaultsens/vaultsens-sdk-python
9
+ Keywords: vaultsens,sdk,storage,upload
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: requests>=2.31
15
+
16
+ # vaultsens-sdk
17
+
18
+ Python SDK for VaultSens. API key + secret authentication with file upload and management helpers.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install vaultsens-sdk
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ from vaultsens_sdk import VaultSensClient
30
+
31
+ client = VaultSensClient(
32
+ base_url="https://api.vaultsens.com",
33
+ api_key="fs_xxx",
34
+ api_secret="sk_xxx",
35
+ )
36
+
37
+ response = client.upload_file("./photo.png", name="marketing-hero", transform=True)
38
+ print(response)
39
+ ```
40
+
41
+ ## API
42
+
43
+ - `upload_file(path, name=None, transform=None)`
44
+ - `upload_files(paths, name=None, transform=None)`
45
+ - `list_files()`
46
+ - `get_file_metadata(file_id)`
47
+ - `update_file(file_id, path, name=None, transform=None)`
48
+ - `delete_file(file_id)`
49
+ - `get_metrics()`
50
+ - `build_file_url(file_id, **options)`
51
+
52
+ ## Docs
53
+
54
+ https://vaultsens.com/
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ vaultsens_sdk/__init__.py
4
+ vaultsens_sdk/client.py
5
+ vaultsens_sdk.egg-info/PKG-INFO
6
+ vaultsens_sdk.egg-info/SOURCES.txt
7
+ vaultsens_sdk.egg-info/dependency_links.txt
8
+ vaultsens_sdk.egg-info/requires.txt
9
+ vaultsens_sdk.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ requests>=2.31
@@ -0,0 +1 @@
1
+ vaultsens_sdk