Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pokedex#7: "makes pokemon requests to downstream api concurrent" #15

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ There exists a `poetry` buildscript called `get-pokemon`.
It can be invoked like so:

```
poetry run get-pokemon
poetry run get-pokemon by --type ghost
```

pipe to `less`
81 changes: 79 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions pokedex/api/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,8 @@ def go(args=sys.argv):
args = parser.parse_args()

if args.type:
for pokemon in get_pokemon_by_type(args.type):
output = json.dumps(pokemon, indent=4)
print(output)
print(json.dumps(list(get_pokemon_by_type(args.type)), indent=4))

if args.move:
move = str(args.move).replace(" ", "-")
for pokemon in get_pokemon_by_move(move):
output = json.dumps(pokemon, indent=4)
print(output)
print(json.dumps(list(get_pokemon_by_move(move)), indent=4))
13 changes: 9 additions & 4 deletions pokedex/api/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from typing import Any, Dict, Generator, Iterable, List, Optional
from actionpack import Procedure

import requests

from actionpack.actions import Call
from actionpack.utils import Closure

from pokedex.api.constants import BASE_URL
from pokedex.api.models import PokeApiRequest, PokeApiResource, PokeApiResourceRef, PokemonRef

Expand Down Expand Up @@ -38,11 +42,12 @@ def generate_pokemon_requests(api_request: PokeApiRequest, response_key: str) ->
yield model.as_request()


# TODO: make concurrent
def get_pokemon(pokemon_requests: Iterable[PokeApiRequest]) -> Generator[Pokemon, None, None]:
for pokemon_request in pokemon_requests:
response: requests.Response = pokemon_request()
response.raise_for_status() # TODO: handle error states
calls = (Call(Closure(pokemon_request)) for pokemon_request in pokemon_requests)
for result in Procedure(calls).execute(synchronously=False, should_raise=True):
# TODO: consider how to proceed if `result.successful => False`
# such handling will preclude the need for the `should_raise` option during Procedure execution
response: requests.Response = result.value
yield response.json()


Expand Down
4 changes: 4 additions & 0 deletions pokedex/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class PokeApiRequest:
def __call__(self) -> ApiResponseType:
return requests.get(self.url)

@property
def __name__(self):
return f"{self.__class__.__name__}:{self.url}"


class PokeApiResourceRef(BaseModel):
name: str
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ python = "^3.8.1"
requests = "2.31.0"
urllib3 = "<=1.26.16"
pydantic = "^1.10.8"
actionpack = "^1.7.15"

[tool.poetry.group.dev.dependencies]
coverage = "5.5"
Expand Down