Compare commits
No commits in common. "main" and "v0.1.0" have entirely different histories.
20 changed files with 50 additions and 499 deletions
44
.github/workflows/docs.yml
vendored
44
.github/workflows/docs.yml
vendored
|
@ -1,44 +0,0 @@
|
||||||
name: docs-builder
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event.repository.fork == false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install uv
|
|
||||||
uses: astral-sh/setup-uv@v5
|
|
||||||
with:
|
|
||||||
version: "0.6.3"
|
|
||||||
- name: Set up Python 3.13
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.13"
|
|
||||||
|
|
||||||
- name: Install the project
|
|
||||||
run: uv sync --all-extras --dev
|
|
||||||
|
|
||||||
- name: Build the docs
|
|
||||||
run: cd docs && uv run make html
|
|
||||||
|
|
||||||
- name: Upload the artifact
|
|
||||||
uses: actions/upload-pages-artifact@v3
|
|
||||||
with:
|
|
||||||
path: docs/_build/html
|
|
||||||
|
|
||||||
- name: Deploy to GH Pages
|
|
||||||
uses: actions/deploy-pages@v4
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -15,6 +15,3 @@ report.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
.ruff_cache/
|
.ruff_cache/
|
||||||
|
|
||||||
# Docs
|
|
||||||
_build/
|
|
|
@ -1,11 +0,0 @@
|
||||||
version: 2
|
|
||||||
|
|
||||||
python:
|
|
||||||
install:
|
|
||||||
- requirements: docs/requirements.txt
|
|
||||||
- requirements: requirements.txt
|
|
||||||
|
|
||||||
sphinx:
|
|
||||||
builder: html
|
|
||||||
configuration: docs/conf.py
|
|
||||||
|
|
23
README.md
23
README.md
|
@ -1,26 +1,3 @@
|
||||||
# Scryfall-py
|
# Scryfall-py
|
||||||
|
|
||||||
An async Scryfall API wrapper written in Python
|
An async Scryfall API wrapper written in Python
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
To get started, install `scryfall-py`
|
|
||||||
|
|
||||||
`pip install scryfall-py`
|
|
||||||
|
|
||||||
### Getting started
|
|
||||||
|
|
||||||
```py
|
|
||||||
from scryfall import Scryfall
|
|
||||||
client = Scryfall()
|
|
||||||
|
|
||||||
card = await client.search_cards_named("Arcades, the Strategist")
|
|
||||||
```
|
|
||||||
|
|
||||||
This will fetch the card Arcades, the Strategist from the Scryfall API
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
Documentation is located at [GitHub Pages](https://zevaryx.github.io/scryfall-py/)
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Minimal makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line, and also
|
|
||||||
# from the environment for the first two.
|
|
||||||
SPHINXOPTS ?=
|
|
||||||
SPHINXBUILD ?= sphinx-build
|
|
||||||
SOURCEDIR = .
|
|
||||||
BUILDDIR = _build
|
|
||||||
|
|
||||||
# Put it first so that "make" without argument is like "make help".
|
|
||||||
help:
|
|
||||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
||||||
|
|
||||||
.PHONY: help Makefile
|
|
||||||
|
|
||||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
||||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
||||||
%: Makefile
|
|
||||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
43
docs/api.rst
43
docs/api.rst
|
@ -1,43 +0,0 @@
|
||||||
.. currentmodule:: scryfall
|
|
||||||
.. _API Reference:
|
|
||||||
|
|
||||||
API Reference
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Client
|
|
||||||
******
|
|
||||||
.. automodule:: scryfall.client
|
|
||||||
:members:
|
|
||||||
:member-order: bysource
|
|
||||||
|
|
||||||
HTTP
|
|
||||||
~~~~
|
|
||||||
.. automodule:: scryfall.client.http
|
|
||||||
:members:
|
|
||||||
:member-order: bysource
|
|
||||||
|
|
||||||
Card
|
|
||||||
----
|
|
||||||
.. automodule:: scryfall.client.http.card
|
|
||||||
:members:
|
|
||||||
:member-order: bysource
|
|
||||||
|
|
||||||
Set
|
|
||||||
----
|
|
||||||
.. automodule:: scryfall.client.http.set
|
|
||||||
:members:
|
|
||||||
:member-order: bysource
|
|
||||||
|
|
||||||
Models
|
|
||||||
******
|
|
||||||
.. automodule:: scryfall.models
|
|
||||||
:members:
|
|
||||||
:member-order: bysource
|
|
||||||
|
|
||||||
.. Card
|
|
||||||
.. ~~~~
|
|
||||||
.. .. automodule:: scryfall.models.cards
|
|
||||||
|
|
||||||
.. Set
|
|
||||||
.. ~~~~
|
|
||||||
.. .. automodule:: scryfall.models.sets
|
|
38
docs/conf.py
38
docs/conf.py
|
@ -1,38 +0,0 @@
|
||||||
# Configuration file for the Sphinx documentation builder.
|
|
||||||
#
|
|
||||||
# For the full list of built-in configuration values, see the documentation:
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
||||||
|
|
||||||
project = "scryfall-py"
|
|
||||||
copyright = "2025, zevaryx"
|
|
||||||
author = "zevaryx"
|
|
||||||
release = "0.1.1"
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
||||||
|
|
||||||
extensions = [
|
|
||||||
"sphinx.ext.duration",
|
|
||||||
"sphinx.ext.autodoc",
|
|
||||||
"sphinx.ext.autosummary",
|
|
||||||
"sphinx.ext.napoleon",
|
|
||||||
"enum_tools.autoenum",
|
|
||||||
]
|
|
||||||
|
|
||||||
templates_path = ["_templates"]
|
|
||||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
||||||
|
|
||||||
html_theme = "sphinx_rtd_theme"
|
|
||||||
html_static_path = ["_static"]
|
|
||||||
|
|
||||||
# Custom config
|
|
||||||
autodoc_default_flags = ["members"]
|
|
||||||
master_doc = "index"
|
|
||||||
source_suffix = [".rst", ".md"]
|
|
|
@ -1,22 +0,0 @@
|
||||||
Usage
|
|
||||||
===============
|
|
||||||
|
|
||||||
Installation
|
|
||||||
************
|
|
||||||
|
|
||||||
To get started, install ``scryfall-py``::
|
|
||||||
|
|
||||||
pip install scryfall-py
|
|
||||||
|
|
||||||
|
|
||||||
Getting Started
|
|
||||||
***************
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from scryfall import Scryfall
|
|
||||||
client = Scryfall()
|
|
||||||
|
|
||||||
card = await client.search_cards_named("Arcades, the Strategist")
|
|
||||||
|
|
||||||
This will fetch the card Arcades, the Strategist from the Scryfall API
|
|
|
@ -1,17 +0,0 @@
|
||||||
Welcome to the scryfall-py documentation!
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
:caption: Contents:
|
|
||||||
|
|
||||||
guide
|
|
||||||
api
|
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
|
@ -1,35 +0,0 @@
|
||||||
@ECHO OFF
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
REM Command file for Sphinx documentation
|
|
||||||
|
|
||||||
if "%SPHINXBUILD%" == "" (
|
|
||||||
set SPHINXBUILD=sphinx-build
|
|
||||||
)
|
|
||||||
set SOURCEDIR=.
|
|
||||||
set BUILDDIR=_build
|
|
||||||
|
|
||||||
%SPHINXBUILD% >NUL 2>NUL
|
|
||||||
if errorlevel 9009 (
|
|
||||||
echo.
|
|
||||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
|
||||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
|
||||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
|
||||||
echo.may add the Sphinx directory to PATH.
|
|
||||||
echo.
|
|
||||||
echo.If you don't have Sphinx installed, grab it from
|
|
||||||
echo.https://www.sphinx-doc.org/
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "" goto help
|
|
||||||
|
|
||||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
||||||
goto end
|
|
||||||
|
|
||||||
:help
|
|
||||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
||||||
|
|
||||||
:end
|
|
||||||
popd
|
|
|
@ -1,6 +1,6 @@
|
||||||
[project]
|
[project]
|
||||||
name = "scryfall-py"
|
name = "scryfall-py"
|
||||||
version = "0.1.1"
|
version = "0.1.0"
|
||||||
description = "An async Scryfall API wrapper"
|
description = "An async Scryfall API wrapper"
|
||||||
license = { text = "MIT License" }
|
license = { text = "MIT License" }
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -16,15 +16,9 @@ classifiers = [
|
||||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||||
"Topic :: Utilities",
|
"Topic :: Utilities",
|
||||||
]
|
]
|
||||||
authors = [{name="zevaryx", email ="zevaryx@gmail.com"}]
|
|
||||||
|
|
||||||
dependencies = ["httpx>=0.28.1", "pydantic>=2.10.6"]
|
dependencies = ["httpx>=0.28.1", "pydantic>=2.10.6"]
|
||||||
|
|
||||||
[project.urls]
|
|
||||||
Homepage = "https://github.com/zevaryx/scryfall-py"
|
|
||||||
Repository = "https://github.com/zevaryx/scryfall-py"
|
|
||||||
Issues = "https://github.com/zevaryx/scryfall-py/issues"
|
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
"black>=25.1.0",
|
"black>=25.1.0",
|
||||||
|
@ -38,7 +32,6 @@ dev = [
|
||||||
"sphinx>=8.2.1",
|
"sphinx>=8.2.1",
|
||||||
"sphinx-rtd-theme>=3.0.2",
|
"sphinx-rtd-theme>=3.0.2",
|
||||||
"pytest-asyncio>=0.25.3",
|
"pytest-asyncio>=0.25.3",
|
||||||
"enum-tools>=0.12.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
|
@ -10,8 +10,8 @@ from httpx import AsyncClient
|
||||||
|
|
||||||
from scryfall.const import get_logger
|
from scryfall.const import get_logger
|
||||||
from scryfall.client.error import LibraryException, HTTPException, ScryfallError, Forbidden, NotFound
|
from scryfall.client.error import LibraryException, HTTPException, ScryfallError, Forbidden, NotFound
|
||||||
from scryfall.client.http.card import CardRequests
|
from scryfall.client.http.http_requests.card import CardRequests
|
||||||
from scryfall.client.http.set import SetRequests
|
from scryfall.client.http.http_requests.set import SetRequests
|
||||||
from scryfall.client.route import Route
|
from scryfall.client.route import Route
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
__version__ = "0.1.1"
|
__version__ = "0.1.0"
|
||||||
|
|
||||||
logger_name = "scryfall"
|
logger_name = "scryfall"
|
||||||
|
|
||||||
|
|
|
@ -12,44 +12,20 @@ CLASS_LOOKUP = {"card": Card, "card_symbol": CardSymbol, "ruling": Ruling, "set"
|
||||||
|
|
||||||
|
|
||||||
class APIError(BaseModel):
|
class APIError(BaseModel):
|
||||||
"""Scryfall API error model."""
|
|
||||||
|
|
||||||
status: int
|
status: int
|
||||||
"""HTTP status code"""
|
|
||||||
|
|
||||||
code: str
|
code: str
|
||||||
"""HTTP status code text (i.e. not_found)"""
|
|
||||||
|
|
||||||
details: str
|
details: str
|
||||||
"""More details"""
|
|
||||||
|
|
||||||
type: str | None = None
|
type: str | None = None
|
||||||
"""The error type"""
|
|
||||||
|
|
||||||
warnings: list[str] | None = None
|
warnings: list[str] | None = None
|
||||||
"""Any associated warnings that are not quite errors"""
|
|
||||||
|
|
||||||
|
|
||||||
class APIList(BaseAPIModel):
|
class APIList(BaseAPIModel):
|
||||||
"""Scryfall API list model for paginated requests"""
|
|
||||||
|
|
||||||
object: Literal["list"]
|
object: Literal["list"]
|
||||||
"""The object type, `list` in this case"""
|
|
||||||
|
|
||||||
data: list[Card | CardSymbol | Ruling | Set]
|
data: list[Card | CardSymbol | Ruling | Set]
|
||||||
"""The page of data, max 175 items unless it is an entire set of cards"""
|
|
||||||
|
|
||||||
has_more: bool
|
has_more: bool
|
||||||
"""If there are more pages"""
|
|
||||||
|
|
||||||
next_page: HttpUrl | None = None
|
next_page: HttpUrl | None = None
|
||||||
"""The URL to the next page"""
|
|
||||||
|
|
||||||
total_cards: int | None = None
|
total_cards: int | None = None
|
||||||
"""The total number of cards found by the original query"""
|
|
||||||
|
|
||||||
warnings: list[str] | None = None
|
warnings: list[str] | None = None
|
||||||
"""Warnings generated by the query that are not quite errors"""
|
|
||||||
|
|
||||||
@model_validator(mode="before")
|
@model_validator(mode="before")
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -64,7 +40,6 @@ class APIList(BaseAPIModel):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
async def get_next_page(self) -> "APIList | None":
|
async def get_next_page(self) -> "APIList | None":
|
||||||
"""Get the next page of the query"""
|
|
||||||
if self.has_more and self.next_page is not None:
|
if self.has_more and self.next_page is not None:
|
||||||
params = dict(self.next_page.query_params())
|
params = dict(self.next_page.query_params())
|
||||||
params.pop("format", None)
|
params.pop("format", None)
|
||||||
|
|
|
@ -10,7 +10,6 @@ class BaseAPIModel(BaseModel):
|
||||||
"""Base API model for base API calls."""
|
"""Base API model for base API calls."""
|
||||||
|
|
||||||
_client: "Scryfall"
|
_client: "Scryfall"
|
||||||
"""Internal Scryfall client"""
|
|
||||||
|
|
||||||
def __init__(self, **data):
|
def __init__(self, **data):
|
||||||
client: "Scryfall" = data["_client"]
|
client: "Scryfall" = data["_client"]
|
||||||
|
|
|
@ -5,34 +5,13 @@ from pydantic import BaseModel, HttpUrl
|
||||||
|
|
||||||
|
|
||||||
class BulkData(BaseModel):
|
class BulkData(BaseModel):
|
||||||
"""Bulk data model"""
|
|
||||||
|
|
||||||
id: UUID
|
id: UUID
|
||||||
"""UUID of the bulk data"""
|
|
||||||
|
|
||||||
uri: HttpUrl
|
uri: HttpUrl
|
||||||
"""URI of the bulk data endpoint"""
|
|
||||||
|
|
||||||
type: str
|
type: str
|
||||||
"""The type of data in the download"""
|
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
"""The name of the download"""
|
|
||||||
|
|
||||||
description: str
|
description: str
|
||||||
"""A description of the download"""
|
|
||||||
|
|
||||||
download_uri: HttpUrl
|
download_uri: HttpUrl
|
||||||
"""The download URL for the bulk data"""
|
|
||||||
|
|
||||||
updated_at: datetime
|
updated_at: datetime
|
||||||
"""When this bulk data was last updated"""
|
|
||||||
|
|
||||||
size: int
|
size: int
|
||||||
"""The size of the data in bytes"""
|
|
||||||
|
|
||||||
content_type: str
|
content_type: str
|
||||||
"""The content type"""
|
|
||||||
|
|
||||||
content_encoding: str
|
content_encoding: str
|
||||||
"""The MIME encoding"""
|
|
||||||
|
|
|
@ -13,112 +13,44 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
|
|
||||||
class RelatedCard(BaseModel):
|
class RelatedCard(BaseModel):
|
||||||
"""A card that's related to the current card"""
|
|
||||||
|
|
||||||
id: UUID
|
id: UUID
|
||||||
"""The UUID of the related card"""
|
|
||||||
|
|
||||||
object: Literal["related_card"]
|
object: Literal["related_card"]
|
||||||
"""The object type, literally `related_card`"""
|
|
||||||
|
|
||||||
component: Literal["token", "meld_part", "meld_result", "combo_piece"]
|
component: Literal["token", "meld_part", "meld_result", "combo_piece"]
|
||||||
"""How the card is related"""
|
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
"""The name of the related card"""
|
|
||||||
|
|
||||||
type_line: str
|
type_line: str
|
||||||
"""The type line of the related card"""
|
|
||||||
|
|
||||||
uri: HttpUrl
|
uri: HttpUrl
|
||||||
"""The URL of the related card"""
|
|
||||||
|
|
||||||
|
|
||||||
class CardFace(BaseModel):
|
class CardFace(BaseModel):
|
||||||
"""A card face, for multi-faced cards"""
|
|
||||||
|
|
||||||
artist: str | None = None
|
artist: str | None = None
|
||||||
"""The face artist"""
|
|
||||||
|
|
||||||
artist_id: str | None = None
|
artist_id: str | None = None
|
||||||
"""The ID of the face artist"""
|
|
||||||
|
|
||||||
cmc: float | None = None
|
cmc: float | None = None
|
||||||
"""Card Mana Cost"""
|
|
||||||
|
|
||||||
color_indicator: list[Color] | None = None
|
color_indicator: list[Color] | None = None
|
||||||
"""The color indicator(s) of the face"""
|
|
||||||
|
|
||||||
colors: list[Color] | None = None
|
colors: list[Color] | None = None
|
||||||
"""The color(s) of the face"""
|
|
||||||
|
|
||||||
defense: str | None = None
|
defense: str | None = None
|
||||||
"""The toughness of the face, if it exists"""
|
|
||||||
|
|
||||||
flavor_text: str | None = None
|
flavor_text: str | None = None
|
||||||
"""The face's flavor text"""
|
|
||||||
|
|
||||||
illustration_id: UUID | None = None
|
illustration_id: UUID | None = None
|
||||||
"""The face's illustration UUID"""
|
|
||||||
|
|
||||||
image_uris: dict[Literal["small", "normal", "large", "png", "art_crop", "border_crop"], HttpUrl] | None = None
|
image_uris: dict[Literal["small", "normal", "large", "png", "art_crop", "border_crop"], HttpUrl] | None = None
|
||||||
"""URLs for the image face for different formats."""
|
|
||||||
|
|
||||||
layout: str | None = None
|
layout: str | None = None
|
||||||
"""Layout of the face."""
|
|
||||||
|
|
||||||
loyalty: str | None = None
|
loyalty: str | None = None
|
||||||
"""Face loyalty"""
|
|
||||||
|
|
||||||
mana_cost: str
|
mana_cost: str
|
||||||
"""Face mana cost"""
|
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
"""Name of the face"""
|
|
||||||
|
|
||||||
object: Literal["card_face"]
|
object: Literal["card_face"]
|
||||||
"""Object type, literally `card_face`"""
|
|
||||||
|
|
||||||
oracle_id: UUID | None = None
|
oracle_id: UUID | None = None
|
||||||
"""Oracle ID of the face"""
|
|
||||||
|
|
||||||
oracle_text: str | None = None
|
oracle_text: str | None = None
|
||||||
"""Oracle text of the face"""
|
|
||||||
|
|
||||||
power: str | None = None
|
power: str | None = None
|
||||||
"""The face's power"""
|
|
||||||
|
|
||||||
printed_name: str | None = None
|
printed_name: str | None = None
|
||||||
"""The printed name of the face"""
|
|
||||||
|
|
||||||
printed_text: str | None = None
|
printed_text: str | None = None
|
||||||
"""The printed text of the face"""
|
|
||||||
|
|
||||||
printed_type_line: str | None = None
|
printed_type_line: str | None = None
|
||||||
"""The printed type line of the face"""
|
|
||||||
|
|
||||||
toughness: str | None = None
|
toughness: str | None = None
|
||||||
"""The toughness of the face"""
|
|
||||||
|
|
||||||
type_line: str | None = None
|
type_line: str | None = None
|
||||||
"""The type line of the face"""
|
|
||||||
|
|
||||||
watermark: str | None = None
|
watermark: str | None = None
|
||||||
"""The watermark of the face"""
|
|
||||||
|
|
||||||
|
|
||||||
class Preview(BaseModel):
|
class Preview(BaseModel):
|
||||||
"""Object for defining when the card was previewed."""
|
|
||||||
|
|
||||||
previewed_at: date | None = None
|
previewed_at: date | None = None
|
||||||
|
|
||||||
"""When it was previewed"""
|
|
||||||
|
|
||||||
source_uri: HttpUrl | None = None
|
source_uri: HttpUrl | None = None
|
||||||
"""The URL of where it was previewed"""
|
|
||||||
|
|
||||||
source: str | None = None
|
source: str | None = None
|
||||||
"""The source of the preview"""
|
|
||||||
|
|
||||||
@field_validator("source_uri", mode="before")
|
@field_validator("source_uri", mode="before")
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -130,104 +62,48 @@ class Preview(BaseModel):
|
||||||
|
|
||||||
|
|
||||||
class Card(BaseAPIModel):
|
class Card(BaseAPIModel):
|
||||||
"""Main Card model."""
|
|
||||||
|
|
||||||
# Core fields
|
# Core fields
|
||||||
arena_id: int | None = None
|
arena_id: int | None = None
|
||||||
"""MTG Arena ID"""
|
|
||||||
|
|
||||||
id: UUID
|
id: UUID
|
||||||
"""Scryfall card UUID"""
|
|
||||||
|
|
||||||
lang: str
|
lang: str
|
||||||
"""Card language"""
|
|
||||||
|
|
||||||
mtgo_id: int | None = None
|
mtgo_id: int | None = None
|
||||||
"""MTG Online ID"""
|
|
||||||
|
|
||||||
mtgo_foil_id: int | None = None
|
mtgo_foil_id: int | None = None
|
||||||
"""MTG Online Foil ID"""
|
|
||||||
|
|
||||||
multiverse_ids: list[int] | None = None
|
multiverse_ids: list[int] | None = None
|
||||||
"""MTG Multiverse IDs"""
|
|
||||||
|
|
||||||
tcgplayer_id: int | None = None
|
tcgplayer_id: int | None = None
|
||||||
"""TCGPlayer ID"""
|
|
||||||
|
|
||||||
tcgplayer_etched_id: int | None = None
|
tcgplayer_etched_id: int | None = None
|
||||||
"""TCGPlayer Etched ID"""
|
|
||||||
|
|
||||||
cardmarket_id: int | None = None
|
cardmarket_id: int | None = None
|
||||||
"""Cardmarket ID"""
|
|
||||||
|
|
||||||
object: Literal["card"]
|
object: Literal["card"]
|
||||||
"""Object type, literally `card`"""
|
|
||||||
|
|
||||||
layout: str
|
layout: str
|
||||||
"""Card layout"""
|
|
||||||
|
|
||||||
oracle_id: UUID | None = None
|
oracle_id: UUID | None = None
|
||||||
"""Oracle UUID"""
|
|
||||||
|
|
||||||
prints_search_uri: HttpUrl
|
prints_search_uri: HttpUrl
|
||||||
"""Print search URL for other printings"""
|
|
||||||
|
|
||||||
rulings_uri: HttpUrl
|
rulings_uri: HttpUrl
|
||||||
"""Rulings URL"""
|
|
||||||
|
|
||||||
scryfall_uri: HttpUrl
|
scryfall_uri: HttpUrl
|
||||||
"""Scryfall URL"""
|
|
||||||
|
|
||||||
uri: HttpUrl
|
uri: HttpUrl
|
||||||
"""Card URL"""
|
|
||||||
|
|
||||||
# Gameplay fields
|
# Gameplay fields
|
||||||
all_parts: list[RelatedCard] | None = None
|
all_parts: list[RelatedCard] | None = None
|
||||||
"""If this card is closely related to other cards, this property will be an array with Related Card objects."""
|
|
||||||
card_faces: list[CardFace] | None = None
|
card_faces: list[CardFace] | None = None
|
||||||
"""All faces of the card"""
|
|
||||||
cmc: float
|
cmc: float
|
||||||
"""Card mana value"""
|
|
||||||
color_identity: list[Color]
|
color_identity: list[Color]
|
||||||
"""Card color identity"""
|
|
||||||
color_indicator: list[Color] | None = None
|
color_indicator: list[Color] | None = None
|
||||||
"""Card color indicator, if any"""
|
|
||||||
colors: list[Color] | None = None
|
colors: list[Color] | None = None
|
||||||
"""Card colors, if any. Colors may be on the card's faces instead"""
|
|
||||||
defense: str | None = None
|
defense: str | None = None
|
||||||
"""Toughness"""
|
|
||||||
edhrec_rank: int | None = None
|
edhrec_rank: int | None = None
|
||||||
"""EDHRec card rank/popularity"""
|
|
||||||
game_changer: bool | None = None
|
game_changer: bool | None = None
|
||||||
"""If this car is on the Commander Game Changer list"""
|
|
||||||
hand_modifier: str | None = None
|
hand_modifier: str | None = None
|
||||||
"""Vanguard card hand modifier"""
|
|
||||||
keywords: list[str]
|
keywords: list[str]
|
||||||
"""List of keywords, such as `Flying` or `Cumulative upkeep`"""
|
|
||||||
legalities: dict[str, Literal["legal", "not_legal", "restricted", "banned"]]
|
legalities: dict[str, Literal["legal", "not_legal", "restricted", "banned"]]
|
||||||
"""List of legalitites across different formats"""
|
|
||||||
life_modifier: str | None = None
|
life_modifier: str | None = None
|
||||||
"""The card's life modifier, if it is a Vanguard card. This value will contain a delta, such as `+2`."""
|
|
||||||
loyalty: str | None = None
|
loyalty: str | None = None
|
||||||
"""This loyalty if any. Note that some cards have loyalties that are not numeric, such as X."""
|
|
||||||
mana_cost: str | None = None
|
mana_cost: str | None = None
|
||||||
"""The mana cost for this card. This value will be any empty string `""` if the cost is absent. Remember that per the game rules, a missing mana cost and a mana cost of `{0}` are different values. Multi-faced cards will report this value in card faces."""
|
|
||||||
name: str
|
name: str
|
||||||
"""The name of this card. If this card has multiple faces, this field will contain both names separated by `␣//␣`."""
|
|
||||||
oracle_text: str | None = None
|
oracle_text: str | None = None
|
||||||
"""The Oracle text for this card, if any."""
|
|
||||||
penny_rank: int | None = None
|
penny_rank: int | None = None
|
||||||
"""This card's rank/popularity on Penny Dreadful. Not all cards are ranked."""
|
|
||||||
power: str | None = None
|
power: str | None = None
|
||||||
"""This card's power, if any. Note that some cards have powers that are not numeric, such as `*`."""
|
|
||||||
produced_mana: list[Color] | None = None
|
produced_mana: list[Color] | None = None
|
||||||
"""Colors of mana that this card could produce."""
|
|
||||||
reserved: bool
|
reserved: bool
|
||||||
"""True if this card is on the Reserved List."""
|
|
||||||
toughness: str | None = None
|
toughness: str | None = None
|
||||||
"""This card's toughness, if any. Note that some cards have toughnesses that are not numeric, such as `*`."""
|
|
||||||
type_line: str
|
type_line: str
|
||||||
"""The type line of this card."""
|
|
||||||
|
|
||||||
# Print fields
|
# Print fields
|
||||||
artist: str | None = None
|
artist: str | None = None
|
||||||
|
|
105
uv.lock
generated
105
uv.lock
generated
|
@ -297,19 +297,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/5b/11/208f72084084d3f6a2ed5ebfdfc846692c3f7ad6dce65e400194924f7eed/domdf_python_tools-3.10.0-py3-none-any.whl", hash = "sha256:5e71c1be71bbcc1f881d690c8984b60e64298ec256903b3147f068bc33090c36", size = 126860 },
|
{ url = "https://files.pythonhosted.org/packages/5b/11/208f72084084d3f6a2ed5ebfdfc846692c3f7ad6dce65e400194924f7eed/domdf_python_tools-3.10.0-py3-none-any.whl", hash = "sha256:5e71c1be71bbcc1f881d690c8984b60e64298ec256903b3147f068bc33090c36", size = 126860 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "enum-tools"
|
|
||||||
version = "0.12.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "pygments" },
|
|
||||||
{ name = "typing-extensions" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/94/06/55dfd19df0386a2a90d325dba67b0b5ba0b879a4bdac9cd225c22f6736d8/enum_tools-0.12.0.tar.gz", hash = "sha256:13ceb9376a4c5f574a1e7c5f9c8eb7f3d3fbfbb361cc18a738df1a58dfefd460", size = 18931 }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/fc/cc600677fe58519352ae5fe9367d05d0054faa47e8c57ef50a1bb9c77b0e/enum_tools-0.12.0-py3-none-any.whl", hash = "sha256:d69b019f193c7b850b17d9ce18440db7ed62381571409af80ccc08c5218b340a", size = 22356 },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "executing"
|
name = "executing"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
@ -729,6 +716,51 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 },
|
{ url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scryfall"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { editable = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "httpx" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dev-dependencies]
|
||||||
|
dev = [
|
||||||
|
{ name = "black" },
|
||||||
|
{ name = "ipython" },
|
||||||
|
{ name = "pre-commit" },
|
||||||
|
{ name = "pytest" },
|
||||||
|
{ name = "pytest-asyncio" },
|
||||||
|
{ name = "pytest-cov" },
|
||||||
|
{ name = "rich" },
|
||||||
|
{ name = "ruff" },
|
||||||
|
{ name = "sphinx" },
|
||||||
|
{ name = "sphinx-rtd-theme" },
|
||||||
|
{ name = "sphinx-toolbox" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "httpx", specifier = ">=0.28.1" },
|
||||||
|
{ name = "pydantic", specifier = ">=2.10.6" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata.requires-dev]
|
||||||
|
dev = [
|
||||||
|
{ name = "black", specifier = ">=25.1.0" },
|
||||||
|
{ name = "ipython", specifier = ">=9.0.0" },
|
||||||
|
{ name = "pre-commit", specifier = ">=4.0.1" },
|
||||||
|
{ name = "pytest", specifier = ">=8.3.3" },
|
||||||
|
{ name = "pytest-asyncio", specifier = ">=0.25.3" },
|
||||||
|
{ name = "pytest-cov", specifier = ">=6.0.0" },
|
||||||
|
{ name = "rich", specifier = ">=13.9.4" },
|
||||||
|
{ name = "ruff", specifier = ">=0.9.9" },
|
||||||
|
{ name = "sphinx", specifier = ">=8.2.1" },
|
||||||
|
{ name = "sphinx-rtd-theme", specifier = ">=3.0.2" },
|
||||||
|
{ name = "sphinx-toolbox", specifier = ">=3.9.0" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygments"
|
name = "pygments"
|
||||||
version = "2.19.1"
|
version = "2.19.1"
|
||||||
|
@ -866,53 +898,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/31/d8/de873d1c1b020d668d8ec9855d390764cb90cf8f6486c0983da52be8b7b7/ruff-0.9.9-py3-none-win_arm64.whl", hash = "sha256:3ac78f127517209fe6d96ab00f3ba97cafe38718b23b1db3e96d8b2d39e37ddf", size = 10435860 },
|
{ url = "https://files.pythonhosted.org/packages/31/d8/de873d1c1b020d668d8ec9855d390764cb90cf8f6486c0983da52be8b7b7/ruff-0.9.9-py3-none-win_arm64.whl", hash = "sha256:3ac78f127517209fe6d96ab00f3ba97cafe38718b23b1db3e96d8b2d39e37ddf", size = 10435860 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scryfall-py"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = { editable = "." }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "httpx" },
|
|
||||||
{ name = "pydantic" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dev-dependencies]
|
|
||||||
dev = [
|
|
||||||
{ name = "black" },
|
|
||||||
{ name = "enum-tools" },
|
|
||||||
{ name = "ipython" },
|
|
||||||
{ name = "pre-commit" },
|
|
||||||
{ name = "pytest" },
|
|
||||||
{ name = "pytest-asyncio" },
|
|
||||||
{ name = "pytest-cov" },
|
|
||||||
{ name = "rich" },
|
|
||||||
{ name = "ruff" },
|
|
||||||
{ name = "sphinx" },
|
|
||||||
{ name = "sphinx-rtd-theme" },
|
|
||||||
{ name = "sphinx-toolbox" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata]
|
|
||||||
requires-dist = [
|
|
||||||
{ name = "httpx", specifier = ">=0.28.1" },
|
|
||||||
{ name = "pydantic", specifier = ">=2.10.6" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
|
||||||
dev = [
|
|
||||||
{ name = "black", specifier = ">=25.1.0" },
|
|
||||||
{ name = "enum-tools", specifier = ">=0.12.0" },
|
|
||||||
{ name = "ipython", specifier = ">=9.0.0" },
|
|
||||||
{ name = "pre-commit", specifier = ">=4.0.1" },
|
|
||||||
{ name = "pytest", specifier = ">=8.3.3" },
|
|
||||||
{ name = "pytest-asyncio", specifier = ">=0.25.3" },
|
|
||||||
{ name = "pytest-cov", specifier = ">=6.0.0" },
|
|
||||||
{ name = "rich", specifier = ">=13.9.4" },
|
|
||||||
{ name = "ruff", specifier = ">=0.9.9" },
|
|
||||||
{ name = "sphinx", specifier = ">=8.2.1" },
|
|
||||||
{ name = "sphinx-rtd-theme", specifier = ">=3.0.2" },
|
|
||||||
{ name = "sphinx-toolbox", specifier = ">=3.9.0" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "six"
|
name = "six"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
|
|
Loading…
Add table
Reference in a new issue