cristalix 0.1.0__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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 kkp_
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.4
2
+ Name: cristalix
3
+ Version: 0.1.0
4
+ Summary: Unofficial Python client for Cristalix OpenAPI
5
+ Author-email: kkp_ <kkplikeme@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://cristalix.gg
8
+ Project-URL: Source, https://example.com/your-repo-url
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: httpx>=0.27.0
21
+ Requires-Dist: pydantic>=2.5.0
22
+ Requires-Dist: typing-extensions>=4.0.0; python_version < "3.11"
23
+ Dynamic: license-file
24
+
25
+ Cristalix Python Client
26
+ =======================
27
+
28
+ Неофициальная python-библиотека для работы с Cristalix OpenAPI.
29
+
30
+ > ВНИМАНИЕ: библиотека не является официальным продуктом Cristalix.
31
+
32
+ ## Быстрый пример
33
+
34
+ ```python
35
+ from cristalix import CristalixClient
36
+
37
+ client = CristalixClient(
38
+ project_key="YOUR_PROJECT_KEY",
39
+ token="YOUR_TOKEN",
40
+ )
41
+
42
+ profile = client.get_profile_by_name("kkp_")
43
+ print(profile.username, profile.group.key)
44
+ ```
45
+
46
+ ## Async-пример
47
+
48
+ ```python
49
+ import asyncio
50
+ from cristalix import AsyncCristalixClient
51
+
52
+
53
+ async def main():
54
+ client = AsyncCristalixClient(
55
+ project_key="YOUR_PROJECT_KEY",
56
+ token="YOUR_TOKEN",
57
+ )
58
+ profile = await client.get_profile_by_name("kkp_")
59
+ print(profile.username, profile.group.key)
60
+
61
+
62
+ asyncio.run(main())
63
+ ```
64
+
@@ -0,0 +1,40 @@
1
+ Cristalix Python Client
2
+ =======================
3
+
4
+ Неофициальная python-библиотека для работы с Cristalix OpenAPI.
5
+
6
+ > ВНИМАНИЕ: библиотека не является официальным продуктом Cristalix.
7
+
8
+ ## Быстрый пример
9
+
10
+ ```python
11
+ from cristalix import CristalixClient
12
+
13
+ client = CristalixClient(
14
+ project_key="YOUR_PROJECT_KEY",
15
+ token="YOUR_TOKEN",
16
+ )
17
+
18
+ profile = client.get_profile_by_name("kkp_")
19
+ print(profile.username, profile.group.key)
20
+ ```
21
+
22
+ ## Async-пример
23
+
24
+ ```python
25
+ import asyncio
26
+ from cristalix import AsyncCristalixClient
27
+
28
+
29
+ async def main():
30
+ client = AsyncCristalixClient(
31
+ project_key="YOUR_PROJECT_KEY",
32
+ token="YOUR_TOKEN",
33
+ )
34
+ profile = await client.get_profile_by_name("kkp_")
35
+ print(profile.username, profile.group.key)
36
+
37
+
38
+ asyncio.run(main())
39
+ ```
40
+
@@ -0,0 +1,64 @@
1
+ Metadata-Version: 2.4
2
+ Name: cristalix
3
+ Version: 0.1.0
4
+ Summary: Unofficial Python client for Cristalix OpenAPI
5
+ Author-email: kkp_ <kkplikeme@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://cristalix.gg
8
+ Project-URL: Source, https://example.com/your-repo-url
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: httpx>=0.27.0
21
+ Requires-Dist: pydantic>=2.5.0
22
+ Requires-Dist: typing-extensions>=4.0.0; python_version < "3.11"
23
+ Dynamic: license-file
24
+
25
+ Cristalix Python Client
26
+ =======================
27
+
28
+ Неофициальная python-библиотека для работы с Cristalix OpenAPI.
29
+
30
+ > ВНИМАНИЕ: библиотека не является официальным продуктом Cristalix.
31
+
32
+ ## Быстрый пример
33
+
34
+ ```python
35
+ from cristalix import CristalixClient
36
+
37
+ client = CristalixClient(
38
+ project_key="YOUR_PROJECT_KEY",
39
+ token="YOUR_TOKEN",
40
+ )
41
+
42
+ profile = client.get_profile_by_name("kkp_")
43
+ print(profile.username, profile.group.key)
44
+ ```
45
+
46
+ ## Async-пример
47
+
48
+ ```python
49
+ import asyncio
50
+ from cristalix import AsyncCristalixClient
51
+
52
+
53
+ async def main():
54
+ client = AsyncCristalixClient(
55
+ project_key="YOUR_PROJECT_KEY",
56
+ token="YOUR_TOKEN",
57
+ )
58
+ profile = await client.get_profile_by_name("kkp_")
59
+ print(profile.username, profile.group.key)
60
+
61
+
62
+ asyncio.run(main())
63
+ ```
64
+
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ cristalix.egg-info/PKG-INFO
5
+ cristalix.egg-info/SOURCES.txt
6
+ cristalix.egg-info/dependency_links.txt
7
+ cristalix.egg-info/requires.txt
8
+ cristalix.egg-info/top_level.txt
9
+ tests/test_models_examples.py
@@ -0,0 +1,5 @@
1
+ httpx>=0.27.0
2
+ pydantic>=2.5.0
3
+
4
+ [:python_version < "3.11"]
5
+ typing-extensions>=4.0.0
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cristalix"
7
+ version = "0.1.0"
8
+ description = "Unofficial Python client for Cristalix OpenAPI"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "kkp_", email = "kkplikeme@gmail.com" },
14
+ ]
15
+ dependencies = [
16
+ "httpx>=0.27.0",
17
+ "pydantic>=2.5.0",
18
+ "typing-extensions>=4.0.0; python_version < '3.11'",
19
+ ]
20
+
21
+ classifiers = [
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Intended Audience :: Developers",
29
+ "Topic :: Software Development :: Libraries",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://cristalix.gg"
34
+ Source = "https://example.com/your-repo-url"
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["."]
38
+ include = ["cristalix*"]
39
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,200 @@
1
+ import pytest
2
+
3
+ from cristalix.models import (
4
+ AllProfileStatisticsEntry,
5
+ FriendsPage,
6
+ GameInfo,
7
+ LeaderboardEntry,
8
+ Player,
9
+ ProfileActivityEntry,
10
+ ProfileReactions,
11
+ ProfileStatisticsEntry,
12
+ SubscriptionsPage,
13
+ )
14
+
15
+
16
+ def test_player_from_docs_example():
17
+ data = {
18
+ "id": "00000000-0000-0000-0000-000000000000",
19
+ "username": "никнейм",
20
+ "registerTime": "2018-03-20T18:04:53.413Z",
21
+ "group": {
22
+ "key": "NO",
23
+ "name": "Player",
24
+ "prefixColor": "§7",
25
+ "nameColor": "§7",
26
+ "staffGroup": False,
27
+ "default": True,
28
+ },
29
+ "donate": {
30
+ "key": "TEST",
31
+ "name": "Test",
32
+ "prefixColor": "§7",
33
+ "nameColor": "§7",
34
+ "staffGroup": False,
35
+ "default": False,
36
+ },
37
+ "textures": {
38
+ "skin": "https://webdata.c7x.dev/textures/skin/00000000-0000-0000-0000-000000000000",
39
+ "cloak": "https://webdata.c7x.dev/textures/cape/00000000-0000-0000-0000-000000000000",
40
+ },
41
+ "realm": "Аркады",
42
+ "lastJoinTime": "2025-11-28T11:02:00.285909002Z",
43
+ "lastQuitTime": "2025-11-28T13:21:01.144844178Z",
44
+ "onlineTime": 0x39071742,
45
+ }
46
+ player = Player.from_raw(data)
47
+ assert player.id == data["id"]
48
+ assert player.username == data["username"]
49
+ assert player.group is not None
50
+ assert player.textures is not None
51
+
52
+
53
+ def test_player_staff_missing_last_times():
54
+ data = {
55
+ "id": "00000000-0000-0000-0000-000000000000",
56
+ "username": "staff",
57
+ "group": {
58
+ "key": "S",
59
+ "name": "Staff",
60
+ "prefixColor": "§c",
61
+ "nameColor": "§c",
62
+ "staffGroup": True,
63
+ "default": False,
64
+ },
65
+ }
66
+ player = Player.from_raw(data)
67
+ assert player.lastJoinTime is None
68
+ assert player.lastQuitTime is None
69
+
70
+
71
+ def test_profile_reactions_example():
72
+ data = {"likes": 10, "dislikes": 2}
73
+ reactions = ProfileReactions.model_validate(data)
74
+ assert reactions.likes == 10
75
+ assert reactions.dislikes == 2
76
+
77
+
78
+ def test_friends_page_example():
79
+ data = {
80
+ "list": [
81
+ {
82
+ "playerId": "00000000-0000-0000-0000-000000000000",
83
+ "groupName": "NO",
84
+ "username": "никнейм",
85
+ "realm": "Аркады",
86
+ "lastJoinTime": "2025-11-28T11:02:00.285909002Z",
87
+ "lastQuitTime": "2025-11-28T13:21:01.144844178Z",
88
+ }
89
+ ],
90
+ "totalCount": 1,
91
+ }
92
+ page = FriendsPage.model_validate(data)
93
+ assert page.totalCount == 1
94
+ assert len(page.list) == 1
95
+
96
+
97
+ def test_subscriptions_page_example():
98
+ data = {
99
+ "list": [
100
+ {
101
+ "playerId": "00000000-0000-0000-0000-000000000000",
102
+ "groupName": "VIP",
103
+ "username": "никнейм",
104
+ "realm": "Аркады",
105
+ }
106
+ ],
107
+ "totalCount": 1,
108
+ }
109
+ page = SubscriptionsPage.model_validate(data)
110
+ assert page.totalCount == 1
111
+ assert page.list[0].groupName == "VIP"
112
+
113
+
114
+ def test_activity_entry_example():
115
+ data = {
116
+ "gameId": "00000000-0000-0000-0000-000000000000",
117
+ "modeKey": "luckywars",
118
+ "subModeKey": "1x12",
119
+ "seasonKey": "default",
120
+ "statistics": {
121
+ "wins": 2,
122
+ "kills": 9,
123
+ "luckyBlockBreak": 590,
124
+ "defeats": 106,
125
+ "games": 108,
126
+ "timeInGame": 11423,
127
+ },
128
+ }
129
+ entry = ProfileActivityEntry.model_validate(data)
130
+ assert entry.statistics.wins == 2
131
+ assert entry.statistics.games == 108
132
+
133
+
134
+ def test_all_profile_statistics_example():
135
+ data = {
136
+ "gameId": "00000000-0000-0000-0000-000000000000",
137
+ "modeKey": "SAO",
138
+ "subModeKey": "default",
139
+ "seasonKey": "default",
140
+ "statisticsByPeriod": {
141
+ "MONTH": {"allDamage": 3, "click": 3},
142
+ "ALL": {"allDamage": 3, "rebirth": 1, "click": 3},
143
+ },
144
+ "periodEndings": {"MONTH": 17698932e5, "ALL": -1},
145
+ }
146
+ entry = AllProfileStatisticsEntry.model_validate(data)
147
+ assert "MONTH" in entry.statisticsByPeriod
148
+ assert "ALL" in entry.statisticsByPeriod
149
+
150
+
151
+ def test_profile_statistics_entry_example():
152
+ data = {
153
+ "gameId": "00000000-0000-0000-0000-000000000000",
154
+ "modeKey": "luckywars",
155
+ "subModeKey": "1x12",
156
+ "seasonKey": "default",
157
+ "statistics": {"wins": 3, "kills": 11, "games": 143},
158
+ }
159
+ entry = ProfileStatisticsEntry.model_validate(data)
160
+ assert entry.statistics["wins"] == 3
161
+
162
+
163
+ def test_games_list_example():
164
+ data = {
165
+ "gameId": "00000000-0000-0000-0000-000000000000",
166
+ "title": "Аркады",
167
+ "description": "",
168
+ "season": "default",
169
+ "released": True,
170
+ "status": "ACTIVATED",
171
+ "icon": "https://webdata.c7x.dev/compass/icons/luckywars.png",
172
+ "modes": [
173
+ {
174
+ "key": "luckywars",
175
+ "name": "LuckyWars",
176
+ "description": "",
177
+ "fields": [
178
+ {"key": "wins", "name": "Побед", "type": "WINS"},
179
+ {"key": "kills", "name": "Убийств", "type": "KILLS"},
180
+ ],
181
+ }
182
+ ],
183
+ "updatedAt": "2025-05-21T14:38:15.566910331Z",
184
+ "createdAt": "2025-05-21T14:38:15.566910331Z",
185
+ }
186
+ game = GameInfo.model_validate(data)
187
+ assert game.gameId == data["gameId"]
188
+ assert game.modes[0].fields[0].key == "wins"
189
+
190
+
191
+ def test_leaderboard_entry_example():
192
+ data = {
193
+ "playerId": "00000000-0000-0000-0000-000000000000",
194
+ "username": "никнейм",
195
+ "statistics": {"wins": 0, "kills": 1, "games": 1},
196
+ "periodEnding": 182041,
197
+ }
198
+ entry = LeaderboardEntry.model_validate(data)
199
+ assert entry.statistics["wins"] == 0
200
+