tf2schema-py 0.4.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.1
2
+ Name: tf2schema-py
3
+ Version: 0.4.4
4
+ Summary: A Python package to interact with the Team Fortress 2 Schema
5
+ Home-page: https://github.com/Osc44r/tf2schema/
6
+ Author: Osc44r
7
+ Keywords: Team Fortress 2,TF2,Steam,Schema,API
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: httpx
13
+ Requires-Dist: python-dotenv
14
+ Requires-Dist: pytest
15
+ Requires-Dist: pytest-asyncio
16
+ Requires-Dist: fake-useragent
17
+ Requires-Dist: vdf
18
+
19
+ # tf2schema
20
+
21
+ tf2schema is a Python package for interacting with the Team Fortress 2 (TF2) Schema. It provides an easy-to-use
22
+ `SchemaManager` class that allows fetching, updating, and managing the TF2 Schema from Steam's API or from a local file.
23
+ The package includes features such as automatic updates, file-based schema storage, and async support for better
24
+ performance.
25
+
26
+ The library builds on the work from [python-tf2-utilities](https://github.com/dixon2004/python-tf2-utilities) but
27
+ extends it with additional features, including async fetch operations and more Pythonic naming conventions.
28
+
29
+ ## Features
30
+
31
+ - Fetch the TF2 schema asynchronously from Steam's API or a local file.
32
+ - Automatic schema updates (optional).
33
+ - Pythonic snake_case naming for schema functions.
34
+ - Integration with file-based schema management for environments where file-only mode is preferred.
35
+ - Uses `httpx` for async HTTP requests.
36
+
37
+ ## Installation
38
+
39
+ ...coming soon...
40
+
41
+ Make sure your environment has the following dependencies installed:
42
+
43
+ - `httpx`
44
+ - `python-dotenv`
45
+ - `pytest`
46
+ - `pytest-asyncio`
47
+
48
+ ## Usage
49
+
50
+ Head to the [Examples](examples) directory for a quick start guide on how to use the `SchemaManager` & `Schema` classes.
51
+
52
+ ### Basic Example
53
+
54
+ By default, when using the `async with` syntax, the `SchemaManager` will start the auto-update loop. If you prefer not
55
+ to have auto-update enabled, you should manually call `fetch_schema` or `get` to fetch the schema.
56
+
57
+ Here’s a basic example of how to use the `SchemaManager`:
58
+
59
+ ```python
60
+ import asyncio
61
+ from tf2schema import SchemaManager
62
+ from pathlib import Path
63
+
64
+
65
+ async def main():
66
+ steam_api_key = "YOUR_STEAM_API_KEY"
67
+
68
+ async with SchemaManager(
69
+ steam_api_key=steam_api_key,
70
+ file_path=Path(__file__).parent / "schema.json",
71
+ save_to_file=True
72
+ ) as manager:
73
+ # Wait until the schema is fetched
74
+ await manager.wait_for_schema()
75
+
76
+ # Get the name of an item from the schema using its SKU
77
+ sku = "30911;5;u144"
78
+ item_name = manager.schema.get_name_from_sku(sku)
79
+ print(f"Item name for SKU {sku}: {item_name}")
80
+ # Expected output: "Item name for SKU 30911;5;u144: Snowblinded Fat Man's Field Cap"
81
+
82
+
83
+ if __name__ == "__main__":
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ### Disabling Auto-Update
88
+
89
+ If you do **not** want auto-update to be enabled, you should avoid using `async with` to create the `SchemaManager`.
90
+ Instead, create an instance and manually fetch the schema.
91
+
92
+ ```python
93
+ import asyncio
94
+ from tf2schema import SchemaManager
95
+ from pathlib import Path
96
+
97
+
98
+ async def main():
99
+ steam_api_key = "YOUR_STEAM_API_KEY"
100
+
101
+ # Create the SchemaManager instance
102
+ manager = SchemaManager(
103
+ steam_api_key=steam_api_key,
104
+ file_path=Path(__file__).parent / "schema.json",
105
+ save_to_file=True
106
+ )
107
+
108
+ # Manually fetch the schema from Steam's API or file if it exists
109
+ await manager.get()
110
+
111
+ # Example: Get the name of an item from the schema using its SKU
112
+ sku = "160;3;u4"
113
+ item_name = manager.schema.get_name_from_sku(sku)
114
+ print(f"Item name for SKU {sku}: {item_name}")
115
+ # Expected output: "Item name for SKU 160;3;u4: Vintage Community Sparkle Lugermorph"
116
+
117
+
118
+ if __name__ == "__main__":
119
+ asyncio.run(main())
120
+ ```
121
+
122
+ ### Auto-Updating Schema
123
+
124
+ The `SchemaManager` supports an auto-update feature that checks for schema updates at regular intervals. If you want to
125
+ enable the auto-update loop explicitly, you can do so with the `run` method:
126
+
127
+ ```python
128
+ import asyncio
129
+ from tf2schema import SchemaManager
130
+ from pathlib import Path
131
+
132
+
133
+ async def main():
134
+ steam_api_key = "YOUR_STEAM_API_KEY"
135
+
136
+ async with SchemaManager(
137
+ steam_api_key=steam_api_key,
138
+ file_path=Path(__file__).parent / "schema.json",
139
+ save_to_file=True,
140
+ update_interval=timedelta(hours=12) # Update every 12 hours
141
+ ) as manager:
142
+ # The manager will automatically update the schema in the background
143
+ await manager.wait_for_schema()
144
+
145
+ # Example: Get the name for another item from the schema using its SKU
146
+ sku = "817;5;u13"
147
+ item_name = manager.schema.get_name_from_sku(sku)
148
+ print(f"Item name for SKU {sku}: {item_name}")
149
+ # Expected output: "Item name for SKU 817;5;u13: Burning Flames Human Cannonball"
150
+
151
+
152
+ if __name__ == "__main__":
153
+ asyncio.run(main())
154
+ ```
155
+
156
+ ### File-Only Mode
157
+
158
+ If you want to use the package in environments where the schema should only be fetched from a file (e.g., in Docker
159
+ containers), you can enable `file_only_mode`:
160
+
161
+ ```python
162
+ import asyncio
163
+ from tf2schema import SchemaManager
164
+ from pathlib import Path
165
+
166
+
167
+ async def main():
168
+ async with SchemaManager(
169
+ file_path=Path(__file__).parent / "schema.json",
170
+ file_only_mode=True
171
+ ) as manager:
172
+ try:
173
+ await manager.wait_for_schema()
174
+ except FileNotFoundError:
175
+ print("Schema file not found. Please make sure it exists.")
176
+ return
177
+
178
+ # Example: Get the name of an item from the schema using its SKU
179
+ sku = "996;6"
180
+ item_name = manager.schema.get_name_from_sku(sku)
181
+ print(f"Item name for SKU {sku}: {item_name}")
182
+ # Expected output: "Item name for SKU 996;6: The Loose Cannon"
183
+
184
+
185
+ if __name__ == "__main__":
186
+ asyncio.run(main())
187
+ ```
188
+
189
+ ## Running Tests
190
+
191
+ To run the tests, you need to set the `STEAM_API_KEY` as an environment variable:
192
+
193
+ 1. Create a `.env` file with your Steam API key:
194
+
195
+ ```
196
+ STEAM_API_KEY=your_steam_api_key_here
197
+ ```
198
+
199
+ 2. Run the tests using `pytest`:
200
+
201
+ ```bash
202
+ pytest
203
+ ```
204
+
205
+ The tests include checks for schema fetching, conversion from SKU to name, and vice versa.
206
+
207
+ ## Contributing
208
+
209
+ If you'd like to contribute to this package, feel free to submit a pull request or open an issue. Contributions are
210
+ always welcome!
211
+
212
+ ## License
213
+
214
+ This project is licensed under the MIT License.
@@ -0,0 +1,196 @@
1
+ # tf2schema
2
+
3
+ tf2schema is a Python package for interacting with the Team Fortress 2 (TF2) Schema. It provides an easy-to-use
4
+ `SchemaManager` class that allows fetching, updating, and managing the TF2 Schema from Steam's API or from a local file.
5
+ The package includes features such as automatic updates, file-based schema storage, and async support for better
6
+ performance.
7
+
8
+ The library builds on the work from [python-tf2-utilities](https://github.com/dixon2004/python-tf2-utilities) but
9
+ extends it with additional features, including async fetch operations and more Pythonic naming conventions.
10
+
11
+ ## Features
12
+
13
+ - Fetch the TF2 schema asynchronously from Steam's API or a local file.
14
+ - Automatic schema updates (optional).
15
+ - Pythonic snake_case naming for schema functions.
16
+ - Integration with file-based schema management for environments where file-only mode is preferred.
17
+ - Uses `httpx` for async HTTP requests.
18
+
19
+ ## Installation
20
+
21
+ ...coming soon...
22
+
23
+ Make sure your environment has the following dependencies installed:
24
+
25
+ - `httpx`
26
+ - `python-dotenv`
27
+ - `pytest`
28
+ - `pytest-asyncio`
29
+
30
+ ## Usage
31
+
32
+ Head to the [Examples](examples) directory for a quick start guide on how to use the `SchemaManager` & `Schema` classes.
33
+
34
+ ### Basic Example
35
+
36
+ By default, when using the `async with` syntax, the `SchemaManager` will start the auto-update loop. If you prefer not
37
+ to have auto-update enabled, you should manually call `fetch_schema` or `get` to fetch the schema.
38
+
39
+ Here’s a basic example of how to use the `SchemaManager`:
40
+
41
+ ```python
42
+ import asyncio
43
+ from tf2schema import SchemaManager
44
+ from pathlib import Path
45
+
46
+
47
+ async def main():
48
+ steam_api_key = "YOUR_STEAM_API_KEY"
49
+
50
+ async with SchemaManager(
51
+ steam_api_key=steam_api_key,
52
+ file_path=Path(__file__).parent / "schema.json",
53
+ save_to_file=True
54
+ ) as manager:
55
+ # Wait until the schema is fetched
56
+ await manager.wait_for_schema()
57
+
58
+ # Get the name of an item from the schema using its SKU
59
+ sku = "30911;5;u144"
60
+ item_name = manager.schema.get_name_from_sku(sku)
61
+ print(f"Item name for SKU {sku}: {item_name}")
62
+ # Expected output: "Item name for SKU 30911;5;u144: Snowblinded Fat Man's Field Cap"
63
+
64
+
65
+ if __name__ == "__main__":
66
+ asyncio.run(main())
67
+ ```
68
+
69
+ ### Disabling Auto-Update
70
+
71
+ If you do **not** want auto-update to be enabled, you should avoid using `async with` to create the `SchemaManager`.
72
+ Instead, create an instance and manually fetch the schema.
73
+
74
+ ```python
75
+ import asyncio
76
+ from tf2schema import SchemaManager
77
+ from pathlib import Path
78
+
79
+
80
+ async def main():
81
+ steam_api_key = "YOUR_STEAM_API_KEY"
82
+
83
+ # Create the SchemaManager instance
84
+ manager = SchemaManager(
85
+ steam_api_key=steam_api_key,
86
+ file_path=Path(__file__).parent / "schema.json",
87
+ save_to_file=True
88
+ )
89
+
90
+ # Manually fetch the schema from Steam's API or file if it exists
91
+ await manager.get()
92
+
93
+ # Example: Get the name of an item from the schema using its SKU
94
+ sku = "160;3;u4"
95
+ item_name = manager.schema.get_name_from_sku(sku)
96
+ print(f"Item name for SKU {sku}: {item_name}")
97
+ # Expected output: "Item name for SKU 160;3;u4: Vintage Community Sparkle Lugermorph"
98
+
99
+
100
+ if __name__ == "__main__":
101
+ asyncio.run(main())
102
+ ```
103
+
104
+ ### Auto-Updating Schema
105
+
106
+ The `SchemaManager` supports an auto-update feature that checks for schema updates at regular intervals. If you want to
107
+ enable the auto-update loop explicitly, you can do so with the `run` method:
108
+
109
+ ```python
110
+ import asyncio
111
+ from tf2schema import SchemaManager
112
+ from pathlib import Path
113
+
114
+
115
+ async def main():
116
+ steam_api_key = "YOUR_STEAM_API_KEY"
117
+
118
+ async with SchemaManager(
119
+ steam_api_key=steam_api_key,
120
+ file_path=Path(__file__).parent / "schema.json",
121
+ save_to_file=True,
122
+ update_interval=timedelta(hours=12) # Update every 12 hours
123
+ ) as manager:
124
+ # The manager will automatically update the schema in the background
125
+ await manager.wait_for_schema()
126
+
127
+ # Example: Get the name for another item from the schema using its SKU
128
+ sku = "817;5;u13"
129
+ item_name = manager.schema.get_name_from_sku(sku)
130
+ print(f"Item name for SKU {sku}: {item_name}")
131
+ # Expected output: "Item name for SKU 817;5;u13: Burning Flames Human Cannonball"
132
+
133
+
134
+ if __name__ == "__main__":
135
+ asyncio.run(main())
136
+ ```
137
+
138
+ ### File-Only Mode
139
+
140
+ If you want to use the package in environments where the schema should only be fetched from a file (e.g., in Docker
141
+ containers), you can enable `file_only_mode`:
142
+
143
+ ```python
144
+ import asyncio
145
+ from tf2schema import SchemaManager
146
+ from pathlib import Path
147
+
148
+
149
+ async def main():
150
+ async with SchemaManager(
151
+ file_path=Path(__file__).parent / "schema.json",
152
+ file_only_mode=True
153
+ ) as manager:
154
+ try:
155
+ await manager.wait_for_schema()
156
+ except FileNotFoundError:
157
+ print("Schema file not found. Please make sure it exists.")
158
+ return
159
+
160
+ # Example: Get the name of an item from the schema using its SKU
161
+ sku = "996;6"
162
+ item_name = manager.schema.get_name_from_sku(sku)
163
+ print(f"Item name for SKU {sku}: {item_name}")
164
+ # Expected output: "Item name for SKU 996;6: The Loose Cannon"
165
+
166
+
167
+ if __name__ == "__main__":
168
+ asyncio.run(main())
169
+ ```
170
+
171
+ ## Running Tests
172
+
173
+ To run the tests, you need to set the `STEAM_API_KEY` as an environment variable:
174
+
175
+ 1. Create a `.env` file with your Steam API key:
176
+
177
+ ```
178
+ STEAM_API_KEY=your_steam_api_key_here
179
+ ```
180
+
181
+ 2. Run the tests using `pytest`:
182
+
183
+ ```bash
184
+ pytest
185
+ ```
186
+
187
+ The tests include checks for schema fetching, conversion from SKU to name, and vice versa.
188
+
189
+ ## Contributing
190
+
191
+ If you'd like to contribute to this package, feel free to submit a pull request or open an issue. Contributions are
192
+ always welcome!
193
+
194
+ ## License
195
+
196
+ This project is licensed under the MIT License.
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ import pathlib
2
+
3
+ from setuptools import setup, find_packages
4
+
5
+ path = pathlib.Path(__file__).parent
6
+
7
+ README = (path / "README.md").read_text()
8
+
9
+ setup(
10
+ name="tf2schema-py",
11
+ version="0.4.4",
12
+ description="A Python package to interact with the Team Fortress 2 Schema",
13
+ long_description=README,
14
+ long_description_content_type="text/markdown",
15
+ author="Osc44r",
16
+ url="https://github.com/Osc44r/tf2schema/",
17
+ packages=find_packages(),
18
+ classifiers=[
19
+ "Programming Language :: Python :: 3",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ ],
23
+ keywords=[
24
+ "Team Fortress 2",
25
+ "TF2",
26
+ "Steam",
27
+ "Schema",
28
+ "API",
29
+ ],
30
+ install_requires=[
31
+ "httpx",
32
+ "python-dotenv",
33
+ "pytest",
34
+ "pytest-asyncio",
35
+ "fake-useragent",
36
+ "vdf"
37
+ ]
38
+ )
File without changes
@@ -0,0 +1,59 @@
1
+ import asyncio
2
+ import os
3
+
4
+ import pytest
5
+ import pytest_asyncio
6
+ from dotenv import load_dotenv
7
+
8
+ from tf2schema import SchemaManager
9
+
10
+
11
+ @pytest.fixture(scope="session")
12
+ def session():
13
+ """Load environment variables for the session."""
14
+ load_dotenv()
15
+ yield
16
+
17
+
18
+ @pytest.fixture(scope="session")
19
+ def steam_api_key(session):
20
+ """Get the Steam API key from the environment."""
21
+ key = os.getenv("STEAM_API_KEY")
22
+ if not key:
23
+ raise ValueError("STEAM_API_KEY is not set in the environment.")
24
+
25
+ return key
26
+
27
+
28
+ @pytest.fixture(scope="session")
29
+ def event_loop():
30
+ """Create an asyncio event loop for the session."""
31
+ # Create a new event loop for the session
32
+ loop = asyncio.new_event_loop()
33
+ asyncio.set_event_loop(loop)
34
+
35
+ yield loop
36
+
37
+ loop.close()
38
+
39
+
40
+ @pytest_asyncio.fixture(scope="session")
41
+ async def schema_manager(steam_api_key, tmp_path_factory):
42
+ """Fixture to create and initialize the SchemaManager for testing."""
43
+ temp_dir = tmp_path_factory.mktemp("test_schema")
44
+ file_path = temp_dir / "schema.json"
45
+
46
+ # Initialize SchemaManager and use it as an async context manager
47
+ async with SchemaManager(
48
+ steam_api_key=steam_api_key,
49
+ file_path=file_path,
50
+ save_to_file=True,
51
+ ) as manager:
52
+ await manager.wait_for_schema(timeout=90)
53
+ yield manager
54
+
55
+
56
+ @pytest.fixture(scope="session")
57
+ def schema(schema_manager):
58
+ """Fixture to provide the fetched schema for the session."""
59
+ return schema_manager.schema
@@ -0,0 +1,47 @@
1
+ from tf2schema import Schema
2
+
3
+ DATA_SKUS_NAMES = {
4
+ "30911;5;u144": "Snowblinded Fat Man's Field Cap",
5
+ "30881;11": "Strange Croaking Hazard",
6
+ "9258;5;uncraftable;td-31154": "Non-Craftable Unusual Taunt: Time Out Therapy Unusualifier",
7
+ "341;5;u39": "Cauldron Bubbles A Rather Festive Tree",
8
+ "30114;5;u87": "Frostbite Valley Forge",
9
+ "199;15;w3;pk120": "Iron Wood Mk.II Shotgun (Field-Tested)",
10
+ "30609;5;u3108": "Festivized Formation Taunt: The Killer Solo",
11
+ "463;5;u3015": "Infernal Flames Taunt: The Schadenfreude",
12
+ "382;5;u35": "Smoking Big Country",
13
+ "996;6": "The Loose Cannon",
14
+ "817;5;u13": "Burning Flames Human Cannonball",
15
+ "30755;5;u263": "Forever And Forever! Berlin Brain Bowl",
16
+ "31374;6": "Hazard Handler",
17
+ "31374;3": "Vintage Hazard Handler",
18
+ "160;3;u4": "Vintage Community Sparkle Lugermorph",
19
+ "61;6;strange": "Strange Unique Ambassador",
20
+ "5778;9": "Self-Made Duck Token",
21
+ "267;5": "Unusual Haunted Metal Scrap",
22
+ "5009;3": "Vintage Class Token - Pyro",
23
+ "5020;6": "Name Tag"
24
+ }
25
+
26
+
27
+ def test_schema_creation(schema: Schema):
28
+ assert isinstance(schema, Schema), "Schema is not an instance of Schema."
29
+ assert schema.fetch_time, "Schema fetch time is not set."
30
+ assert schema.raw, "Schema raw data is not set."
31
+ assert schema.crate_series_list, "Schema crate series list is not set."
32
+ assert schema.munition_crates_list, "Schema munition crates list is not set."
33
+ assert schema.weapon_skins_list, "Schema weapon skins list is not set."
34
+ assert schema.qualities, "Schema qualities list is not set."
35
+ assert schema.effects, "Schema effects list is not set."
36
+ assert schema.paint_kits, "Schema paint kits list is not set."
37
+ assert schema.paints, "Schema paints list is not set."
38
+
39
+
40
+ def test_sku_to_name(schema: Schema):
41
+ for sku, name in DATA_SKUS_NAMES.items():
42
+ assert schema.get_name_from_sku(sku) == name, f"SKU {sku} does not match name {name}"
43
+
44
+
45
+ def test_name_to_sku(schema: Schema):
46
+ for sku, name in DATA_SKUS_NAMES.items():
47
+ assert schema.get_sku_from_name(name) == sku, f"Name {name} does not match SKU {sku}"
@@ -0,0 +1,29 @@
1
+ import pytest
2
+
3
+ from tests.conftest import schema_manager
4
+ from tf2schema import SchemaManager, Schema
5
+
6
+
7
+ @pytest.mark.asyncio
8
+ async def test_schema_fetching(schema_manager: SchemaManager):
9
+ assert schema_manager.has_schema, "Schema was not fetched."
10
+
11
+ schema = schema_manager.schema
12
+
13
+ assert isinstance(schema, Schema), "Schema is not an instance of Schema."
14
+ assert schema.fetch_time, "Schema fetch time is not set."
15
+ assert schema.raw, "Schema raw data is not set."
16
+
17
+
18
+ @pytest.mark.asyncio
19
+ async def test_get_schema_from_file(schema_manager):
20
+ new_manager = SchemaManager(
21
+ file_path=schema_manager.file_path,
22
+ file_only_mode=True
23
+ )
24
+
25
+ schema = new_manager.get_schema_from_file()
26
+
27
+ assert isinstance(schema, Schema), "Schema is not an instance of Schema."
28
+ assert schema.fetch_time, "Schema fetch time is not set."
29
+ assert schema.raw, "Schema raw data is not set."
@@ -0,0 +1,8 @@
1
+ from . import sku
2
+ from .schema import Schema, SchemaManager
3
+
4
+ __all__ = [
5
+ "Schema",
6
+ "SchemaManager",
7
+ "sku"
8
+ ]
@@ -0,0 +1,2 @@
1
+ from .manager import SchemaManager
2
+ from .schema import Schema