Skip to main content

tf2schema

tf2schema is a Python package for interacting with the Team Fortress 2 (TF2) Schema. It provides an easy-to-use SchemaManager class that allows fetching, updating, and managing the TF2 Schema from Steam's API or from a local file. The package includes features such as automatic updates, file-based schema storage, and async support for better performance.

The library builds on the work from python-tf2-utilities but extends it with additional features, including async fetch operations and more Pythonic naming conventions.

Features

  • Fetch the TF2 schema asynchronously from Steam's API or a local file.
  • Automatic schema updates (optional).
  • Pythonic snake_case naming for schema functions.
  • Integration with file-based schema management for environments where file-only mode is preferred.
  • Uses httpx for async HTTP requests.

CrateTF ownership and consumers

tf2schema owns low-level TF2 schema fetching, file-backed schema loading, SKU helpers, and schema lookup helpers. It does not own CrateTF catalog, inventory, pricing, recommendations, classifieds, or trade policy.

Current CrateTF consumers include:

  • schema-service, which fetches and writes the shared schema file.
  • catalog-service, inventory-service, trade-api-service, trade-orchestrator-service, recommendations-service, and backpacktf-classifieds-service, which read schema data directly or through CrateTfLib schema helpers.
  • CrateTfLib, which wraps local schema cache, schema lookup, lootlist, collection, and catalog metadata helpers.

Compatibility rules:

  • Preserve SKU parsing and rendering compatibility unless every catalog/inventory/trade consumer is migrated together.
  • File-backed schema behavior matters in Docker because many services read a shared schema volume rather than fetching from Steam themselves.
  • Do not move CrateTF service policy into this library; keep it as TF2 schema/domain utilities.
  • Schema fetching can touch Steam and GitHub endpoints. Production service retries, leader election, and event publication belong in schema-service.
  • GitHub VDF inputs may contain trailing non-VDF bytes from upstream tracking files; the library normalizes trailing NUL/control junk before parsing while still fetching the latest upstream content.

Public API

Stable imports:

from tf2schema import Schema, SchemaManager, sku
from tf2schema.sku import from_string, from_object, from_api

Public behavior:

  • SchemaManager fetches schema data from Steam/GitHub or loads it from a local file.
  • Schema resolves item names, SKUs, qualities, effects, crate series, paint kits, and related TF2 schema metadata.
  • tf2schema.sku converts between TF2 SKU strings, item objects, and Steam API item representations.

These helpers are shared contract code. Changes to SKU rendering, file-backed loading, or schema lookup behavior must be treated as cross-service changes for catalog, inventory, trade, schema, recommendations, and classifieds consumers.

Installation

You can install the package using pip:

pip install tf2schema-py

Make sure your environment has the following dependencies installed:

  • httpx
  • python-dotenv
  • pytest
  • pytest-asyncio

Usage

Head to the Examples directory for a quick start guide on how to use the SchemaManager & Schema classes.

Basic Example

By default, when using the async with syntax, the SchemaManager will start the auto-update loop. If you prefer not to have auto-update enabled, you should manually call fetch_schema or get to fetch the schema.

Here’s a basic example of how to use the SchemaManager:

import asyncio
from tf2schema import SchemaManager
from pathlib import Path


async def main():
    steam_api_key = "YOUR_STEAM_API_KEY"

    async with SchemaManager(
            steam_api_key=steam_api_key,
            file_path=Path(__file__).parent / "schema.json",
            save_to_file=True
    ) as manager:
        # Wait until the schema is fetched
        await manager.wait_for_schema()

        # Get the name of an item from the schema using its SKU
        sku = "30911;5;u144"
        item_name = manager.schema.get_name_from_sku(sku)
        print(f"Item name for SKU {sku}: {item_name}")
        # Expected output: "Item name for SKU 30911;5;u144: Snowblinded Fat Man's Field Cap"


if __name__ == "__main__":
    asyncio.run(main())

Disabling Auto-Update

If you do not want auto-update to be enabled, you should avoid using async with to create the SchemaManager. Instead, create an instance and manually fetch the schema.

import asyncio
from tf2schema import SchemaManager
from pathlib import Path


async def main():
    steam_api_key = "YOUR_STEAM_API_KEY"

    # Create the SchemaManager instance
    manager = SchemaManager(
        steam_api_key=steam_api_key,
        file_path=Path(__file__).parent / "schema.json",
        save_to_file=True
    )

    # Manually fetch the schema from Steam's API or file if it exists
    await manager.get()

    # Example: Get the name of an item from the schema using its SKU
    sku = "160;3;u4"
    item_name = manager.schema.get_name_from_sku(sku)
    print(f"Item name for SKU {sku}: {item_name}")
    # Expected output: "Item name for SKU 160;3;u4: Vintage Community Sparkle Lugermorph"


if __name__ == "__main__":
    asyncio.run(main())

Auto-Updating Schema

The SchemaManager supports an auto-update feature that checks for schema updates at regular intervals. If you want to enable the auto-update loop explicitly, you can do so with the run method:

import asyncio
from tf2schema import SchemaManager
from pathlib import Path


async def main():
    steam_api_key = "YOUR_STEAM_API_KEY"

    async with SchemaManager(
            steam_api_key=steam_api_key,
            file_path=Path(__file__).parent / "schema.json",
            save_to_file=True,
            update_interval=timedelta(hours=12)  # Update every 12 hours
    ) as manager:
        # The manager will automatically update the schema in the background
        await manager.wait_for_schema()

        # Example: Get the name for another item from the schema using its SKU
        sku = "817;5;u13"
        item_name = manager.schema.get_name_from_sku(sku)
        print(f"Item name for SKU {sku}: {item_name}")
        # Expected output: "Item name for SKU 817;5;u13: Burning Flames Human Cannonball"


if __name__ == "__main__":
    asyncio.run(main())

File-Only Mode

If you want to use the package in environments where the schema should only be fetched from a file (e.g., in Docker containers), you can enable file_only_mode:

import asyncio
from tf2schema import SchemaManager
from pathlib import Path


async def main():
    async with SchemaManager(
            file_path=Path(__file__).parent / "schema.json",
            file_only_mode=True
    ) as manager:
        try:
            await manager.wait_for_schema()
        except FileNotFoundError:
            print("Schema file not found. Please make sure it exists.")
            return

        # Example: Get the name of an item from the schema using its SKU
        sku = "996;6"
        item_name = manager.schema.get_name_from_sku(sku)
        print(f"Item name for SKU {sku}: {item_name}")
        # Expected output: "Item name for SKU 996;6: The Loose Cannon"


if __name__ == "__main__":
    asyncio.run(main())

Running Tests

To run the tests, you need to set the STEAM_API_KEY as an environment variable:

  1. Create a .env file with your Steam API key:

    STEAM_API_KEY=your_steam_api_key_here
    
  2. Run the tests using pytest:

    uv run --with-requirements requirements.txt --with pytest pytest
    

The tests include checks for schema fetching, conversion from SKU to name, and vice versa.

For changes that affect SKU behavior, schema loading, or file-only mode, also run targeted tests in schema-service, catalog-service, inventory-service, and trade consumers as appropriate.

Release rules

  • Documentation-only changes do not require a version bump.
  • Code releases use setup.py version.
  • CrateTfLib pins tf2schema-py, so release tf2schema before updating CrateTfLib and dependent service images.
  • Do not document real Steam API keys.

Contributing

If you'd like to contribute to this package, feel free to submit a pull request or open an issue. Contributions are always welcome!

License

This project is licensed under the MIT License.

Schema compatibility in 0.4.9

The 1 October 2026 TF2 schema introduced two sound strings directly inside items_game.items. Schema construction removes only those misplaced mouse_pressed_sound and drop_sound strings from its private copy before building indexes and serializing the cache. Actual item definitions, nested sound properties, and the caller's input are preserved. This keeps newly written schema files readable by older consumers; unrelated malformed item entries are not silently discarded.

The quality-prefix parser also recognizes Haunted Hoard Case and Haunted Hoard Key as item names, rather than interpreting Haunted as quality 13. Their SKUs are 5981;6;c153 and 5982;6. The existing canonical case-name format is Haunted Hoard Case #153.

Consumers that resolve these names must install 0.4.9. Loading a compatible cache alone does not upgrade their name parser. No public method signatures or existing valid SKU formats change.

Offline regression tests: pytest tests/test_schema_upstream_compatibility.py. The existing full suite also fetches Steam data and requires STEAM_API_KEY.

Metadata

Release files for tf2schema-py 0.4.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tf2schema-py 0.4.9
File Size Uploaded
tf2schema_py-0.4.9.tar.gz 27.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tf2schema-py 0.4.9
File Interpreter ABI Platform
tf2schema_py-0.4.9-py3-none-any.whl Python 3 none any Details

Total release size: 53.4 kB

Release files / tf2schema_py-0.4.9.tar.gz

Download URL tf2schema_py-0.4.9.tar.gz
Size 27.3 kB
Tags Source
SHA-256 checksum
How to use checksums
e90d6f735af0a5834b42c4502a21dba55e43afe809f9de8860639160b65fdeef
BLAKE2b-256 checksum
How to use checksums
7a82ab96cf9d0ae066f2923e283119b637e3065237d7367d20150d9bb36d80d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / tf2schema_py-0.4.9-py3-none-any.whl

Download URL tf2schema_py-0.4.9-py3-none-any.whl
Size 26.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b870fc78870cb329a880a0efd427ac76b12394fa5bdddc97fa6a5e56ff2577b4
BLAKE2b-256 checksum
How to use checksums
a3b17bf3f03bec6139b4e67e43fc6c704d9f8846f8689bea3ba1553ac604c5c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

0.4.9 This release

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page