Skip to content

Commit ac39608

Browse files
committed
Docstrings
1 parent 5b823ae commit ac39608

File tree

2 files changed

+84
-10
lines changed

2 files changed

+84
-10
lines changed

async_substrate_interface/async_substrate.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,15 @@ async def init_runtime(
10591059
async def get_runtime_for_version(
10601060
self, runtime_version: int, block_hash: Optional[str] = None
10611061
) -> Runtime:
1062+
"""
1063+
Retrieves the `Runtime` for a given runtime version at a given block hash.
1064+
Args:
1065+
runtime_version: version of the runtime (from `get_block_runtime_version_for`)
1066+
block_hash: hash of the block to query
1067+
1068+
Returns:
1069+
Runtime object for the given runtime version
1070+
"""
10621071
return await self._get_runtime_for_version(runtime_version, block_hash)
10631072

10641073
async def _get_runtime_for_version(
@@ -1927,10 +1936,18 @@ async def get_metadata(self, block_hash=None) -> MetadataV15:
19271936
return runtime.metadata_v15
19281937

19291938
@cached_fetcher(max_size=512)
1930-
async def get_parent_block_hash(self, block_hash):
1939+
async def get_parent_block_hash(self, block_hash) -> str:
1940+
"""
1941+
Retrieves the block hash of the parent of the given block hash
1942+
Args:
1943+
block_hash: hash of the block to query
1944+
1945+
Returns:
1946+
Hash of the parent block hash, or the original block hash (if it has not parent)
1947+
"""
19311948
return await self._get_parent_block_hash(block_hash)
19321949

1933-
async def _get_parent_block_hash(self, block_hash):
1950+
async def _get_parent_block_hash(self, block_hash) -> str:
19341951
block_header = await self.rpc_request("chain_getHeader", [block_hash])
19351952

19361953
if block_header["result"] is None:
@@ -1975,25 +1992,25 @@ async def get_storage_by_key(self, block_hash: str, storage_key: str) -> Any:
19751992

19761993
@cached_fetcher(max_size=16)
19771994
async def get_block_runtime_info(self, block_hash: str) -> dict:
1995+
"""
1996+
Retrieve the runtime info of given block_hash
1997+
"""
19781998
return await self._get_block_runtime_info(block_hash)
19791999

19802000
get_block_runtime_version = get_block_runtime_info
19812001

19822002
async def _get_block_runtime_info(self, block_hash: str) -> dict:
1983-
"""
1984-
Retrieve the runtime info of given block_hash
1985-
"""
19862003
response = await self.rpc_request("state_getRuntimeVersion", [block_hash])
19872004
return response.get("result")
19882005

19892006
@cached_fetcher(max_size=512)
19902007
async def get_block_runtime_version_for(self, block_hash: str):
1991-
return await self._get_block_runtime_version_for(block_hash)
1992-
1993-
async def _get_block_runtime_version_for(self, block_hash: str):
19942008
"""
19952009
Retrieve the runtime version of the parent of a given block_hash
19962010
"""
2011+
return await self._get_block_runtime_version_for(block_hash)
2012+
2013+
async def _get_block_runtime_version_for(self, block_hash: str):
19972014
parent_block_hash = await self.get_parent_block_hash(block_hash)
19982015
runtime_info = await self.get_block_runtime_info(parent_block_hash)
19992016
if runtime_info is None:
@@ -2306,6 +2323,14 @@ async def rpc_request(
23062323

23072324
@cached_fetcher(max_size=512)
23082325
async def get_block_hash(self, block_id: int) -> str:
2326+
"""
2327+
Retrieves the hash of the specified block number
2328+
Args:
2329+
block_id: block number
2330+
2331+
Returns:
2332+
Hash of the block
2333+
"""
23092334
return await self._get_block_hash(block_id)
23102335

23112336
async def _get_block_hash(self, block_id: int) -> str:

async_substrate_interface/utils/cache.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ async def inner(self, *args, **kwargs):
148148

149149

150150
class LRUCache:
151+
"""
152+
Basic Least-Recently-Used Cache, with simple methods `set` and `get`
153+
"""
154+
151155
def __init__(self, max_size: int):
152156
self.max_size = max_size
153157
self.cache = OrderedDict()
@@ -168,12 +172,51 @@ def get(self, key):
168172

169173

170174
class CachedFetcher:
175+
"""
176+
Async caching class that allows the standard async LRU cache system, but also allows for concurrent
177+
asyncio calls (with the same args) to use the same result of a single call.
178+
179+
This should only be used for asyncio calls where the result is immutable.
180+
181+
Concept and usage:
182+
```
183+
async def fetch(self, block_hash: str) -> str:
184+
return await some_resource(block_hash)
185+
186+
a1, a2, b = await asyncio.gather(fetch("a"), fetch("a"), fetch("b"))
187+
```
188+
189+
Here, you are making three requests, but you really only need to make two I/O requests
190+
(one for "a", one for "b"), and while you wouldn't typically make a request like this directly, it's very
191+
common in using this library to inadvertently make these requests y gathering multiple resources that depend
192+
on the calls like this under the hood.
193+
194+
By using
195+
196+
```
197+
@cached_fetcher(max_size=512)
198+
async def fetch(self, block_hash: str) -> str:
199+
return await some_resource(block_hash)
200+
201+
a1, a2, b = await asyncio.gather(fetch("a"), fetch("a"), fetch("b"))
202+
```
203+
204+
You are only making two I/O calls, and a2 will simply use the result of a1 when it lands.
205+
"""
206+
171207
def __init__(
172208
self,
173209
max_size: int,
174210
method: Callable[..., Awaitable[Any]],
175211
cache_key_index: int = 0,
176212
):
213+
"""
214+
Args:
215+
max_size: max size of the cache (in items)
216+
method: the function to cache
217+
cache_key_index: if the method takes multiple args, only one will be used as the cache key. This is the
218+
index of that cache key in the args list (default is the first arg)
219+
"""
177220
self._inflight: dict[Hashable, asyncio.Future] = {}
178221
self._method = method
179222
self._cache = LRUCache(max_size=max_size)
@@ -203,7 +246,11 @@ async def __call__(self, *args: Any) -> Any:
203246
self._inflight.pop(key, None)
204247

205248

206-
class CachedFetcherMethod:
249+
class _CachedFetcherMethod:
250+
"""
251+
Helper class for using CachedFetcher with method caches (rather than functions)
252+
"""
253+
207254
def __init__(self, method, max_size: int, cache_key_index: int):
208255
self.method = method
209256
self.max_size = max_size
@@ -226,7 +273,9 @@ def __get__(self, instance, owner):
226273

227274

228275
def cached_fetcher(max_size: int, cache_key_index: int = 0):
276+
"""Wrapper for CachedFetcher. See example in CachedFetcher docstring."""
277+
229278
def wrapper(method):
230-
return CachedFetcherMethod(method, max_size, cache_key_index)
279+
return _CachedFetcherMethod(method, max_size, cache_key_index)
231280

232281
return wrapper

0 commit comments

Comments
 (0)