Skip to content

Commit c24b372

Browse files
authored
Merge pull request #89 from ourzora/try-async-parser
Make everything async for Metadata
2 parents 622958f + c81d9bf commit c24b372

File tree

80 files changed

+2639
-969
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2639
-969
lines changed

docs/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v0.2.2
4+
5+
- Go deep on making things as async as they possibly can
6+
37
## v0.2.1
48

59
- Add async support for custom adapters

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Getting Started
22

3-
Documentation for version: **v0.2.1**
3+
Documentation for version: **v0.2.2**
44

55
## Overview
66

offchain/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from offchain.metadata import (
1+
from offchain.metadata import ( # type: ignore[attr-defined]
22
get_token_metadata,
33
Metadata,
44
MetadataFetcher,

offchain/base/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class StringEnum(str, Enum):
77
def __repr__(self) -> str:
88
return str(self.value)
99

10-
def __str__(self):
10+
def __str__(self): # type: ignore[no-untyped-def]
1111
return str(self.value)
1212

1313
@classmethod

offchain/concurrency.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
MAX_PROCS = (multiprocessing.cpu_count() * 2) + 1
88

99

10-
def parallelize_with_threads(*args: Sequence[Callable]) -> Sequence[Any]:
10+
def parallelize_with_threads(*args: Sequence[Callable]) -> Sequence[Any]: # type: ignore[type-arg] # noqa: E501
1111
"""Parallelize a set of functions with a threadpool.
1212
Good for network calls, less for for number crunching.
1313
@@ -17,12 +17,12 @@ def parallelize_with_threads(*args: Sequence[Callable]) -> Sequence[Any]:
1717
n_tasks = len(args)
1818
logger.debug("Starting tasks", extra={"num_tasks": n_tasks})
1919
with ThreadPoolExecutor(max_workers=min(n_tasks, MAX_PROCS)) as pool:
20-
futures = [pool.submit(fn) for fn in args]
20+
futures = [pool.submit(fn) for fn in args] # type: ignore[arg-type, var-annotated] # noqa: E501
2121
res = [f.result() for f in futures]
2222
return res
2323

2424

25-
def parmap(fn: Callable, args: list) -> list:
25+
def parmap(fn: Callable, args: list) -> list: # type: ignore[type-arg]
2626
"""Run a map in parallel safely
2727
2828
Args:
@@ -35,11 +35,11 @@ def parmap(fn: Callable, args: list) -> list:
3535
Note: explicitly using a map to generate function rather than a list comprehension to prevent
3636
a subtle variable shadowing bug that can occur with code like this:
3737
>>> parallelize_with_threads(*[lambda: fn(arg) for arg in args])
38-
"""
39-
return list(parallelize_with_threads(*map(lambda i: lambda: fn(i), args)))
38+
""" # noqa: E501
39+
return list(parallelize_with_threads(*map(lambda i: lambda: fn(i), args))) # type: ignore[arg-type] # noqa: E501
4040

4141

42-
def batched_parmap(fn: Callable, args: list, batch_size: int = 10) -> list:
42+
def batched_parmap(fn: Callable, args: list, batch_size: int = 10) -> list: # type: ignore[type-arg] # noqa: E501
4343
results = []
4444
i, j = 0, 0
4545
while i < len(args):

offchain/logger/logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
log_handler = logging.StreamHandler()
66
log_handler.setFormatter(
7-
jsonlogger.JsonFormatter(
7+
jsonlogger.JsonFormatter( # type: ignore[no-untyped-call]
88
rename_fields={"levelname": "severity"},
99
fmt="%(name)s %(threadName) %(message)s '%(asctime)s %(levelname)",
1010
)

offchain/metadata/adapters/arweave.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class ARWeaveAdapter(HTTPAdapter):
1818
key (str, optional): optional key to send with request
1919
secret (str, optional): optional secret to send with request
2020
timeout (int): request timeout in seconds. Defaults to 10 seconds.
21-
"""
21+
""" # noqa: E501
2222

23-
def __init__(
23+
def __init__( # type: ignore[no-untyped-def]
2424
self,
2525
host_prefixes: Optional[list[str]] = None,
2626
key: Optional[str] = None,
@@ -59,7 +59,7 @@ def parse_ar_url(self, url: str) -> str:
5959
url = new_url
6060
return url
6161

62-
async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -> httpx.Response:
62+
async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -> httpx.Response: # type: ignore[no-untyped-def, valid-type] # noqa: E501
6363
"""Format and send async request to ARWeave host.
6464
6565
Args:
@@ -69,9 +69,9 @@ async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -
6969
Returns:
7070
httpx.Response: response from ARWeave host.
7171
"""
72-
return await sess.get(self.parse_ar_url(url), timeout=self.timeout, follow_redirects=True)
72+
return await sess.get(self.parse_ar_url(url), timeout=self.timeout, follow_redirects=True) # type: ignore[no-any-return] # noqa: E501
7373

74-
def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
74+
def send(self, request: PreparedRequest, *args, **kwargs) -> Response: # type: ignore[no-untyped-def] # noqa: E501
7575
"""Format and send request to ARWeave host.
7676
7777
Args:
@@ -80,6 +80,6 @@ def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
8080
Returns:
8181
Response: response from ARWeave host.
8282
"""
83-
request.url = self.parse_ar_url(request.url)
83+
request.url = self.parse_ar_url(request.url) # type: ignore[arg-type]
8484
kwargs["timeout"] = self.timeout
8585
return super().send(request, *args, **kwargs)

offchain/metadata/adapters/base_adapter.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
class BaseAdapter(RequestsBaseAdapter):
1111
"""Base Adapter inheriting from requests BaseAdapter"""
1212

13-
def __init__(self, *args, **kwargs):
13+
def __init__(self, *args, **kwargs): # type: ignore[no-untyped-def]
1414
super().__init__()
1515

16-
async def gen_send(self, url: str, *args, **kwargs) -> httpx.Response:
16+
async def gen_send(self, url: str, *args, **kwargs) -> httpx.Response: # type: ignore[no-untyped-def] # noqa: E501
1717
"""Format and send async request to url host.
1818
1919
Args:
@@ -28,18 +28,18 @@ async def gen_send(self, url: str, *args, **kwargs) -> httpx.Response:
2828
class HTTPAdapter(RequestsHTTPAdapter):
2929
"""HTTP Adapter inheriting from requests HTTPAdapter"""
3030

31-
def __init__(
31+
def __init__( # type: ignore[no-untyped-def]
3232
self,
33-
pool_connections: int = ...,
34-
pool_maxsize: int = ...,
35-
max_retries: Union[Retry, int, None] = ...,
36-
pool_block: bool = ...,
33+
pool_connections: int = ..., # type: ignore[assignment]
34+
pool_maxsize: int = ..., # type: ignore[assignment]
35+
max_retries: Union[Retry, int, None] = ..., # type: ignore[assignment]
36+
pool_block: bool = ..., # type: ignore[assignment]
3737
*args,
3838
**kwargs
3939
) -> None:
4040
super().__init__(pool_connections, pool_maxsize, max_retries, pool_block)
4141

42-
async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -> httpx.Response:
42+
async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -> httpx.Response: # type: ignore[no-untyped-def, valid-type] # noqa: E501
4343
"""Format and send async request to url host.
4444
4545
Args:
@@ -48,7 +48,7 @@ async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -
4848
Returns:
4949
httpx.Response: response from host.
5050
"""
51-
return await sess.get(url, follow_redirects=True)
51+
return await sess.get(url, follow_redirects=True) # type: ignore[no-any-return]
5252

5353

5454
Adapter = Union[BaseAdapter, HTTPAdapter]
@@ -59,4 +59,4 @@ class AdapterConfig:
5959
adapter_cls: Type[Adapter]
6060
mount_prefixes: list[str]
6161
host_prefixes: Optional[list[str]] = None
62-
kwargs: dict = field(default_factory=dict)
62+
kwargs: dict = field(default_factory=dict) # type: ignore[type-arg]

offchain/metadata/adapters/data_uri.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from offchain.metadata.registries.adapter_registry import AdapterRegistry
99

1010

11-
def decode_data_url(data_url):
11+
def decode_data_url(data_url): # type: ignore[no-untyped-def]
1212
data_parts = data_url.split(",")
1313
data = data_parts[1]
1414

@@ -24,10 +24,10 @@ def decode_data_url(data_url):
2424
class DataURIAdapter(BaseAdapter):
2525
"""Provides an interface for Requests sessions to handle data uris."""
2626

27-
def __init__(self, *args, **kwargs):
28-
super().__init__(*args, **kwargs)
27+
def __init__(self, *args, **kwargs): # type: ignore[no-untyped-def]
28+
super().__init__(*args, **kwargs) # type: ignore[no-untyped-call]
2929

30-
async def gen_send(self, url: str, *args, **kwargs) -> httpx.Response:
30+
async def gen_send(self, url: str, *args, **kwargs) -> httpx.Response: # type: ignore[no-untyped-def] # noqa: E501
3131
"""Handle async data uri request.
3232
3333
Args:
@@ -38,12 +38,12 @@ async def gen_send(self, url: str, *args, **kwargs) -> httpx.Response:
3838
"""
3939
response = httpx.Response(
4040
status_code=200,
41-
text=decode_data_url(url),
41+
text=decode_data_url(url), # type: ignore[no-untyped-call]
4242
request=httpx.Request(method="GET", url=url),
4343
)
4444
return response
4545

46-
def send(self, request: PreparedRequest, *args, **kwargs):
46+
def send(self, request: PreparedRequest, *args, **kwargs): # type: ignore[no-untyped-def] # noqa: E501
4747
"""Handle data uri request.
4848
4949
Args:
@@ -54,10 +54,10 @@ def send(self, request: PreparedRequest, *args, **kwargs):
5454
"""
5555
newResponse = Response()
5656
newResponse.request = request
57-
newResponse.url = request.url
58-
newResponse.connection = self
57+
newResponse.url = request.url # type: ignore[assignment]
58+
newResponse.connection = self # type: ignore[attr-defined]
5959
try:
60-
response = urlopen(request.url)
60+
response = urlopen(request.url) # type: ignore[arg-type]
6161
newResponse.status_code = 200
6262
newResponse.headers = response.headers
6363
newResponse.raw = response
@@ -66,5 +66,5 @@ def send(self, request: PreparedRequest, *args, **kwargs):
6666
finally:
6767
return newResponse
6868

69-
def close(self):
69+
def close(self): # type: ignore[no-untyped-def]
7070
self.response.close()

offchain/metadata/adapters/ipfs.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@ def build_request_url(gateway: str, request_url: str) -> str:
2828
if parsed_url.host != "ipfs":
2929
host = parsed_url.host
3030
# Remove duplicate slashes
31-
if url.endswith("/") and host.startswith("/"):
32-
host = host[1:]
33-
url += host
31+
if url.endswith("/") and host.startswith("/"): # type: ignore[union-attr]
32+
host = host[1:] # type: ignore[index]
33+
url += host # type: ignore[operator]
3434
if parsed_url.path is not None:
3535
path = parsed_url.path
3636
# Remove duplicate slashes
3737
if url.endswith("/") and path.startswith("/"):
3838
path = path[1:]
3939
url += path
4040
# Handle "https://" prefixed urls that have "/ipfs/" in the path
41-
elif parsed_url.scheme == "https" and "ipfs" in parsed_url.path:
41+
elif parsed_url.scheme == "https" and "ipfs" in parsed_url.path: # type: ignore[operator] # noqa: E501
4242
url = f"{gateway}"
4343
if parsed_url.path is not None:
4444
path = parsed_url.path
@@ -60,9 +60,9 @@ class IPFSAdapter(HTTPAdapter):
6060
key (str, optional): optional key to send with request
6161
secret (str, optional): optional secret to send with request
6262
timeout (int): request timeout in seconds. Defaults to 10 seconds.
63-
"""
63+
""" # noqa: E501
6464

65-
def __init__(
65+
def __init__( # type: ignore[no-untyped-def]
6666
self,
6767
host_prefixes: Optional[list[str]] = None,
6868
key: Optional[str] = None,
@@ -96,7 +96,7 @@ def make_request_url(self, request_url: str, gateway: Optional[str] = None) -> s
9696
gateway = gateway or random.choice(self.host_prefixes)
9797
return build_request_url(gateway=gateway, request_url=request_url)
9898

99-
async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -> httpx.Response:
99+
async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -> httpx.Response: # type: ignore[no-untyped-def, valid-type] # noqa: E501
100100
"""Format and send async request to IPFS host.
101101
102102
Args:
@@ -106,9 +106,9 @@ async def gen_send(self, url: str, sess: httpx.AsyncClient(), *args, **kwargs) -
106106
Returns:
107107
httpx.Response: response from IPFS host.
108108
"""
109-
return await sess.get(self.make_request_url(url), timeout=self.timeout, follow_redirects=True)
109+
return await sess.get(self.make_request_url(url), timeout=self.timeout, follow_redirects=True) # type: ignore[no-any-return] # noqa: E501
110110

111-
def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
111+
def send(self, request: PreparedRequest, *args, **kwargs) -> Response: # type: ignore[no-untyped-def] # noqa: E501
112112
"""For IPFS hashes, query pinata cloud gateway
113113
114114
Args:
@@ -117,7 +117,7 @@ def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
117117
Returns:
118118
Response: response from IPFS Gateway
119119
"""
120-
request.url = self.make_request_url(request.url)
120+
request.url = self.make_request_url(request.url) # type: ignore[arg-type]
121121

122122
kwargs["timeout"] = self.timeout
123123
return super().send(request, *args, **kwargs)

0 commit comments

Comments
 (0)