Skip to content

Commit ff6ca53

Browse files
committed
docs: async api example [skip ci]
1 parent 4551279 commit ff6ca53

File tree

1 file changed

+63
-3
lines changed

1 file changed

+63
-3
lines changed

docs/async.md

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
1-
# Async
1+
# Async API
22

3-
TODO
3+
Largely motivated by its integration with [Python Liquid](https://jg-rp.github.io/liquid/jsonpath/introduction), Python JSONPath offers an asynchronous API that allows for items in a target data structure to be "fetched" lazily.
44

5-
Coming soon.
5+
[`findall_async()`](api.md#jsonpath.env.JSONPathEnvironment.findall_async) and [`finditer_async()`](api.md#jsonpath.env.JSONPathEnvironment.finditer) are [asyncio](https://docs.python.org/3/library/asyncio.html) equivalents to [`findall()`](api.md#jsonpath.env.JSONPathEnvironment.findall) and [`finditer()`](api.md#jsonpath.env.JSONPathEnvironment.finditer). By default, any class implementing the [mapping](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping) or [sequence](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence) interfaces, and a `__getitem_async__()` method, will have `__getitem_async__()` awaited instead of calling `__getitem__()` when resolving mapping keys or sequence indices.
6+
7+
## Example
8+
9+
In this example, showing a lazy-loading collections of `Player` objects, only the "A" team's players are fetched from the database, and only when they are first accessed.
10+
11+
```python
12+
from collections import abc
13+
from dataclasses import dataclass
14+
from typing import Dict
15+
from typing import Iterator
16+
from typing import List
17+
18+
import jsonpath
19+
20+
21+
@dataclass
22+
class Player:
23+
name: str
24+
pid: int
25+
rank: int
26+
27+
28+
class LazyPlayers(abc.Mapping[str, Player]):
29+
def __init__(self, names: List[str]):
30+
self.names = names
31+
self.cached_players: Dict[str, Player] = {}
32+
33+
def __len__(self) -> int:
34+
return len(self.names)
35+
36+
def __iter__(self) -> Iterator[str]:
37+
return iter(self.names)
38+
39+
def __getitem__(self, k: str) -> Player:
40+
if self.cached_players is None:
41+
# Blocking IO here
42+
self.cached_players = get_stuff_from_database()
43+
return self.cached_players[k]
44+
45+
async def __getitem_async__(self, k: str) -> Player:
46+
if self.cached_players is None:
47+
# Do async IO here.
48+
self.cached_players = await get_stuff_from_database_async()
49+
return self.cached_players[k]
50+
51+
52+
data = {
53+
"teams": {
54+
"A Team": LazyPlayers(["Sue", "Bob"]),
55+
"B Team": LazyPlayers(["Sally", "Frank"]),
56+
}
57+
}
58+
59+
best_a_team_players = jsonpath.findall_async("$.teams['A Team'][?rank >= 8]", data)
60+
61+
```
62+
63+
## Custom Async Item Getting
64+
65+
TODO:

0 commit comments

Comments
 (0)