SkillAgentSearch skills...

Mtgtools

collection of tools for easy handling of Magic: The Gathering data on your computer

Install / Use

/learn @EskoSalaka/Mtgtools

README

mtgtools

mtgtools is a collection of tools for easy handling of Magic: The Gathering data on your computer. The card data can be easily downloaded from Scryfall API or magicthegathering.io API and saved in a ZODB - database, a native object database for Python. Everything is simply in Python, so no knowledge of SQL or the likes is needed to work with the database.

Features

  • Easily download, update and save Magic: The Gathering card and set data from Scryfall and/or magicthegathering.io to a local ZODB database (native object database for Python). Updating the database from scratch usually takes about 2 minutes on my computer.

  • Easily iterate, filter, sort, group and handle card lists, sets and decks. The usual searching methods on the whole card database of 40k cards take about 0.15s on my computer.

  • Save your own card lists and decks in a database in pure Python.

  • Read and write card lists or decks from files.

  • Generate random samples, random cards, booster packs etc. from any lists of cards.

  • Download card images of the type of your choice from Scryfall.

  • Create proxy image sheets from lists of cards using Scryfall.

Requirements

  • Python 3.5 - mtgtools is tested on Python 3.5 but will probably also work on later versions

  • ZODB - Can be installed with pip install zodb. More info at http://www.zodb.org/en/latest/.

  • requests - Can be installed with pip install requests. More info at https://pypi.org/project/requests/.

  • PIL - Not necessary, but needed for creating proxy image sheets. Can be installed with pip install pillow

Scryfall vs magicthegathering.io

At the moment there exists two different kind of APIs for mtg data, Scryfall and magicthegathering.io. They are structured in different ways and both have pros and cons. For example, Scryfall cards contain attribute card_faces whereas the faces in mtgio are separate cards.

At the moment, Scryfall has a more extensive database with more useful data like prices and purchase uris and also hosts good quality card images, so in my opinion it is more useful of the two.

Installing

mtgtools can be simply installed with pip install mtgtools.

Usage guide

Persistent card, set and card list objects

Working with the database mostly revolves around working with the following persistent card and card list objects. Data persistence in this case basically means that ZODB will automatically detect when these objects are accessed and modified and saves the according changes automatically when transactions have been committed.

A good guide on ZODB can for example be found here: https://media.readthedocs.org/pdf/zodborg/latest/zodborg.pdf

PCard

PCard is a simple persistent dataclass representing Magic: the Gathering cards with their characteristic attributes. It is constructed simply with a json response dictionary from either magicthegathering.io or Scryfall API, so PCard has all the attributes matching the responses' keys and values.

Note that the attributes power, toughness and loyalty are saved as strings since they might contain characters like '*' or 'X'. For convenience, the card objects will also contain numerical versions of these attributes: power_num, toughness_num and loyalty_num. This makes searching much easier in many cases. After stripping away these non-digit characters, the remaining numbers will be in the numerical version of the attribute. If nothing is left after stripping, the numerical version will be 0.

Another difference between Scryfall and mtgio is that in mtgio API attribute names are in camelCase style. For consistency, the attributes in this software are transformed into snake_case which makes many of the attributes identical to the ones in Scryfall. For example, the attribute manaCost from mtgio has been changed to mana_cost, which is the same as in Scryfall.

For more information on what attributes cards have, read https://scryfall.com/docs/api/cards for Scryfall card objects and https://docs.magicthegathering.io/#api_v1cards_list for magicthegathering.io card objects.

PCardList

PCardList is a persistent card list or deck object that mainly acts just like a normal Python list for PCard objects. These lists can be saved in the database just like any other persistent objects, and a PCardList is used as a container for all the cards in the database.

PCardList has many useful methods for querying, filtering, sorting and grouping its contents and creating new card lists by combining other card lists in various ways. It also contains other handy methods like downloading the images of its cards from Scryfall, creating proxy image sheets from its cards, printing out its contents in a readable way and creating deck-like strings or files of its contents.

Except for the usual in-place list methods like extend, append and remove the PCardList is functional in style, meaning that calling any of the other filtering or querying methods return new PCardList objects leaving the original untouched.

PCardList can also be used as a deck by adding cards to its sideboard. Having cards in the sideboard changes some functionalities of the methods like deck_str. Images are downloaded and proxies created for both the cards and the sideboard. However, Having cards in the 'sideboard' does not change the behavior of the core internal methods like len, getitem or setitem, so basically the cards in the sideboard are a kind of an extra.

PSet

Pset is a simple Persistent dataclass representing Magic: The Gathering sets with their characteristic attributes. It is constructed simply with a json response dictionary from either magicthegathering.io or Scryfall API, so PSet has all the attributes matching the responses' keys and values.

For more information on what attributes sets have, read https://scryfall.com/docs/api/sets for Scryfall set objects and https://docs.magicthegathering.io/#api_v1sets_list for magicthegathering.io set objects.

Additionally, PSet inherits from PCardList and contains all the cards of the set. PSet can be queried just like PCardList.

PSetList

PSetList is a persistent set list object that mostly acts just like a normal Python list for Pset objects. These lists can be saved in the database just like any other persistent objects. PSetList contains handy methods for querying the sets it contains but in most cases it is only useful as a container database. It works very similarly to PCardList except that it holds sets rather than cards.

Working with the database

Opening/creating databases

An existing database can be opened simply with

>>> from mtgtools.MtgDB import MtgDB
>>> mtg_db = MtgDB('my_db.fs')

If no storage in the given path is found, a new empty database is automatically created.

Now that the connection to the database is open, the mtg_db will contain all the needed ZODB-related objects storage, connection, database and root (more about these in http://www.zodb.org/en/latest/reference/index.html). The cards and sets can now be found in the root of the database with

>>> scryfall_cards = mtg_db.root.scryfall_cards
>>> scryfall_sets = mtg_db.root.scryfall_sets

and

>>> mtgio_cards = mtg_db.root.mtgio_cards
>>> mtgio_sets = mtg_db.root.mtgio_sets

All the cards are saved as a PCardList and all the sets are saved as a PSetList. The root acts as a boot-strapping point and a top-level container for all the objects in the database.

>>> print(mtg_db.root)

<root: mtgio_cards mtgio_sets scryfall_cards scryfall_sets>

The above method for accessing the database objects is a convenience, and you can also access the root mapping with

>>> root_mapping = tool.connection.root()
>>> print([key for key in root_mapping.keys()])

['scryfall_sets', 'mtgio_cards', 'scryfall_cards', 'mtgio_sets']

>>> print('scryfall_cards' in root_mapping)

True

Updating

Building the database from scratch from Scryfall and mtgio is simply done with

my_db.scryfall_bulk_update()
my_db.mtgio_update()

The update downloads and saves all new card and set data and also updates any changes to the existing data. This is also useful when updating for example the price and legality attributes of the Scryfall cards which might often change.

Building the database from scratch takes about few minutes to complete and it is mostly affected by the API request limits which are 10 request per second for Scryfall and 5000 requests per hour for magicthegathering.io. About 10 requests per second are sent during updating which should comply with the Scryfall limits, and with magicthegathering.io you have to make sure not to run the update too many times per hour.

Working with card lists

Querying, filtering and sorting

PCardList has two handy methods for "querying" its contents which return new PCardList objects:<br/>

where(invert=False, search_all_faces=False, **kwargs)

and

where_exactly(invert=False, search_all_faces=False, **kwargs)

where, the looser method, returns a new PCardList for which ANY of the given keyword arguments match 'loosely' with the attributes of the cards in this list. The arguments should be any card attribute names such as 'power', 'toughness' and 'name'.

String attributes are case insensitive and it is enough that the argument is a substring of the attribute.

For list attributes the order does not matter and it is enough for one of the elements to match exactly.

For convenience, for numerical attributes it is enough that the argument is larger or equal to the attribute.

where_exactly, the stricter method, returns a new list of cards for which ALL the given keyword arguments match completely with the attributes of the cards in this list.

For both of these methods, the results can be inverted to return all the cards

Related Skills

View on GitHub
GitHub Stars74
CategoryData
Updated14d ago
Forks15

Languages

Python

Security Score

85/100

Audited on Mar 16, 2026

No findings