Parse Minecraft-relative JSON to structured objects
Project description
minecraft-schemas
A Python library for help you to parse Minecraft-relative JSON to structured objects.
Disclaimer: Although the project name contains "minecraft", this project is not supported by Mojang Studios or Microsoft.
Notice for users/developers migrated from minecraft-schemes
This project is renamed from minecraft-schemes, with a full package structure reorganization.
For more information about migration, see the version history file for more details. (Or scroll down to see the version history if you are reading this on PyPI.)
Due to limited time and energy, I am unable to provide a complete backward compatibility solution for this release. Sorry for the inconvenience.
Features
Already implemented
- Easy installing
- Open source
- All public APIs are static typed
- Supports parsing various file structures used by Mojang and Minecraft (see below)
- Easy-to-use file structure definitions, powered by
attrs - Rapidly file parsing, powered by
cattrs - Conditional testing for game/command line options and dependency libraries (in
client.json)
Not implemented yet (not a complete list)
- Parse/build supports for
launcher_profiles.json(used by official Minecraft Launcher) - Game/JVM command line options concatenating and completing
Supported file structures
version_manifest.json and version_manifest_v2.json
See more: Minecraft Wiki
- A JSON file that list Minecraft versions available in the official launcher.
client.json
See more: Minecraft Wiki
- A JSON file that accompanies client.jar in
.minecraft/versions/<version>and lists the version's attributes. - Usually named
<game version>.json. - Don't confuse this file with
version.json; they are fundamentally different.
Asset index file
See more: Minecraft Wiki (only Chinese version)
- A series of JSON files used to query the hash value of the corresponding hashed resource file based on the resource path, in order to invoke the file.
- Can be downloaded from the URL pointed in the
client.json:[Root Tag] > "assetIndex" > "url"
version.json
See more: Minecraft Wiki
- A JSON file that offers some basic information about the version's attributes.
- Embedded within client.jar in
.minecraft/versions/<version>andserver.jar. - Don't confuse this file with
client.json; they are fundamentally different.
Mojang Java Runtime index file and manifest files
- A JSON file that list manifest files of Java Runtime provided by Mojang via their "codename".
- Not documented by Minecraft Wiki or Mojang, but it is believed to be for the purposes described above.
Yggdrasil API Responses
Included the following things:
- Error response
- Endpoint
/authenticateresponse and its parts - Endpoint
/refreshresponse and its parts authlib-injector-compatible Yggdrasil API metadataauthlib-injector-compatible Yggdrasil Server metadata- Included in the
authlib-injector-compatible Yggdrasil API metadata:[Root Tag] > "meta"(JSON) orapi_metadata.serverMetadata(parsed) - According to this
authlib-injectorWiki section about the server metadata, this structure is not mandatory. Regardless of whether the parsing is successful or not, users/developers should access and manipulate it as a regular dict.
- Included in the
- Player texture property
- As a part of Yggdrasil API endpoint
/authenticateand/refresh. - Usually encoded in Base64. Users/developers should decode and load it manually.
- As a part of Yggdrasil API endpoint
Install
Install minecraft-schemas using pip:
pip install minecraft-schemas
The release page also provides various versions of wheel files for manual download and installation.
API Documentation
mcschemas's most useful functionalities are the following APIs:
mcschemas.Schemas- An enum class that declares currently supported schemas. All schemas have parsing support, but no one currently have build support.
mcschemas.parse(obj, schema, /, *, converter=None)- Parse
objas the givenschemato the corresponding type. schemamust be a member of enummcschemas.Schemas.convertercan be an instance ofcattrs.BaseConverteror its subclasses.- Default is
None. At this time, amcschemas.DedicatedConverterinstance will be automatically created for internal structuring.
- Default is
- Parse
mcschemas.loads(s, schema, /, *, converter=None, **json_loads_kwargs)- Deserialize the string
s, then parse the deserialized result as the givenschemato the corresponding type. schemaandconverteris identical tomcschemas.parse().**json_loads_kwargswill be passed tojson.loads(), except the keywords.
- Deserialize the string
mcschemas.load(fp, schema, /, *, converter=None, **json_load_kwargs)- Identical to
mcschemas.loads(), but instead of a string, deserialize the file-like objectfp, then parse the deserialized result as the givenschemato the corresponding type.fpmust be a.read()-supporting text file.
schemaandconverteris identical tomcschemas.parse().**json_load_kwargswill be passed tojson.load(), except the keywordfp.
- Identical to
mcschemas.loadVersionAttrsFromClientJar(file, /, *, converter=None, **json_load_kwargs)- A convenience function for loading, deserializing and parsing
version.jsonfromclient.jar. - The schema is fixed to
mcschemas.Schemas.VERSION_ATTRIBUTES. converteris identical tomcschemas.parse().**json_load_kwargsis identical tomcschemas.load().
- A convenience function for loading, deserializing and parsing
- class
mcschemas.DedicatedConverter(*, regex_flags=0, detailed_validation=True, forbid_extra_keys=False)- A converter for converting between structured and unstructured data according to the data structures defined in this package.
- classmethod
mcschemas.DedicatedConverter.configure(converter, /, *, regex_flags=0)- Configure an existing converter to convert some specific types.
convertermust be an instance ofcattrs.BaseConverteror its subclasses.
- Configure an existing converter to convert some specific types.
- Full documentation can be found in the code: src/mcschemas/parser/converters.py
And file structure model declarations:
| Sub Package | mcschemas.Schemas Enum Member Name |
Corresponding File Structure |
|---|---|---|
mcschemas.models.versionmanifest |
VERSION_MANIFEST |
version_manifest.json and version_manifest_v2.json |
mcschemas.models.clientmanifest |
CLIENT_MANIFEST |
client.json |
mcschemas.models.assetindex |
ASSET_INDEX |
Asset index file |
mcschemas.models.versionattrs |
VERSION_ATTRIBUTES |
version.json |
mcschemas.models.mojangjava |
MOJANG_JAVA_RUNTIME_INDEXMOJANG_JAVA_RUNTIME_MANIFEST |
Mojang Java Runtime index file and manifest files |
mcschemas.models.yggdrasil |
TEXTURE_PROPERTYERROR_RESPONSEENDPOINT_AUTHENTICATE_RESPONSEENDPOINT_REFRESH_RESPONSEYGGDRASIL_API_METADATAREFERENCE_SERVER_METADATA |
Yggdrasil API Responses |
Usage Example
Parse version_manifest.json
Download at here.
import mcschemas
from mcschemas.models.enums import VersionType
with open('version_manifest.json', mode='r') as f:
version_manifest = mcschemas.load(f, mcschemas.Schema.VERSION_MANIFEST)
print('Latest release:', version_manifest.latest.release)
print('Latest snapshot:', version_manifest.latest.snapshot)
print('Number of available versions:', len(version_manifest.versions))
print('Show information on the first 5 release versions:')
for idx, entity in enumerate(version_manifest.filterVersions(type=VersionType.RELEASE)):
if idx >= 5:
break
print(' The ID of the release version (at index {0}):'.format(version_manifest.index(entity)), entity.id)
print(' The release time of the release version (at index {0}):'.format(version_manifest.index(entity)), entity.releaseTime)
print(' The last update time of the release version (at index {0}):'.format(version_manifest.index(entity)), entity.time)
Parse client.json
This example code uses client.json from Minecraft Java Edition
1.21.11, download at here.
import mcschemas
with open('1.21.11.json', mode='r') as f:
client_manifest_1_21_11 = mcschemas.load(f, mcschemas.Schema.CLIENT_MANIFEST)
print('Version ID:', client_manifest_1_21_11.id)
# The following field is structured as a member of enum mcschemas.enums.VersionType
print('Version Type:', str(client_manifest_1_21_11.type))
print('Asset version ID:', client_manifest_1_21_11.assetIndex.id)
print('Main class:', client_manifest_1_21_11.mainClass)
print('Release time:', client_manifest_1_21_11.releaseTime)
print('Last update time:', client_manifest_1_21_11.time)
print('Number of dependency libraries:', len(client_manifest_1_21_11.libraries))
client_jar_file_info = client_manifest_1_21_11.downloads.get('client')
if client_jar_file_info:
print('URL to download the client JAR file:', client_jar_file_info.url)
Parse asset index file
This example code uses the asset index file version 29. You can download it at here.
from pathlib import Path
import mcschemas
with open('29.json', mode='r') as f:
asset_index = mcschemas.load(f, mcschemas.Schema.ASSET_INDEX)
print('Number of asset files:', len(asset_index.objects))
asset_file_relative_path = Path('icons/icon_256x256.png')
if asset_file_relative_path in asset_index.objects:
target_asset_file_info = asset_index.objects[asset_file_relative_path]
print('Information about asset file {0}: hash={1.hash}, size={1.size}'.format(asset_file_relative_path, target_asset_file_info))
Parse version.json from a client JAR file
This example code uses the client JAR file from Minecraft Java Edition 1.21.11. You can download it in official Minecraft Launcher or at here.
from pathlib import Path
import mcschemas
version_attrs = mcschemas.loadVersionAttrsFromClientJar(Path.home().joinpath('.minecraft/versions/1.21.11/1.21.11.jar'))
print('Unique identifier of this client JAR:', version_attrs.id)
print('User-friendly name of this client JAR:', version_attrs.name)
print('Data version of this client JAR:', version_attrs.world_version)
print('Protocol version of this client JAR:', version_attrs.protocol_version)
print('Build time of this client JAR:', version_attrs.build_time)
if version_attrs.series_id:
print('Series ID (branch name) of this client JAR:', version_attrs.series_id)
Load client.json, then filter and concatenate command line
This example code uses client.json from Minecraft Java Edition
1.21.11, download at here.
Note: this example only demonstrates basic conditional filtering and concatenation operations, and does not consider the replacement of placeholder parameters (which may be supported in future versions).
import mcschemas
from mcschemas.tools import rules
with open('1.21.11.json', mode='r') as f:
client_manifest_1_21_11 = mcschemas.load(f, mcschemas.Schema.CLIENT_MANIFEST)
features: dict[str, bool] = {
'is_demo_user' : True,
'has_custom_resolution': True
}
cmdline: list[str] = ['java']
for jvm_arg_entry in client_manifest_1_21_11.arguments.jvm:
if rules.isArgumentCanBeAppended(jvm_arg_entry, features=features):
cmdline.extend(jvm_arg_entry.value)
cmdline.append(client_manifest_1_21_11.mainClass)
for game_arg_entry in client_manifest_1_21_11.arguments.game:
if rules.isArgumentCanBeAppended(game_arg_entry, features=features):
cmdline.extend(game_arg_entry.value)
print('Concatenated command line (without placeholder replacements):', cmdline)
Fetch API metadata from an authlib-injector compatible Yggdrasil Service
This example code requires httpx. You can install it through pip.
The Yggdrasil service is provided by Drasl.
import sys
import cattrs
import httpx
import mcschemas
try:
resp = httpx.get('https://drasl.unmojang.org/authlib-injector').raise_for_status()
except httpx.HTTPError as exc:
print('Failed to fetch the Yggdrasil API metadata: {0}'.format(exc))
sys.exit(1)
# Parse the structure that already unserialized by `resp.json()`
api_metadata = mcschemas.parse(resp.json(), mcschemas.Schema.YGGDRASIL_API_METADATA)
# Or directly load from original response text
api_metadata = mcschemas.loads(resp.text, mcschemas.Schema.YGGDRASIL_API_METADATA)
# Parse the server metadata
# If failed to parse, we can still access/manipulate it as a regular dict
try:
server_metadata = mcschemas.parse(api_metadata.serverMetadata, mcschemas.Schema.REFERENCE_SERVER_METADATA)
except cattrs.ClassValidationError:
server_metadata = api_metadata.serverMetadata
print('Skin domain allowlist:')
for allowed_skin_domain in api_metadata.skinDomainAllowlist:
print(' -', allowed_skin_domain)
print('Player profile signature public key (in PEM format):')
print(api_metadata.signaturePublicKey)
print('Yggdrasil server name (if exists):', server_metadata.get('serverName', ''))
print(
'Yggdrasil server implementation name and version (if exists):',
server_metadata.get('implementationName'),
server_metadata.get('implementationVersion'),
)
print('Yggdrasil server supports non-email account name:', server_metadata.get('feature.non_email_login', False))
History
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.4.1] - 2026-02-21
Added
- Schema: Supported to parse the response format of Yggdrasil APIs compatible with authlib-injector.
- Corresponding model declarations at
mcschemas.models.yggdrasil.
- Corresponding model declarations at
- Schema: Added the method
filterVersions()formcschemas.models.versionmanifest.VersionManifestto help filtering version entries by version type/ID.
Changes
- Project metadata: Overhauled and updated the README.
- Schema: Registered
mcschemas.models.versionmanifest.VersionManifestas acollections.abc.MutableSequenceby implementing required abstract methods. In short,mcschemas.models.versionmanifest.VersionManifestnow is a mutable sequence.- Its
__getitem__method behaves a little differently from a regular sequence: when a string is passed in, it iterates through the internal list of version entries, searches for and returns the entry whose version ID exactly matches the string.
- Its
- Schema: Registered
mcschemas.models.assetindex.AssetIndexas acollections.abc.MutableMappingby implementing required abstract methods. In short,mcschemas.models.assetindex.AssetIndexnow is a mutable mapping.- Its
__getitem__,_setitem__and__delitem__method behaves a little differently from a regular mapping: when a string is passed as the first argument after theself, it is first converted into apathlib.Pathinstance before being passed to the internal asset objects mapping.
- Its
[0.4.0] - 2026-02-09
This release focuses on renaming package and reorganizing the package internal structure.
Due to limited time and energy, I am unable to design a complete backward compatibility solution for this release. Sorry for the inconvenience.
Backwards-incompatible Changes
- Organizational: The package is renamed to
mcschemas(formallymcschemes), and this project is renamed tominecraft-schemas(formallyminecraft-schemes).- Since the word "scheme" [Merriam-Webster] does not accurately reflect the content and objectives of this project, using "schema" [Merriam-Webster] is clearly more appropriate.
- Organizational: Package structure changed:
- All sub packages and modules including schema declarations are moved to
mcschemas.models, detailed below:mcschemes.assetindex->mcschemas.models.assetindexmcschemes.clientmanifest->mcschemas.models.clientmanifestmcschemes.mojangjava->mcschemas.models.mojangjavamcschemes.versionattrs->mcschemas.models.versionattrsmcschemes.versionmanifest->mcschemas.models.versionmanifestmcschemes.enums->mcschemas.models.enumsmcschemes.specials->mcschemas.models.specials
- Parser submodule
mcschemes.tools.parseris moved tomcschemas.parser.
- All sub packages and modules including schema declarations are moved to
Changes
- Project metadata: Fixed typos in this version history file and README:
scheme->schema.
[0.3.0.post1] - 2026-02-09
Deprecated:
- Announced the abandonment of the old package name
mcschemesand the old project nameminecraft-schemes.- The obsolete parts are kept in a separate branch
0.3.0-announced-deprecation.
- The obsolete parts are kept in a separate branch
[0.3.0] - 2026-01-31
Added
- Schema: Added support for parsing version information files (the
version.jsonembedded withinclient.jar). - Schema: Added parse support for index file of Mojang Java Runtimes, and file manifest of each java runtime.
- Parsing: Added a dedicated converter class in
mcschemes.tools.parser.Converter.DedicatedConverter.- This is intended to replace the
mcschemes.tools.parser.createConverter().
- This is intended to replace the
Backwards-incompatible Changes
-
Schema:
mcschemes.assetindex.AssetIndexnow use thePathobject from the standard library'spathlibmodule to represent file relative paths in asset index files.-
Previously, it will use
strto represent file relative paths, so you can access information (e.g. hash, size) by the following way:from mcschemes.models.assetindex import AssetIndex asset_index: AssetIndex = ... # Some operations to obtain the json and structure it to the AssetIndex instance file_info = asset_index.objects['icons/icon_128x128.png'] [...] # Do your operations for file_info
-
Now, you need to use a
pathlib.Pathobject as the key to access the corresponding information:from pathlib import Path from mcschemes.models.assetindex import AssetIndex asset_index: AssetIndex = ... # Some operations to obtain the json and structure it to the AssetIndex instance file_info = asset_index.objects[Path('icons/icon_128x128.png')] [...] # Do your operations for file_info
-
Deprecations
- Parsing:
mcschemes.tools.parser.createConverter()is now marked as deprecated and will be removed in future versions.- Now pass a converter class based on
cattrs.Converterto the kw-only argumentconverter_classis no longer determines the type of the returned dedicated converter instance.
- Now pass a converter class based on
Changes
- Project metadata: This version history file has been revised to conform to the format described in Keep a Changelog.
- Project metadata: Fully updated the README file:
- Added a summary of the main features and benefits.
- Added a summary of file structures supported by this library.
- Usage example are now more useful and better represent typical use cases.
- Organizational: Reorganized the project structure:
mcschemes.tools.parsernow is a package.- Sub-package
mcschemes.tools.parser.convertersis added to contains dedicated converters.
- Sub-package
- Typing:
typing-extensionswas used instead of stdlibtypingfor better backward-compatibility for type annotation. - Schema: Several changes for SHA-1 hexdigest container:
- The comparison between two
mcsehemes.specials.Sha1Suminstances now is based on the case-insensitive form of thehexdigestattribute of both. - The exception class
mcschemes.specials.ChecksumMismatchis now exposed.
- The comparison between two
- Parsing:
mcschemes.tools.parser.parse()now will check the second argumentschemein more robust way.
Fixed
- Tooling: Fixed a mistake when comparing the OS name in the function
mcschemes.tools.rules.isAllow().
[0.2.0] - 2025-12-11
Added
- Project metadata: Added
MANIFEST.infor setuptools. - Schema: Added an SHA-1 hexdigest container type for
sha1/hashfields (un-)structuring. Its definition can be found at:mcschemes.specials.Sha1Sum. - Tooling: Added some tool functions to calculate a set of rules (iterable of
mcschemes.clientmanifest.nodes.RuleEntryinstances) means allow or disallow some operation, such as append an argument or download a library file.
Changes
- Project metadata: Declared build backend
setuptoolsintopyproject.toml. - Project metadata: According to PEP 561, an empty
py.typedis added into the root directory of package. - Project metadata: Corrected the date format for all tier-2 titles in this version history file.
- Organizational: Moved
typings.pyto the root directory of package.
[0.1.0.post1] - 2025-12-05
Changes
- Project metadata: Added project urls into
pyproject.toml. - Project metadata: Added disclaimer in
README.md.
[0.1.0] - 2025-12-04
Added
The initial release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file minecraft_schemas-0.4.1.tar.gz.
File metadata
- Download URL: minecraft_schemas-0.4.1.tar.gz
- Upload date:
- Size: 37.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcb2696a29785e4e9110c6b53657c5018035aa81855b8a92168dacf0955b59b1
|
|
| MD5 |
742c8504b2471954567756a9f5b35b77
|
|
| BLAKE2b-256 |
488a76bf02b98aaa1c58e52c3c0e4267e003995a1ee0b1ee49c2e67368e40e93
|
File details
Details for the file minecraft_schemas-0.4.1-py3-none-any.whl.
File metadata
- Download URL: minecraft_schemas-0.4.1-py3-none-any.whl
- Upload date:
- Size: 33.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e30a99891b3d3195290e09dea49889f16fe11b78bf4d2d9e52da0b471a51fa02
|
|
| MD5 |
aae430bafdd4d9fa64c455e3ccef425d
|
|
| BLAKE2b-256 |
be74ff13ed2e85a662eba2d67a7e55a8940f154fd8dc76a9dc8d0ef09217b265
|