Skip to main content

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> and server.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

See more: Unofficial Yggdrasil server technical specification, provided by authlib-injector (only Chinese version)

Included the following things:

  • Error response
  • Endpoint /authenticate response and its parts
  • Endpoint /refresh response and its parts
  • authlib-injector-compatible Yggdrasil API metadata
  • authlib-injector-compatible Yggdrasil Server metadata
    • Included in the authlib-injector-compatible Yggdrasil API metadata: [Root Tag] > "meta" (JSON) or api_metadata.serverMetadata (parsed)
    • According to this authlib-injector Wiki 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.
  • Player texture property
    • As a part of Yggdrasil API endpoint /authenticate and /refresh.
    • Usually encoded in Base64. Users/developers should decode and load it manually.

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 obj as the given schema to the corresponding type.
    • schema must be a member of enum mcschemas.Schemas.
    • converter can be an instance of cattrs.BaseConverter or its subclasses.
      • Default is None. At this time, a mcschemas.DedicatedConverter instance will be automatically created for internal structuring.
  • mcschemas.loads(s, schema, /, *, converter=None, **json_loads_kwargs)
    • Deserialize the string s, then parse the deserialized result as the given schema to the corresponding type.
    • schema and converter is identical to mcschemas.parse().
    • **json_loads_kwargs will be passed to json.loads(), except the keyword s.
  • mcschemas.load(fp, schema, /, *, converter=None, **json_load_kwargs)
    • Identical to mcschemas.loads(), but instead of a string, deserialize the file-like object fp, then parse the deserialized result as the given schema to the corresponding type.
      • fp must be a .read()-supporting text file.
    • schema and converter is identical to mcschemas.parse().
    • **json_load_kwargs will be passed to json.load(), except the keyword fp.
  • mcschemas.loadVersionAttrsFromClientJar(file, /, *, converter=None, **json_load_kwargs)
    • A convenience function for loading, deserializing and parsing version.json from client.jar.
    • The schema is fixed to mcschemas.Schemas.VERSION_ATTRIBUTES.
    • converter is identical to mcschemas.parse().
    • **json_load_kwargs is identical to mcschemas.load().
  • 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.
        • converter must be an instance of cattrs.BaseConverter or its subclasses.
    • 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_INDEX
MOJANG_JAVA_RUNTIME_MANIFEST
Mojang Java Runtime index file and manifest files
mcschemas.models.yggdrasil TEXTURE_PROPERTY
ERROR_RESPONSE
ENDPOINT_AUTHENTICATE_RESPONSE
ENDPOINT_REFRESH_RESPONSE
YGGDRASIL_API_METADATA
REFERENCE_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.

[Unreleased] - TBD

[0.4.1.post1] - 2026-02-21

Removed

  • Parsing: mcschemas.parser.createConverter() has been removed; it had previously been declared deprecated.
    • This function was removed at the code level in the previous release, but this was not mentioned in the previous release's changelog. Therefore, this release is specifically for correcting this oversight.

[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.
  • Schema: Added the method filterVersions() for mcschemas.models.versionmanifest.VersionManifest to help filtering version entries by version type/ID.

Changes

  • Project metadata: Overhauled and updated the README.
  • Schema: Registered mcschemas.models.versionmanifest.VersionManifest as a collections.abc.MutableSequence by implementing required abstract methods. In short, mcschemas.models.versionmanifest.VersionManifest now 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.
  • Schema: Registered mcschemas.models.assetindex.AssetIndex as a collections.abc.MutableMapping by implementing required abstract methods. In short, mcschemas.models.assetindex.AssetIndex now 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 the self, it is first converted into apathlib.Path instance before being passed to the internal asset objects mapping.

[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 (formally mcschemes), and this project is renamed to minecraft-schemas (formally minecraft-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.assetindex
      • mcschemes.clientmanifest -> mcschemas.models.clientmanifest
      • mcschemes.mojangjava -> mcschemas.models.mojangjava
      • mcschemes.versionattrs -> mcschemas.models.versionattrs
      • mcschemes.versionmanifest -> mcschemas.models.versionmanifest
      • mcschemes.enums -> mcschemas.models.enums
      • mcschemes.specials -> mcschemas.models.specials
    • Parser submodule mcschemes.tools.parser is moved to mcschemas.parser.

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 mcschemes and the old project name minecraft-schemes.
    • The obsolete parts are kept in a separate branch 0.3.0-announced-deprecation.

[0.3.0] - 2026-01-31

Added

  • Schema: Added support for parsing version information files (the version.json embedded within client.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().

Backwards-incompatible Changes

  • Schema: mcschemes.assetindex.AssetIndex now use the Path object from the standard library's pathlib module to represent file relative paths in asset index files.

    1. Previously, it will use str to 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
      
    2. Now, you need to use a pathlib.Path object 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.Converter to the kw-only argument converter_class is no longer determines the type of the returned dedicated converter instance.

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.parser now is a package.
      • Sub-package mcschemes.tools.parser.converters is added to contains dedicated converters.
  • Typing: typing-extensions was used instead of stdlib typing for better backward-compatibility for type annotation.
  • Schema: Several changes for SHA-1 hexdigest container:
    • The comparison between two mcsehemes.specials.Sha1Sum instances now is based on the case-insensitive form of the hexdigest attribute of both.
    • The exception class mcschemes.specials.ChecksumMismatch is now exposed.
  • Parsing: mcschemes.tools.parser.parse() now will check the second argument scheme in 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.in for setuptools.
  • Schema: Added an SHA-1 hexdigest container type for sha1/hash fields (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.RuleEntry instances) means allow or disallow some operation, such as append an argument or download a library file.

Changes

  • Project metadata: Declared build backend setuptools into pyproject.toml.
  • Project metadata: According to PEP 561, an empty py.typed is 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.py to 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

minecraft_schemas-0.4.1.post1.tar.gz (37.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

minecraft_schemas-0.4.1.post1-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file minecraft_schemas-0.4.1.post1.tar.gz.

File metadata

  • Download URL: minecraft_schemas-0.4.1.post1.tar.gz
  • Upload date:
  • Size: 37.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for minecraft_schemas-0.4.1.post1.tar.gz
Algorithm Hash digest
SHA256 18321c95f3316ac0230728f3b9f6e7a4f56f9a70d8f611c7aaf58a7e3f74458e
MD5 b1a489378bce80a67b5338fdec7cb95d
BLAKE2b-256 da6af4affef33fea8dd18af9cba8a0d6409bb8a59917af3f075ad1188ea8c719

See more details on using hashes here.

File details

Details for the file minecraft_schemas-0.4.1.post1-py3-none-any.whl.

File metadata

File hashes

Hashes for minecraft_schemas-0.4.1.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 5a5015503e13b9f12f7147a43a177009ccfbc6e056e75a70e49e172b1f8fe6e4
MD5 f5c36b8bb7385a79b6b2b248a8a7314a
BLAKE2b-256 061dc90f3e4007593208e97441317c01a189b3b0f38c3265878dfafd627e2034

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page