scryfall-py/pyfall/models/cards.py

161 lines
No EOL
5.1 KiB
Python

from datetime import date
from typing import Any, Literal, TYPE_CHECKING
from pydantic import BaseModel, HttpUrl, field_validator
from pydantic.types import UUID
# from pyfall.models.api import APIList
from pyfall.models.base import BaseAPIModel
from pyfall.models.enums import Color
if TYPE_CHECKING:
from pyfall.client import Pyfall
from pyfall.models.rulings import Ruling
from pyfall.models.sets import Set
class RelatedCard(BaseModel):
id: UUID
object: Literal["related_card"]
component: Literal["token", "meld_part", "meld_result", "combo_piece"]
name: str
type_line: str
uri: HttpUrl
class CardFace(BaseModel):
artist: str | None = None
artist_id: str | None = None
cmc: float | None = None
color_indicator: list[Color] | None = None
colors: list[Color] | None = None
defense: str | None = None
flavor_text: str | None = None
illustration_id: UUID | None = None
image_uris: dict[Literal["small", "normal", "large", "png", "art_crop", "border_crop"], HttpUrl] | None = None
layout: str | None = None
loyalty: str | None = None
mana_cost: str
name: str
object: Literal["card_face"]
oracle_id: UUID | None = None
oracle_text: str | None = None
power: str | None = None
printed_name: str | None = None
printed_text: str | None = None
printed_type_line: str | None = None
toughness: str | None = None
type_line: str | None = None
watermark: str | None = None
class Preview(BaseModel):
previewed_at: date | None = None
source_uri: HttpUrl | None = None
source: str | None = None
@field_validator("source_uri", mode="before")
@classmethod
def validate_source_uri(cls, value: Any) -> Any:
if isinstance(value, str):
if len(value) > 0:
return HttpUrl(value)
return None
class Card(BaseAPIModel):
# Core fields
arena_id: int | None = None
id: UUID
lang: str
mtgo_id: int | None = None
mtgo_foil_id: int | None = None
multiverse_ids: list[int] | None = None
tcgplayer_id: int | None = None
tcgplayer_etched_id: int | None = None
cardmarket_id: int | None = None
object: Literal["card"]
layout: str
oracle_id: UUID | None = None
prints_search_uri: HttpUrl
rulings_uri: HttpUrl
scryfall_uri: HttpUrl
uri: HttpUrl
# Gameplay fields
all_parts: list[RelatedCard] | None = None
card_faces: list[CardFace] | None = None
cmc: float
color_identity: list[Color]
color_indicator: list[Color] | None = None
colors: list[Color] | None = None
defense: str | None = None
edhrec_rank: int | None = None
game_changer: bool | None = None
hand_modifier: str | None = None
keywords: list[str]
legalities: dict[str, Literal["legal", "not_legal", "restricted", "banned"]]
life_modifier: str | None = None
loyalty: str | None = None
mana_cost: str | None = None
name: str
oracle_text: str | None = None
penny_rank: int | None = None
power: str | None = None
produced_mana: list[Color] | None = None
reserved: bool
toughness: str | None = None
type_line: str
# Print fields
artist: str | None = None
artist_ids: list[UUID] | None = None
attraction_lights: list[int] | None = None
booster: bool
border_color: Literal["black", "white", "borderless", "yellow", "silver", "gold"]
card_back_id: UUID | None = None
collector_number: str
content_warning: bool | None = None
digital: bool
finishes: list[Literal["foil", "nonfoil", "etched"]]
flavor_name: str | None = None
flavor_text: str | None = None
frame_effects: list[str] | None = None
frame: str
full_art: bool
games: list[Literal["paper", "arena", "mtgo"]]
highres_image: bool
illustration_id: UUID | None = None
image_status: Literal["missing", "placeholder", "lowres", "highres_scan"]
image_uris: dict[Literal["small", "normal", "large", "png", "art_crop", "border_crop"], HttpUrl] | None = None
oversized: bool
prices: dict[str, str | None]
printed_name: str | None = None
printed_text: str | None = None
printed_type_line: str | None = None
promo: bool
promo_types: list[str] | None = None
purchase_uris: dict[str, HttpUrl] | None = None
rarity: Literal["common", "uncommon", "rare", "special", "mythic", "bonus"]
related_uris: dict[str, HttpUrl]
released_at: date
reprint: bool
scryfall_set_uri: HttpUrl
set_name: str
set_search_uri: HttpUrl
set_type: str
set_uri: HttpUrl
set: str
set_id: UUID
story_spotlight: bool
textless: bool
variation: bool
variation_of: UUID | None = None
security_stamp: Literal["oval", "triangle", "acorn", "circle", "arena", "heart"] | None = None
watermark: str | None = None
preview: Preview | None = None
async def get_set(self) -> "Set":
"""Get set card is a part of."""
return await self._client.get_set_by_id(self.set_id)
async def get_rulings(self) -> "Ruling":
"""Get rulings for card."""
return await self._client.get_rulings_by_card_id(self.id)