Skip to content

Commit

Permalink
feat: scryfall services applies the new method() / method_async() dic…
Browse files Browse the repository at this point in the history
…hotomy
  • Loading branch information
Guibod committed Mar 6, 2023
1 parent 8ceb49d commit d82bed1
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 48 deletions.
2 changes: 1 addition & 1 deletion examples/scryfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from mightstone.services.scryfall import Scryfall

scryfall = Scryfall()
found = stream_as_list(scryfall.search("boseiju"))
found = stream_as_list(scryfall.search_async("boseiju"))

print(f"Found {len(found)} instances of Boseiju")
for card in found:
Expand Down
70 changes: 53 additions & 17 deletions src/mightstone/services/scryfall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pydantic.error_wrappers import ValidationError
from typing_extensions import AsyncGenerator, TypeVar

from mightstone.ass import compressor
from mightstone.ass import compressor, synchronize
from mightstone.services import MightstoneHttpClient, ServiceError
from mightstone.services.scryfall.models import (
BulkTagType,
Expand Down Expand Up @@ -49,7 +49,9 @@ class Scryfall(MightstoneHttpClient):

base_url = "https://api.scryfall.com"

async def get_bulk_tags(self, tag_type: BulkTagType) -> AsyncGenerator[Tag, None]:
async def get_bulk_tags_async(
self, tag_type: BulkTagType
) -> AsyncGenerator[Tag, None]:
"""
Access the private tag repository
Expand All @@ -66,7 +68,9 @@ async def get_bulk_tags(self, tag_type: BulkTagType) -> AsyncGenerator[Tag, None
):
yield Tag.parse_obj(current_tag)

async def get_bulk_data(self, bulk_type: str) -> AsyncGenerator[Card, None]:
get_bulk_tags = synchronize(get_bulk_tags_async)

async def get_bulk_data_async(self, bulk_type: str) -> AsyncGenerator[Card, None]:
"""
Access the bulk cards
This script uses ijson and should stream data on the fly
Expand Down Expand Up @@ -98,7 +102,9 @@ async def get_bulk_data(self, bulk_type: str) -> AsyncGenerator[Card, None]:
):
yield Card.parse_obj(current_card)

async def card(
get_bulk_data = synchronize(get_bulk_data_async)

async def card_async(
self, id: str, type: CardIdentifierPath = CardIdentifierPath.SCRYFALL
) -> Card:
"""
Expand All @@ -125,7 +131,9 @@ async def card(
path = f"/cards/{type.value}/{id}"
return await self._get_item(path, Card)

async def random(self, q: str = None) -> Card:
card = synchronize(card_async)

async def random_async(self, q: str = None) -> Card:
"""
Returns a single random Card object.
Expand All @@ -142,7 +150,9 @@ async def random(self, q: str = None) -> Card:
params["q"] = q
return await self._get_item("/cards/random", Card, params=params)

async def search(
random = synchronize(random_async)

async def search_async(
self,
q: str,
unique: UniqueStrategy = UniqueStrategy.CARDS,
Expand Down Expand Up @@ -186,7 +196,9 @@ async def search(
):
yield item

async def named(self, q: str, set: str = None, exact=True) -> Card:
search = synchronize(search_async)

async def named_async(self, q: str, set: str = None, exact=True) -> Card:
"""
Returns a Card based on a name search string. This method is designed for
building chatbots, forum bots, and other services that need card details
Expand Down Expand Up @@ -222,7 +234,9 @@ async def named(self, q: str, set: str = None, exact=True) -> Card:
params["set"] = set
return await self._get_item("/cards/named", Card, params=params)

async def autocomplete(self, q: str, include_extras=False) -> Catalog:
named = synchronize(named_async)

async def autocomplete_async(self, q: str, include_extras=False) -> Catalog:
"""
Returns a Catalog object containing up to 20 full English card names that
could be autocompletions of the given string parameter.
Expand All @@ -247,7 +261,9 @@ async def autocomplete(self, q: str, include_extras=False) -> Catalog:
params["include_extras"] = include_extras
return await self._get_item("/cards/autocomplete", Catalog, params=params)

async def collection(
autocomplete = synchronize(autocomplete_async)

async def collection_async(
self,
identifiers: List[
Union[
Expand Down Expand Up @@ -277,7 +293,9 @@ async def collection(
):
yield item

async def rulings(
collection = synchronize(collection_async)

async def rulings_async(
self,
id: str,
type: RulingIdentifierPath = RulingIdentifierPath.SCRYFALL,
Expand Down Expand Up @@ -305,7 +323,9 @@ async def rulings(
async for item in self._list(path, Ruling, limit=limit):
yield item

async def symbols(self, limit: int = None) -> AsyncGenerator[Symbol, None]:
rulings = synchronize(rulings_async)

async def symbols_async(self, limit: int = None) -> AsyncGenerator[Symbol, None]:
"""
Returns a List of all Card Symbols.
Expand All @@ -316,7 +336,9 @@ async def symbols(self, limit: int = None) -> AsyncGenerator[Symbol, None]:
async for item in self._list("/symbology", Symbol, limit=limit):
yield item

async def parse_mana(self, cost: str) -> ManaCost:
symbols = synchronize(symbols_async)

async def parse_mana_async(self, cost: str) -> ManaCost:
"""
Parses the given mana cost parameter and returns Scryfall’s interpretation.
Expand All @@ -334,7 +356,9 @@ async def parse_mana(self, cost: str) -> ManaCost:
"/symbology/parse-mana", ManaCost, params={"cost": cost}
)

async def catalog(self, type: CatalogType) -> Catalog:
parse_mana = synchronize(parse_mana_async)

async def catalog_async(self, type: CatalogType) -> Catalog:
"""
A Catalog object contains an array of Magic datapoints (words, card values,
etc). Catalog objects are provided by the API as aids for building other
Expand All @@ -346,7 +370,11 @@ async def catalog(self, type: CatalogType) -> Catalog:
type = CatalogType(type)
return await self._get_item(f"/catalog/{type.value}", Catalog)

async def migrations(self, limit: int = None) -> AsyncGenerator[Migration, None]:
catalog = synchronize(catalog_async)

async def migrations_async(
self, limit: int = None
) -> AsyncGenerator[Migration, None]:
"""
For the vast majority of Scryfall’s database, Magic card entries are additive.
We add new and upcoming cards as we learn about them and obtain images.
Expand Down Expand Up @@ -375,15 +403,19 @@ async def migrations(self, limit: int = None) -> AsyncGenerator[Migration, None]
async for item in self._list("/migrations", Migration, limit=limit):
yield item

async def migration(self, id: str) -> Migration:
migrations = synchronize(migrations_async)

async def migration_async(self, id: str) -> Migration:
"""
Returns a single Card Migration with the given :id
:return: A `Migration` instance
"""
return await self._get_item(f"/migrations/{id}", Migration)

async def sets(self, limit: int = None) -> AsyncGenerator[Set, None]:
migration = synchronize(migration_async)

async def sets_async(self, limit: int = None) -> AsyncGenerator[Set, None]:
"""
Returns a List object of all Sets on Scryfall.
Expand All @@ -394,7 +426,9 @@ async def sets(self, limit: int = None) -> AsyncGenerator[Set, None]:
async for item in self._list("/sets", Set, limit=limit):
yield item

async def set(self, id_or_code: str = None) -> Set:
sets = synchronize(sets_async)

async def set_async(self, id_or_code: str = None) -> Set:
"""
Returns a Set with the given set code.
Expand All @@ -404,6 +438,8 @@ async def set(self, id_or_code: str = None) -> Set:
"""
return await self._get_item(f"/sets/{id_or_code}", Set)

set = synchronize(sets_async)

async def _get_item(self, path, model: T = None, **kwargs) -> Union[T, Any]:
try:
response = await self.client.get(path, **kwargs)
Expand Down
44 changes: 30 additions & 14 deletions src/mightstone/services/scryfall/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ def scryfall(obj: ScryfallObj, **kwargs):
@click.option("--limit", type=int)
@catch_service_error
def scryfall_sets(obj: ScryfallObj, **kwargs):
pretty_print(stream_as_list(obj["client"].sets(**kwargs)), obj.get("format"))
pretty_print(stream_as_list(obj["client"].sets_async(**kwargs)), obj.get("format"))


@scryfall.command(name="set")
@click.pass_obj
@click.argument("id_or_code", type=str)
def scryfall_set(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].set(**kwargs)), obj.get("format"))
pretty_print(asyncio_run(obj["client"].set_async(**kwargs)), obj.get("format"))


@scryfall.command()
Expand All @@ -46,7 +46,7 @@ def scryfall_set(obj: ScryfallObj, **kwargs):
@click.argument("type", type=click.Choice([t.value for t in CardIdentifierPath]))
@catch_service_error
def card(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].card(**kwargs)), obj.get("format"))
pretty_print(asyncio_run(obj["client"].card_async(**kwargs)), obj.get("format"))


@scryfall.command()
Expand All @@ -55,15 +55,17 @@ def card(obj: ScryfallObj, **kwargs):
@click.option("--limit", type=int, default=100)
@catch_service_error
def search(obj: ScryfallObj, **kwargs):
pretty_print(stream_as_list(obj["client"].search(**kwargs)), obj.get("format"))
pretty_print(
stream_as_list(obj["client"].search_async(**kwargs)), obj.get("format")
)


@scryfall.command()
@click.pass_obj
@click.argument("q", type=str)
@catch_service_error
def random(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].random(**kwargs)), obj.get("format"))
pretty_print(asyncio_run(obj["client"].random_async(**kwargs)), obj.get("format"))


@scryfall.command()
Expand All @@ -73,7 +75,7 @@ def random(obj: ScryfallObj, **kwargs):
@click.option("--set", type=str)
@catch_service_error
def named(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].named(**kwargs)), obj.get("format"))
pretty_print(asyncio_run(obj["client"].named_async(**kwargs)), obj.get("format"))


@scryfall.command()
Expand All @@ -82,7 +84,9 @@ def named(obj: ScryfallObj, **kwargs):
@click.option("--include_extras", type=bool, is_flag=True)
@catch_service_error
def autocomplete(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].autocomplete(**kwargs)), obj.get("format"))
pretty_print(
asyncio_run(obj["client"].autocomplete_async(**kwargs)), obj.get("format")
)


class ScryfallIdentifier(click.ParamType):
Expand All @@ -109,7 +113,9 @@ def collection(obj: ScryfallObj, **kwargs):
:param kwargs:
:return:
"""
pretty_print(stream_as_list(obj["client"].collection(**kwargs)), obj.get("format"))
pretty_print(
stream_as_list(obj["client"].collection_async(**kwargs)), obj.get("format")
)


@scryfall.command()
Expand All @@ -119,44 +125,54 @@ def collection(obj: ScryfallObj, **kwargs):
@click.option("-l", "--limit", type=int)
@catch_service_error
def rulings(obj: ScryfallObj, **kwargs):
pretty_print(stream_as_list(obj["client"].rulings(**kwargs)), obj.get("format"))
pretty_print(
stream_as_list(obj["client"].rulings_async(**kwargs)), obj.get("format")
)


@scryfall.command()
@click.pass_obj
@click.option("-l", "--limit", type=int, required=False)
@catch_service_error
def symbols(obj: ScryfallObj, **kwargs):
pretty_print(stream_as_list(obj["client"].symbols(**kwargs)), obj.get("format"))
pretty_print(
stream_as_list(obj["client"].symbols_async(**kwargs)), obj.get("format")
)


@scryfall.command()
@click.pass_obj
@click.argument("cost", type=str)
@catch_service_error
def parse_mana(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].parse_mana(**kwargs)), obj.get("format"))
pretty_print(
asyncio_run(obj["client"].parse_mana_async(**kwargs)), obj.get("format")
)


@scryfall.command()
@click.pass_obj
@click.argument("type", type=click.Choice([t.value for t in CatalogType]))
@catch_service_error
def catalog(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].catalog(**kwargs)), obj.get("format"))
pretty_print(asyncio_run(obj["client"].catalog_async(**kwargs)), obj.get("format"))


@scryfall.command()
@click.pass_obj
@click.option("-l", "--limit", type=int, default=100)
@catch_service_error
def migrations(obj: ScryfallObj, **kwargs):
pretty_print(stream_as_list(obj["client"].migrations(**kwargs)), obj.get("format"))
pretty_print(
stream_as_list(obj["client"].migrations_async(**kwargs)), obj.get("format")
)


@scryfall.command()
@click.pass_obj
@click.argument("id", type=str)
@catch_service_error
def migration(obj: ScryfallObj, **kwargs):
pretty_print(asyncio_run(obj["client"].migration(**kwargs)), obj.get("format"))
pretty_print(
asyncio_run(obj["client"].migration_async(**kwargs)), obj.get("format")
)

0 comments on commit d82bed1

Please sign in to comment.