Skip to content

Commit fdda98a

Browse files
committed
Fix Python SDK linting errors and test failure
- Fix 69 ruff linting errors: import ordering, modern type annotations (Optional[X] -> X | None, Union -> |), isinstance tuple syntax - Remove unused imports (pytest in test files) - Fix test_verify_valid_signature: use actual derived address from signature.public_key instead of hardcoded incorrect address
1 parent 1e8ae3e commit fdda98a

File tree

8 files changed

+100
-105
lines changed

8 files changed

+100
-105
lines changed

python/capture_sdk/__init__.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,33 @@
1111
>>> print(asset.nid)
1212
"""
1313

14+
from . import verify
1415
from .client import Capture
16+
from .crypto import sha256, verify_signature
17+
from .errors import (
18+
AuthenticationError,
19+
CaptureError,
20+
InsufficientFundsError,
21+
NetworkError,
22+
NotFoundError,
23+
PermissionError,
24+
ValidationError,
25+
)
1526
from .types import (
16-
FileInput,
17-
CaptureOptions,
18-
RegisterOptions,
19-
UpdateOptions,
20-
SignOptions,
2127
Asset,
22-
Commit,
23-
AssetTree,
2428
AssetSearchOptions,
2529
AssetSearchResult,
26-
SimilarMatch,
27-
NftSearchResult,
30+
AssetTree,
31+
CaptureOptions,
32+
Commit,
33+
FileInput,
2834
NftRecord,
35+
NftSearchResult,
36+
RegisterOptions,
37+
SignOptions,
38+
SimilarMatch,
39+
UpdateOptions,
2940
)
30-
from .errors import (
31-
CaptureError,
32-
AuthenticationError,
33-
PermissionError,
34-
NotFoundError,
35-
InsufficientFundsError,
36-
ValidationError,
37-
NetworkError,
38-
)
39-
from .crypto import sha256, verify_signature
40-
from . import verify
4141

4242
__version__ = "0.1.0"
4343

python/capture_sdk/client.py

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,27 @@
55
import json
66
import mimetypes
77
from pathlib import Path
8-
from typing import Any, Optional, Union
8+
from typing import Any
99
from urllib.parse import urlencode
1010

1111
import httpx
1212

13+
from .crypto import create_integrity_proof, sha256, sign_integrity_proof
14+
from .errors import CaptureError, ValidationError, create_api_error
1315
from .types import (
14-
FileInput,
15-
CaptureOptions,
16-
RegisterOptions,
17-
UpdateOptions,
1816
Asset,
19-
Commit,
20-
AssetTree,
2117
AssetSearchOptions,
2218
AssetSearchResult,
23-
SimilarMatch,
24-
NftSearchResult,
19+
AssetTree,
20+
CaptureOptions,
21+
Commit,
22+
FileInput,
2523
NftRecord,
24+
NftSearchResult,
25+
RegisterOptions,
26+
SimilarMatch,
27+
UpdateOptions,
2628
)
27-
from .errors import ValidationError, CaptureError, create_api_error
28-
from .crypto import sha256, create_integrity_proof, sign_integrity_proof
29-
3029

3130
DEFAULT_BASE_URL = "https://api.numbersprotocol.io/api/v3"
3231
HISTORY_API_URL = "https://e23hi68y55.execute-api.us-east-1.amazonaws.com/default/get-commits-storage-backend-jade-near"
@@ -65,7 +64,7 @@ def _get_mime_type(filename: str) -> str:
6564

6665
def _normalize_file(
6766
file_input: FileInput,
68-
options: Optional[RegisterOptions] = None,
67+
options: RegisterOptions | None = None,
6968
) -> tuple[bytes, str, str]:
7069
"""
7170
Normalizes various file input types to a common format.
@@ -93,7 +92,7 @@ def _normalize_file(
9392
return data, filename, mime_type
9493

9594
# 3. bytes or bytearray
96-
if isinstance(file_input, (bytes, bytearray)):
95+
if isinstance(file_input, bytes | bytearray):
9796
if not options or not options.filename:
9897
raise ValidationError("filename is required for binary input")
9998
data = bytes(file_input)
@@ -128,11 +127,11 @@ class Capture:
128127

129128
def __init__(
130129
self,
131-
token: Optional[str] = None,
130+
token: str | None = None,
132131
*,
133132
testnet: bool = False,
134-
base_url: Optional[str] = None,
135-
options: Optional[CaptureOptions] = None,
133+
base_url: str | None = None,
134+
options: CaptureOptions | None = None,
136135
):
137136
"""
138137
Initialize the Capture client.
@@ -171,10 +170,10 @@ def _request(
171170
method: str,
172171
url: str,
173172
*,
174-
data: Optional[dict[str, Any]] = None,
175-
files: Optional[dict[str, Any]] = None,
176-
json_body: Optional[dict[str, Any]] = None,
177-
nid: Optional[str] = None,
173+
data: dict[str, Any] | None = None,
174+
files: dict[str, Any] | None = None,
175+
json_body: dict[str, Any] | None = None,
176+
nid: str | None = None,
178177
) -> dict[str, Any]:
179178
"""Makes an authenticated API request."""
180179
headers = {"Authorization": f"token {self._token}"}
@@ -221,12 +220,12 @@ def register(
221220
self,
222221
file: FileInput,
223222
*,
224-
filename: Optional[str] = None,
225-
caption: Optional[str] = None,
226-
headline: Optional[str] = None,
223+
filename: str | None = None,
224+
caption: str | None = None,
225+
headline: str | None = None,
227226
public_access: bool = True,
228-
sign: Optional[dict[str, str]] = None,
229-
options: Optional[RegisterOptions] = None,
227+
sign: dict[str, str] | None = None,
228+
options: RegisterOptions | None = None,
230229
) -> Asset:
231230
"""
232231
Registers a new asset.
@@ -330,11 +329,11 @@ def update(
330329
self,
331330
nid: str,
332331
*,
333-
caption: Optional[str] = None,
334-
headline: Optional[str] = None,
335-
commit_message: Optional[str] = None,
336-
custom_metadata: Optional[dict[str, Any]] = None,
337-
options: Optional[UpdateOptions] = None,
332+
caption: str | None = None,
333+
headline: str | None = None,
334+
commit_message: str | None = None,
335+
custom_metadata: dict[str, Any] | None = None,
336+
options: UpdateOptions | None = None,
338337
) -> Asset:
339338
"""
340339
Updates an existing asset's metadata.
@@ -565,12 +564,12 @@ def get_asset_tree(self, nid: str) -> AssetTree:
565564
def search_asset(
566565
self,
567566
*,
568-
file_url: Optional[str] = None,
569-
file: Optional[FileInput] = None,
570-
nid: Optional[str] = None,
571-
threshold: Optional[float] = None,
572-
sample_count: Optional[int] = None,
573-
options: Optional[AssetSearchOptions] = None,
567+
file_url: str | None = None,
568+
file: FileInput | None = None,
569+
nid: str | None = None,
570+
threshold: float | None = None,
571+
sample_count: int | None = None,
572+
options: AssetSearchOptions | None = None,
574573
) -> AssetSearchResult:
575574
"""
576575
Searches for similar assets using image similarity.
@@ -632,7 +631,7 @@ def search_asset(
632631
form_data: dict[str, Any] = {"token": self._token}
633632

634633
# Add input source
635-
files_data: Optional[dict[str, Any]] = None
634+
files_data: dict[str, Any] | None = None
636635
if options.file_url:
637636
form_data["url"] = options.file_url
638637
elif options.nid:

python/capture_sdk/crypto.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
import hashlib
66
import json
77
import time
8-
from typing import Union
98

109
from eth_account import Account
1110
from eth_account.messages import encode_defunct
1211

13-
from .types import IntegrityProof, AssetSignature
12+
from .types import AssetSignature, IntegrityProof
1413

1514

16-
def sha256(data: Union[bytes, bytearray]) -> str:
15+
def sha256(data: bytes | bytearray) -> str:
1716
"""
1817
Computes SHA-256 hash of data.
1918

python/capture_sdk/errors.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Error classes for the Capture SDK.
33
"""
44

5-
from typing import Optional
65

76

87
class CaptureError(Exception):
@@ -12,7 +11,7 @@ def __init__(
1211
self,
1312
message: str,
1413
code: str,
15-
status_code: Optional[int] = None,
14+
status_code: int | None = None,
1615
):
1716
super().__init__(message)
1817
self.message = message
@@ -43,7 +42,7 @@ def __init__(self, message: str = "Insufficient permissions for this operation")
4342
class NotFoundError(CaptureError):
4443
"""Thrown when the requested asset is not found."""
4544

46-
def __init__(self, nid: Optional[str] = None):
45+
def __init__(self, nid: str | None = None):
4746
message = f"Asset not found: {nid}" if nid else "Asset not found"
4847
super().__init__(message, "NOT_FOUND", 404)
4948
self.nid = nid
@@ -66,14 +65,14 @@ def __init__(self, message: str):
6665
class NetworkError(CaptureError):
6766
"""Thrown when a network or API request fails."""
6867

69-
def __init__(self, message: str, status_code: Optional[int] = None):
68+
def __init__(self, message: str, status_code: int | None = None):
7069
super().__init__(message, "NETWORK_ERROR", status_code)
7170

7271

7372
def create_api_error(
7473
status_code: int,
7574
message: str,
76-
nid: Optional[str] = None,
75+
nid: str | None = None,
7776
) -> CaptureError:
7877
"""Maps HTTP status codes to appropriate error classes."""
7978
if status_code == 400:

0 commit comments

Comments
 (0)