ecapi-sdk 3.7.2__tar.gz → 3.7.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecapi-sdk
3
- Version: 3.7.2
3
+ Version: 3.7.4
4
4
  Summary: ECAPI SDK for Python
5
5
  Author: EaseCation
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ecapi-sdk"
7
- version = "3.7.2"
7
+ version = "3.7.4"
8
8
  description = "ECAPI SDK for Python"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -4,6 +4,9 @@ from __future__ import annotations
4
4
  import asyncio
5
5
  import inspect
6
6
  import json
7
+ import mimetypes
8
+ from pathlib import Path
9
+ from uuid import uuid4
7
10
  from dataclasses import dataclass
8
11
  from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Tuple, Union
9
12
  from urllib.error import HTTPError, URLError
@@ -21,6 +24,61 @@ REQUEST_OPTION_KEYS = {"body", "headers", "response_type", "auth"}
21
24
  DEFAULT_BASE_URL = "https://api.easecation.net"
22
25
 
23
26
 
27
+ class _MultipartBody:
28
+ """Stream ordinary files without buffering a large ZIP in memory."""
29
+ def __init__(self, payload: Mapping[str, Any], binary_fields: Sequence[str]) -> None:
30
+ self.boundary = "ecapi-" + uuid4().hex
31
+ self.parts = []
32
+ self.length = 0
33
+ for name, value in payload.items():
34
+ if value is None:
35
+ continue
36
+ if not name.replace("_", "").isalnum():
37
+ raise ValueError("Invalid multipart field name")
38
+ prefix = f'--{self.boundary}\r\nContent-Disposition: form-data; name="{name}"'
39
+ if name in binary_fields:
40
+ if isinstance(value, Path):
41
+ if not value.is_file():
42
+ raise ValueError("Upload path must be an ordinary file")
43
+ filename, data, size = value.name, value, value.stat().st_size
44
+ elif isinstance(value, tuple) and len(value) == 2 and isinstance(value[0], str) and isinstance(value[1], bytes):
45
+ filename, data = value
46
+ size = len(data)
47
+ else:
48
+ raise TypeError("Binary fields require pathlib.Path or (filename, bytes)")
49
+ if any(c in filename for c in '\r\n\0'):
50
+ raise ValueError("Invalid upload filename")
51
+ filename = filename.replace('"', '%22').replace('\\', '%5C')
52
+ mime = mimetypes.guess_type(filename)[0] or "application/octet-stream"
53
+ prefix += f'; filename="{filename}"\r\nContent-Type: {mime}'
54
+ else:
55
+ data = (str(value).lower() if isinstance(value, bool) else str(value)).encode("utf-8")
56
+ size = len(data)
57
+ prefix = (prefix + "\r\n\r\n").encode("utf-8")
58
+ self.parts.append((prefix, data, size))
59
+ self.length += len(prefix) + size + 2
60
+ self.suffix = f"--{self.boundary}--\r\n".encode("ascii")
61
+ self.length += len(self.suffix)
62
+
63
+ def __iter__(self):
64
+ for prefix, data, size in self.parts:
65
+ yield prefix
66
+ if isinstance(data, Path):
67
+ with data.open("rb") as handle:
68
+ remaining = size
69
+ while remaining:
70
+ chunk = handle.read(min(65536, remaining))
71
+ if not chunk:
72
+ raise OSError("Upload file changed while reading")
73
+ remaining -= len(chunk)
74
+ yield chunk
75
+ if handle.read(1):
76
+ raise OSError("Upload file changed while reading")
77
+ else:
78
+ yield data
79
+ yield b"\r\n"
80
+ yield self.suffix
81
+
24
82
  class ECAPIError(Exception):
25
83
  def __init__(self, message: str, status: int, payload: Any, url: str) -> None:
26
84
  resolved_message = _extract_error_message(payload) or message
@@ -224,7 +282,11 @@ class _HttpClient:
224
282
  merged_headers["Authorization"] = f"Bearer {token}"
225
283
 
226
284
  request_data: Optional[bytes] = None
227
- if body is not None:
285
+ if isinstance(body, _MultipartBody):
286
+ merged_headers["Content-Type"] = "multipart/form-data; boundary=" + body.boundary
287
+ merged_headers["Content-Length"] = str(body.length)
288
+ request_data = body
289
+ elif body is not None:
228
290
  content_type = merged_headers.get("Content-Type", "")
229
291
  if not content_type:
230
292
  merged_headers["Content-Type"] = "application/json"
@@ -487,6 +549,7 @@ class AdminAPI(_BaseApi):
487
549
  self.operation_log = AdminOperationLogAPI(http)
488
550
  self.overwatch_case = AdminOverwatchCaseAPI(http)
489
551
  self.overwatch_supervisor = AdminOverwatchSupervisorAPI(http)
552
+ self.parkour = AdminParkourAPI(http)
490
553
  self.permission = AdminPermissionAPI(http)
491
554
  self.player_data = AdminPlayerDataAPI(http)
492
555
  self.player_merchandise = AdminPlayerMerchandiseAPI(http)
@@ -494,6 +557,7 @@ class AdminAPI(_BaseApi):
494
557
  self.player_wallet = AdminPlayerWalletAPI(http)
495
558
  self.punishment = AdminPunishmentAPI(http)
496
559
  self.source_account_binding = AdminSourceAccountBindingAPI(http)
560
+ self.sp_workbench = AdminSpWorkbenchAPI(http)
497
561
  self.vote_reward_mail = AdminVoteRewardMailAPI(http)
498
562
 
499
563
  class AdminAccountAPI(_BaseApi):
@@ -562,6 +626,15 @@ class AdminOverwatchSupervisorAPI(_BaseApi):
562
626
  """修改监管者资格"""
563
627
  return self._patch(f"/admin/overwatch-supervisors/{quote(str(ecid), safe='')}", payload, **kwargs)
564
628
 
629
+ class AdminParkourAPI(_BaseApi):
630
+ def clear_community_scores(self, ecid: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
631
+ """清除社区版逐关成绩"""
632
+ return self._post(f"/admin/players/{quote(str(ecid), safe='')}/parkour/community-score-clears", payload, **kwargs)
633
+
634
+ def preview_community_score_clear(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
635
+ """预览社区版逐关成绩清除范围"""
636
+ return self._get(f"/admin/players/{quote(str(ecid), safe='')}/parkour/community-score-clear-preview", query, **kwargs)
637
+
565
638
  class AdminPermissionAPI(_BaseApi):
566
639
  def delete_entitlement(self, ecid: str, entitlementKey: str, **kwargs: Any) -> Any:
567
640
  """删除玩家权益"""
@@ -660,6 +733,10 @@ class AdminPunishmentAPI(_BaseApi):
660
733
  """解除处罚"""
661
734
  return self._delete(f"/admin/players/{quote(str(ecid), safe='')}/punishments/{quote(str(type), safe='')}", query, **kwargs)
662
735
 
736
+ def set_parkour_punishment(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
737
+ """设置老版跑酷天堂成绩惩罚"""
738
+ return self._post(f"/punishments/parkour", payload, **kwargs)
739
+
663
740
  class AdminSourceAccountBindingAPI(_BaseApi):
664
741
  def bind_account_player(self, xuid: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
665
742
  """绑定或改绑来源账号到玩家"""
@@ -677,11 +754,53 @@ class AdminSourceAccountBindingAPI(_BaseApi):
677
754
  """解绑玩家名下全部来源账号"""
678
755
  return self._delete(f"/admin/players/{quote(str(ecid), safe='')}/source-accounts", None, **kwargs)
679
756
 
757
+ class AdminSpWorkbenchAPI(_BaseApi):
758
+ def capabilities(self, **kwargs: Any) -> Any:
759
+ """只读查询 SP 专用进度执行能力"""
760
+ return self._get(f"/admin/sp/progress/capabilities", None, **kwargs)
761
+
762
+ def progress(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
763
+ """执行 SP 专用标准值进度修正"""
764
+ return self._post(f"/admin/sp/progress/operations", payload, **kwargs)
765
+
680
766
  class AdminVoteRewardMailAPI(_BaseApi):
681
767
  def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
682
768
  """创建投票奖励邮件"""
683
769
  return self._post(f"/admin/vote-reward-mails", payload, **kwargs)
684
770
 
771
+ class AnnouncementsAPI(_BaseApi):
772
+ def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
773
+ """新建公告"""
774
+ return self._post(f"/admin/announcements", payload, **kwargs)
775
+
776
+ def get(self, id: str, **kwargs: Any) -> Any:
777
+ """读取公告管理详情"""
778
+ return self._get(f"/admin/announcements/{quote(str(id), safe='')}", None, **kwargs)
779
+
780
+ def list(self, **kwargs: Any) -> Any:
781
+ """读取服内生效公告"""
782
+ return self._get(f"/announcements", None, **kwargs)
783
+
784
+ def list_get(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
785
+ """查询公告管理列表"""
786
+ return self._get(f"/admin/announcements", query, **kwargs)
787
+
788
+ def move(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
789
+ """原子移动公告顺序"""
790
+ return self._post(f"/admin/announcements/{quote(str(id), safe='')}/move", payload, **kwargs)
791
+
792
+ def remove(self, id: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
793
+ """公告移入回收站"""
794
+ return self._delete(f"/admin/announcements/{quote(str(id), safe='')}", query, **kwargs)
795
+
796
+ def restore(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
797
+ """恢复公告"""
798
+ return self._post(f"/admin/announcements/{quote(str(id), safe='')}/restore", payload, **kwargs)
799
+
800
+ def update(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
801
+ """修改公告"""
802
+ return self._patch(f"/admin/announcements/{quote(str(id), safe='')}", payload, **kwargs)
803
+
685
804
  class AuditAPI(_BaseApi):
686
805
  def get_admin_logs(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
687
806
  """查询管理员操作日志"""
@@ -737,6 +856,10 @@ class CatalogAPI(_BaseApi):
737
856
  super().__init__(http)
738
857
  self.sync = CatalogSyncAPI(http)
739
858
 
859
+ def batch_update_products(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
860
+ """批量设置商品价格、稀有度或状态"""
861
+ return self._post(f"/catalog/products/batch-update", payload, **kwargs)
862
+
740
863
  def change_product_status(self, id: Union[int, float], payload: Mapping[str, Any], **kwargs: Any) -> Any:
741
864
  """商品状态流转"""
742
865
  return self._post(f"/catalog/products/{quote(str(id), safe='')}/status", payload, **kwargs)
@@ -749,6 +872,10 @@ class CatalogAPI(_BaseApi):
749
872
  """新建商品类型"""
750
873
  return self._post(f"/catalog/types", payload, **kwargs)
751
874
 
875
+ def delete_products(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
876
+ """移入商品回收站"""
877
+ return self._post(f"/catalog/products/batch-delete", payload, **kwargs)
878
+
752
879
  def export_by_type(self, typeId: str, **kwargs: Any) -> Any:
753
880
  """按类型导出 CodeFunCore 商品配置 JSON"""
754
881
  return self._get(f"/catalog/export/{quote(str(typeId), safe='')}", None, **kwargs)
@@ -765,6 +892,10 @@ class CatalogAPI(_BaseApi):
765
892
  """分页查询商品列表"""
766
893
  return self._get(f"/catalog/products", query, **kwargs)
767
894
 
895
+ def list_published_products(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
896
+ """分页查询正式服已上架商品"""
897
+ return self._get(f"/catalog/published-products", query, **kwargs)
898
+
768
899
  def list_types(self, **kwargs: Any) -> Any:
769
900
  """获取商品类型列表"""
770
901
  return self._get(f"/catalog/types", None, **kwargs)
@@ -773,6 +904,10 @@ class CatalogAPI(_BaseApi):
773
904
  """整体替换套装部件列表"""
774
905
  return self._put(f"/catalog/products/{quote(str(id), safe='')}/parts", payload, **kwargs)
775
906
 
907
+ def restore_products(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
908
+ """恢复回收站商品"""
909
+ return self._post(f"/catalog/products/batch-restore", payload, **kwargs)
910
+
776
911
  def update_product(self, id: Union[int, float], payload: Mapping[str, Any], **kwargs: Any) -> Any:
777
912
  """更新商品"""
778
913
  return self._put(f"/catalog/products/{quote(str(id), safe='')}", payload, **kwargs)
@@ -1032,6 +1167,11 @@ class LotteryAPI(_BaseApi):
1032
1167
  return self._post(f"/lottery/validate", payload, **kwargs)
1033
1168
 
1034
1169
  class MinecraftDeveloperAPI(_BaseApi):
1170
+ def __init__(self, http: _HttpClient) -> None:
1171
+ super().__init__(http)
1172
+ self.messages = MinecraftMessagesAPI(http)
1173
+ self.mobile_mods = MinecraftMobileModsAPI(http)
1174
+
1035
1175
  def apply_self_test(self, edition: str, projectId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1036
1176
  """申请手游自测"""
1037
1177
  return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/self-test-applications", payload, **kwargs)
@@ -1086,6 +1226,7 @@ class MinecraftDeveloperAPI(_BaseApi):
1086
1226
 
1087
1227
  def replace_resource_pack(self, edition: str, projectId: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1088
1228
  """上传并替换资源包"""
1229
+ payload = _MultipartBody(payload, ['package'])
1089
1230
  return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/resource-packs", payload, **kwargs)
1090
1231
 
1091
1232
  def revoke_review(self, edition: str, projectId: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
@@ -1096,6 +1237,81 @@ class MinecraftDeveloperAPI(_BaseApi):
1096
1237
  """提交网易审核"""
1097
1238
  return self._post(f"/mcdev/projects/{quote(str(edition), safe='')}/{quote(str(projectId), safe='')}/review-submissions", payload, **kwargs)
1098
1239
 
1240
+ class MinecraftMessagesAPI(_BaseApi):
1241
+ def detail(self, messageId: str, **kwargs: Any) -> Any:
1242
+ """读取审核消息正文"""
1243
+ return self._get(f"/mcdev/messages/{quote(str(messageId), safe='')}", None, **kwargs)
1244
+
1245
+ def list(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
1246
+ """分页查询审核与打包消息"""
1247
+ return self._get(f"/mcdev/messages", query, **kwargs)
1248
+
1249
+ def mark_read(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1250
+ """标记指定审核消息已读"""
1251
+ return self._post(f"/mcdev/message-read-receipts", payload, **kwargs)
1252
+
1253
+ def unread(self, **kwargs: Any) -> Any:
1254
+ """查询审核消息未读数量"""
1255
+ return self._get(f"/mcdev/messages/unread-count", None, **kwargs)
1256
+
1257
+ class MinecraftMobileModsAPI(_BaseApi):
1258
+ def apply_self_test(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1259
+ """申请手机组件自测"""
1260
+ return self._post(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/self-test-applications", payload, **kwargs)
1261
+
1262
+ def cancel_self_test(self, id: str, **kwargs: Any) -> Any:
1263
+ """取消手机组件自测"""
1264
+ return self._delete(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/self-test-applications/current", None, **kwargs)
1265
+
1266
+ def create(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1267
+ """创建手机组件"""
1268
+ return self._post(f"/mcdev/mobile-mods", payload, **kwargs)
1269
+
1270
+ def detail(self, id: str, **kwargs: Any) -> Any:
1271
+ """读取手机组件编辑内容"""
1272
+ return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}", None, **kwargs)
1273
+
1274
+ def feedback(self, id: str, **kwargs: Any) -> Any:
1275
+ """读取手机组件审核意见"""
1276
+ return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/review-feedback", None, **kwargs)
1277
+
1278
+ def list(self, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
1279
+ """分页查询手机组件"""
1280
+ return self._get(f"/mcdev/mobile-mods", query, **kwargs)
1281
+
1282
+ def metadata(self, **kwargs: Any) -> Any:
1283
+ """读取手机组件编辑规则"""
1284
+ return self._get(f"/mcdev/mobile-mods/metadata", None, **kwargs)
1285
+
1286
+ def preview_asset(self, id: str, assetId: str, **kwargs: Any) -> Any:
1287
+ """读取手机组件素材"""
1288
+ return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/assets/{quote(str(assetId), safe='')}/content", None, response_type="bytes", **kwargs)
1289
+
1290
+ def preview_upload(self, uploadId: str, **kwargs: Any) -> Any:
1291
+ """预览已上传图片"""
1292
+ return self._get(f"/mcdev/mobile-mods/uploads/{quote(str(uploadId), safe='')}/content", None, response_type="bytes", **kwargs)
1293
+
1294
+ def revoke_review(self, id: str, **kwargs: Any) -> Any:
1295
+ """撤销手机组件审核"""
1296
+ return self._delete(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/review-submissions/current", None, **kwargs)
1297
+
1298
+ def status(self, id: str, **kwargs: Any) -> Any:
1299
+ """查询手机组件处理状态"""
1300
+ return self._get(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/status", None, **kwargs)
1301
+
1302
+ def submit_review(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1303
+ """提交手机组件审核"""
1304
+ return self._post(f"/mcdev/mobile-mods/{quote(str(id), safe='')}/review-submissions", payload, **kwargs)
1305
+
1306
+ def update(self, id: str, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1307
+ """保存手机组件修改"""
1308
+ return self._patch(f"/mcdev/mobile-mods/{quote(str(id), safe='')}", payload, **kwargs)
1309
+
1310
+ def upload(self, payload: Mapping[str, Any], **kwargs: Any) -> Any:
1311
+ """上传手机组件素材"""
1312
+ payload = _MultipartBody(payload, ['file'])
1313
+ return self._post(f"/mcdev/mobile-mods/uploads", payload, **kwargs)
1314
+
1099
1315
  class OSSAPI(_BaseApi):
1100
1316
  def get_ze_content(self, fileName: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
1101
1317
  """读取 ZE OSS 配置内容"""
@@ -1182,7 +1398,7 @@ class PlayerAPI(_BaseApi):
1182
1398
  return self._get(f"/players/{quote(str(ecid), safe='')}/farm/freshness-batches", query, **kwargs)
1183
1399
 
1184
1400
  def get_farm_overview(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
1185
- """查询 EC 农场 S1 完整总览"""
1401
+ """查询 EC 农场总览(S1 与 S2 核心状态)"""
1186
1402
  return self._get(f"/players/{quote(str(ecid), safe='')}/farm/overview", query, **kwargs)
1187
1403
 
1188
1404
  def get_farm_summary(self, ecid: str, query: Optional[QueryParams] = None, **kwargs: Any) -> Any:
@@ -1673,6 +1889,7 @@ class ECAPIClient:
1673
1889
  ) -> None:
1674
1890
  self._http = _HttpClient(base_url, auth, timeout_seconds, default_headers, auth_provider)
1675
1891
  self.admin = AdminAPI(self._http)
1892
+ self.announcements = AnnouncementsAPI(self._http)
1676
1893
  self.audit = AuditAPI(self._http)
1677
1894
  self.auth = AuthAPI(self._http)
1678
1895
  self.catalog = CatalogAPI(self._http)
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
+ from pathlib import Path
4
5
  from typing import Any, Awaitable, Callable, Dict, Mapping, Optional, Sequence, TypedDict, Union
5
6
 
6
7
  Primitive = Union[str, int, float, bool, None]
@@ -334,6 +335,24 @@ class AdminOverwatchSupervisorAPIUpdateBody(TypedDict, total=False):
334
335
  level: int
335
336
  expiry: Optional[str]
336
337
 
338
+ class AdminParkourAPIPreviewCommunityScoreClearQueryRequired(TypedDict):
339
+ scope: QueryValue
340
+
341
+ class AdminParkourAPIPreviewCommunityScoreClearQuery(AdminParkourAPIPreviewCommunityScoreClearQueryRequired, total=False):
342
+ playerDataId: QueryValue
343
+ trackKey: QueryValue
344
+
345
+ class AdminParkourAPIClearCommunityScoresBodyRequired(TypedDict):
346
+ scope: str
347
+ requestId: str
348
+ reason: str
349
+
350
+ class AdminParkourAPIClearCommunityScoresBody(AdminParkourAPIClearCommunityScoresBodyRequired, total=False):
351
+ playerDataId: int
352
+ trackKey: str
353
+ scopeFingerprint: str
354
+ evidenceRefs: Sequence[Any]
355
+
337
356
  class AdminPermissionAPISetAnticheatPermissionBodyRequired(TypedDict):
338
357
  enabled: bool
339
358
 
@@ -455,18 +474,84 @@ class AdminPunishmentAPIListQuery(TypedDict, total=False):
455
474
  current: QueryValue
456
475
  pageSize: QueryValue
457
476
 
477
+ class AdminPunishmentAPISetParkourPunishmentBodyRequired(TypedDict):
478
+ ecid: str
479
+ map: str
480
+ start: int
481
+ end: int
482
+ useTime: int
483
+
484
+ class AdminPunishmentAPISetParkourPunishmentBody(AdminPunishmentAPISetParkourPunishmentBodyRequired, total=False):
485
+ source: str
486
+
458
487
  class AdminSourceAccountBindingAPIBindAccountPlayerBodyRequired(TypedDict):
459
488
  ecid: str
460
489
 
461
490
  class AdminSourceAccountBindingAPIBindAccountPlayerBody(AdminSourceAccountBindingAPIBindAccountPlayerBodyRequired, total=False):
462
491
  pass
463
492
 
493
+ class AdminSpWorkbenchAPIProgressBodyRequired(TypedDict):
494
+ operationId: str
495
+ tid: int
496
+
497
+ class AdminSpWorkbenchAPIProgressBody(AdminSpWorkbenchAPIProgressBodyRequired, total=False):
498
+ pass
499
+
464
500
  class AdminVoteRewardMailAPICreateBodyRequired(TypedDict):
465
501
  players: Sequence[Any]
466
502
 
467
503
  class AdminVoteRewardMailAPICreateBody(AdminVoteRewardMailAPICreateBodyRequired, total=False):
468
504
  enableDisplayNameLookup: bool
469
505
 
506
+ class AnnouncementsAPIListGetQuery(TypedDict, total=False):
507
+ current: QueryValue
508
+ pageSize: QueryValue
509
+ search: QueryValue
510
+ enabled: QueryValue
511
+ autoPopup: QueryValue
512
+ view: QueryValue
513
+
514
+ class AnnouncementsAPICreateBodyRequired(TypedDict):
515
+ id: str
516
+ title: str
517
+
518
+ class AnnouncementsAPICreateBody(AnnouncementsAPICreateBodyRequired, total=False):
519
+ content: Sequence[Any]
520
+ enabled: bool
521
+ autoPopup: bool
522
+ sortOrder: int
523
+
524
+ class AnnouncementsAPIRemoveQueryRequired(TypedDict):
525
+ version: QueryValue
526
+
527
+ class AnnouncementsAPIRemoveQuery(AnnouncementsAPIRemoveQueryRequired, total=False):
528
+ pass
529
+
530
+ class AnnouncementsAPIUpdateBodyRequired(TypedDict):
531
+ version: int
532
+
533
+ class AnnouncementsAPIUpdateBody(AnnouncementsAPIUpdateBodyRequired, total=False):
534
+ title: str
535
+ content: Sequence[Any]
536
+ enabled: bool
537
+ autoPopup: bool
538
+ sortOrder: int
539
+
540
+ class AnnouncementsAPIMoveBodyRequired(TypedDict):
541
+ version: int
542
+ targetId: str
543
+ targetVersion: int
544
+ direction: str
545
+
546
+ class AnnouncementsAPIMoveBody(AnnouncementsAPIMoveBodyRequired, total=False):
547
+ pass
548
+
549
+ class AnnouncementsAPIRestoreBodyRequired(TypedDict):
550
+ version: int
551
+
552
+ class AnnouncementsAPIRestoreBody(AnnouncementsAPIRestoreBodyRequired, total=False):
553
+ pass
554
+
470
555
  class AuditAPIQueryAccessLogsQuery(TypedDict, total=False):
471
556
  current: QueryValue
472
557
  pageSize: QueryValue
@@ -597,6 +682,7 @@ class AuthAPIRefreshTokenBody(AuthAPIRefreshTokenBodyRequired, total=False):
597
682
  class CatalogAPIListProductsQuery(TypedDict, total=False):
598
683
  current: QueryValue
599
684
  pageSize: QueryValue
685
+ view: QueryValue
600
686
  search: QueryValue
601
687
  author: QueryValue
602
688
  typeId: QueryValue
@@ -616,6 +702,25 @@ class CatalogAPICreateProductBody(CatalogAPICreateProductBodyRequired, total=Fal
616
702
  acquireConfig: str
617
703
  remark: str
618
704
 
705
+ class CatalogAPIDeleteProductsBodyRequired(TypedDict):
706
+ productIds: Sequence[Any]
707
+
708
+ class CatalogAPIDeleteProductsBody(CatalogAPIDeleteProductsBodyRequired, total=False):
709
+ pass
710
+
711
+ class CatalogAPIRestoreProductsBodyRequired(TypedDict):
712
+ productIds: Sequence[Any]
713
+
714
+ class CatalogAPIRestoreProductsBody(CatalogAPIRestoreProductsBodyRequired, total=False):
715
+ pass
716
+
717
+ class CatalogAPIBatchUpdateProductsBodyRequired(TypedDict):
718
+ productIds: Sequence[Any]
719
+ change: Mapping[str, Any]
720
+
721
+ class CatalogAPIBatchUpdateProductsBody(CatalogAPIBatchUpdateProductsBodyRequired, total=False):
722
+ pass
723
+
619
724
  class CatalogAPIUpdateProductBody(TypedDict, total=False):
620
725
  typeId: str
621
726
  idItem: str
@@ -639,6 +744,11 @@ class CatalogAPIChangeProductStatusBodyRequired(TypedDict):
639
744
  class CatalogAPIChangeProductStatusBody(CatalogAPIChangeProductStatusBodyRequired, total=False):
640
745
  pass
641
746
 
747
+ class CatalogAPIListPublishedProductsQuery(TypedDict, total=False):
748
+ current: QueryValue
749
+ pageSize: QueryValue
750
+ typeId: QueryValue
751
+
642
752
  class CatalogAPICreateTypeBodyRequired(TypedDict):
643
753
  typeId: str
644
754
  category: str
@@ -676,6 +786,7 @@ class GameLogAPIGetMatchesQueryRequired(TypedDict):
676
786
 
677
787
  class GameLogAPIGetMatchesQuery(GameLogAPIGetMatchesQueryRequired, total=False):
678
788
  ecid: QueryValue
789
+ gameMode: QueryValue
679
790
  startTime: QueryValue
680
791
  endTime: QueryValue
681
792
  current: QueryValue
@@ -970,7 +1081,7 @@ class MinecraftDeveloperAPIListPlayerFeedbacksQuery(MinecraftDeveloperAPIListPla
970
1081
  pageSize: QueryValue
971
1082
 
972
1083
  class MinecraftDeveloperAPIReplaceResourcePackBodyRequired(TypedDict):
973
- package: str
1084
+ package: Union[Path, tuple[str, bytes]]
974
1085
 
975
1086
  class MinecraftDeveloperAPIReplaceResourcePackBody(MinecraftDeveloperAPIReplaceResourcePackBodyRequired, total=False):
976
1087
  confirmQueue: bool
@@ -999,6 +1110,100 @@ class MinecraftDeveloperAPICancelSelfTestQueryRequired(TypedDict):
999
1110
  class MinecraftDeveloperAPICancelSelfTestQuery(MinecraftDeveloperAPICancelSelfTestQueryRequired, total=False):
1000
1111
  pass
1001
1112
 
1113
+ class MinecraftMessagesAPIMarkReadBodyRequired(TypedDict):
1114
+ messageIds: Sequence[Any]
1115
+
1116
+ class MinecraftMessagesAPIMarkReadBody(MinecraftMessagesAPIMarkReadBodyRequired, total=False):
1117
+ pass
1118
+
1119
+ class MinecraftMessagesAPIListQuery(TypedDict, total=False):
1120
+ current: QueryValue
1121
+ pageSize: QueryValue
1122
+ title: QueryValue
1123
+ read: QueryValue
1124
+
1125
+ class MinecraftMobileModsAPIListQuery(TypedDict, total=False):
1126
+ current: QueryValue
1127
+ pageSize: QueryValue
1128
+ search: QueryValue
1129
+ kind: QueryValue
1130
+ status: QueryValue
1131
+ playPlan: QueryValue
1132
+ sortBy: QueryValue
1133
+ sortOrder: QueryValue
1134
+
1135
+ class MinecraftMobileModsAPICreateBodyRequired(TypedDict):
1136
+ name: str
1137
+ kind: str
1138
+ subTypeId: int
1139
+ labelIds: Sequence[Any]
1140
+ modVersion: str
1141
+ original: bool
1142
+ contentHtml: str
1143
+ pricing: Mapping[str, Any]
1144
+ resources: Sequence[Any]
1145
+ images: Sequence[Any]
1146
+
1147
+ class MinecraftMobileModsAPICreateBody(MinecraftMobileModsAPICreateBodyRequired, total=False):
1148
+ secondTypeId: int
1149
+ tags: Sequence[Any]
1150
+ copyrightProof: Optional[Mapping[str, Any]]
1151
+ updateSummary: str
1152
+ activityDescription: str
1153
+ video: Optional[Mapping[str, Any]]
1154
+ banner: Optional[Mapping[str, Any]]
1155
+ bodyType: str
1156
+ mountCall: bool
1157
+ lobby: Mapping[str, Any]
1158
+ increaseVersion: bool
1159
+ confirmQueue: bool
1160
+
1161
+ class MinecraftMobileModsAPIUploadBodyRequired(TypedDict):
1162
+ file: Union[Path, tuple[str, bytes]]
1163
+ purpose: str
1164
+ kind: str
1165
+ subTypeId: int
1166
+
1167
+ class MinecraftMobileModsAPIUploadBody(MinecraftMobileModsAPIUploadBodyRequired, total=False):
1168
+ channelId: int
1169
+
1170
+ class MinecraftMobileModsAPIUpdateBodyRequired(TypedDict):
1171
+ baseRevision: str
1172
+
1173
+ class MinecraftMobileModsAPIUpdateBody(MinecraftMobileModsAPIUpdateBodyRequired, total=False):
1174
+ name: str
1175
+ kind: str
1176
+ subTypeId: int
1177
+ secondTypeId: int
1178
+ labelIds: Sequence[Any]
1179
+ tags: Sequence[Any]
1180
+ modVersion: str
1181
+ original: bool
1182
+ copyrightProof: Optional[Mapping[str, Any]]
1183
+ contentHtml: str
1184
+ updateSummary: str
1185
+ activityDescription: str
1186
+ pricing: Mapping[str, Any]
1187
+ resources: Sequence[Any]
1188
+ images: Sequence[Any]
1189
+ video: Optional[Mapping[str, Any]]
1190
+ banner: Optional[Mapping[str, Any]]
1191
+ bodyType: str
1192
+ mountCall: bool
1193
+ lobby: Mapping[str, Any]
1194
+ increaseVersion: bool
1195
+ confirmQueue: bool
1196
+
1197
+ class MinecraftMobileModsAPISubmitReviewBody(TypedDict, total=False):
1198
+ note: str
1199
+ conflictNotify: str
1200
+ conflictTypes: Sequence[Any]
1201
+ confirmQueue: bool
1202
+
1203
+ class MinecraftMobileModsAPIApplySelfTestBody(TypedDict, total=False):
1204
+ mode: str
1205
+ confirmQueue: bool
1206
+
1002
1207
  class OSSAPIGetZeContentQuery(TypedDict, total=False):
1003
1208
  versionId: QueryValue
1004
1209
 
@@ -1568,6 +1773,7 @@ class AdminAPI:
1568
1773
  operation_log: AdminOperationLogAPI
1569
1774
  overwatch_case: AdminOverwatchCaseAPI
1570
1775
  overwatch_supervisor: AdminOverwatchSupervisorAPI
1776
+ parkour: AdminParkourAPI
1571
1777
  permission: AdminPermissionAPI
1572
1778
  player_data: AdminPlayerDataAPI
1573
1779
  player_merchandise: AdminPlayerMerchandiseAPI
@@ -1575,6 +1781,7 @@ class AdminAPI:
1575
1781
  player_wallet: AdminPlayerWalletAPI
1576
1782
  punishment: AdminPunishmentAPI
1577
1783
  source_account_binding: AdminSourceAccountBindingAPI
1784
+ sp_workbench: AdminSpWorkbenchAPI
1578
1785
  vote_reward_mail: AdminVoteRewardMailAPI
1579
1786
 
1580
1787
  class AdminAccountAPI:
@@ -1604,6 +1811,10 @@ class AdminOverwatchSupervisorAPI:
1604
1811
  def select(self, payload: AdminOverwatchSupervisorAPISelectBody, **kwargs: Any) -> Any: ...
1605
1812
  def update(self, ecid: str, payload: AdminOverwatchSupervisorAPIUpdateBody, **kwargs: Any) -> Any: ...
1606
1813
 
1814
+ class AdminParkourAPI:
1815
+ def clear_community_scores(self, ecid: str, payload: AdminParkourAPIClearCommunityScoresBody, **kwargs: Any) -> Any: ...
1816
+ def preview_community_score_clear(self, ecid: str, query: AdminParkourAPIPreviewCommunityScoreClearQuery, **kwargs: Any) -> Any: ...
1817
+
1607
1818
  class AdminPermissionAPI:
1608
1819
  def delete_entitlement(self, ecid: str, entitlementKey: str, **kwargs: Any) -> Any: ...
1609
1820
  def set_anticheat_permission(self, ecid: str, payload: AdminPermissionAPISetAnticheatPermissionBody, **kwargs: Any) -> Any: ...
@@ -1638,6 +1849,7 @@ class AdminPunishmentAPI:
1638
1849
  def list(self, query: Optional[AdminPunishmentAPIListQuery] = ..., **kwargs: Any) -> Any: ...
1639
1850
  def list_prism_device_ban_logs(self, query: Optional[AdminPunishmentAPIListPrismDeviceBanLogsQuery] = ..., **kwargs: Any) -> Any: ...
1640
1851
  def remove(self, ecid: str, type: str, query: Optional[AdminPunishmentAPIRemoveQuery] = ..., **kwargs: Any) -> Any: ...
1852
+ def set_parkour_punishment(self, payload: AdminPunishmentAPISetParkourPunishmentBody, **kwargs: Any) -> Any: ...
1641
1853
 
1642
1854
  class AdminSourceAccountBindingAPI:
1643
1855
  def bind_account_player(self, xuid: str, payload: AdminSourceAccountBindingAPIBindAccountPlayerBody, **kwargs: Any) -> Any: ...
@@ -1645,9 +1857,23 @@ class AdminSourceAccountBindingAPI:
1645
1857
  def reset_player_account(self, ecid: str, xuid: str, **kwargs: Any) -> Any: ...
1646
1858
  def reset_player_accounts(self, ecid: str, **kwargs: Any) -> Any: ...
1647
1859
 
1860
+ class AdminSpWorkbenchAPI:
1861
+ def capabilities(self, **kwargs: Any) -> Any: ...
1862
+ def progress(self, payload: AdminSpWorkbenchAPIProgressBody, **kwargs: Any) -> Any: ...
1863
+
1648
1864
  class AdminVoteRewardMailAPI:
1649
1865
  def create(self, payload: AdminVoteRewardMailAPICreateBody, **kwargs: Any) -> Any: ...
1650
1866
 
1867
+ class AnnouncementsAPI:
1868
+ def create(self, payload: AnnouncementsAPICreateBody, **kwargs: Any) -> Any: ...
1869
+ def get(self, id: str, **kwargs: Any) -> Any: ...
1870
+ def list(self, **kwargs: Any) -> Any: ...
1871
+ def list_get(self, query: Optional[AnnouncementsAPIListGetQuery] = ..., **kwargs: Any) -> Any: ...
1872
+ def move(self, id: str, payload: AnnouncementsAPIMoveBody, **kwargs: Any) -> Any: ...
1873
+ def remove(self, id: str, query: AnnouncementsAPIRemoveQuery, **kwargs: Any) -> Any: ...
1874
+ def restore(self, id: str, payload: AnnouncementsAPIRestoreBody, **kwargs: Any) -> Any: ...
1875
+ def update(self, id: str, payload: AnnouncementsAPIUpdateBody, **kwargs: Any) -> Any: ...
1876
+
1651
1877
  class AuditAPI:
1652
1878
  def get_admin_logs(self, query: Optional[AuditAPIGetAdminLogsQuery] = ..., **kwargs: Any) -> Any: ...
1653
1879
  def get_auth_logs(self, query: Optional[AuditAPIGetAuthLogsQuery] = ..., **kwargs: Any) -> Any: ...
@@ -1666,15 +1892,19 @@ class AuthAPI:
1666
1892
 
1667
1893
  class CatalogAPI:
1668
1894
  sync: CatalogSyncAPI
1895
+ def batch_update_products(self, payload: CatalogAPIBatchUpdateProductsBody, **kwargs: Any) -> Any: ...
1669
1896
  def change_product_status(self, id: Union[int, float], payload: CatalogAPIChangeProductStatusBody, **kwargs: Any) -> Any: ...
1670
1897
  def create_product(self, payload: CatalogAPICreateProductBody, **kwargs: Any) -> Any: ...
1671
1898
  def create_type(self, payload: CatalogAPICreateTypeBody, **kwargs: Any) -> Any: ...
1899
+ def delete_products(self, payload: CatalogAPIDeleteProductsBody, **kwargs: Any) -> Any: ...
1672
1900
  def export_by_type(self, typeId: str, **kwargs: Any) -> Any: ...
1673
1901
  def get_product_detail(self, id: Union[int, float], **kwargs: Any) -> Any: ...
1674
1902
  def get_suit_parts(self, id: Union[int, float], **kwargs: Any) -> Any: ...
1675
1903
  def list_products(self, query: Optional[CatalogAPIListProductsQuery] = ..., **kwargs: Any) -> Any: ...
1904
+ def list_published_products(self, query: Optional[CatalogAPIListPublishedProductsQuery] = ..., **kwargs: Any) -> Any: ...
1676
1905
  def list_types(self, **kwargs: Any) -> Any: ...
1677
1906
  def replace_suit_parts(self, id: Union[int, float], payload: CatalogAPIReplaceSuitPartsBody, **kwargs: Any) -> Any: ...
1907
+ def restore_products(self, payload: CatalogAPIRestoreProductsBody, **kwargs: Any) -> Any: ...
1678
1908
  def update_product(self, id: Union[int, float], payload: CatalogAPIUpdateProductBody, **kwargs: Any) -> Any: ...
1679
1909
  def update_type(self, typeId: str, payload: CatalogAPIUpdateTypeBody, **kwargs: Any) -> Any: ...
1680
1910
 
@@ -1757,6 +1987,8 @@ class LotteryAPI:
1757
1987
  def validate(self, payload: LotteryAPIValidateBody, **kwargs: Any) -> Any: ...
1758
1988
 
1759
1989
  class MinecraftDeveloperAPI:
1990
+ messages: MinecraftMessagesAPI
1991
+ mobile_mods: MinecraftMobileModsAPI
1760
1992
  def apply_self_test(self, edition: str, projectId: str, payload: MinecraftDeveloperAPIApplySelfTestBody, **kwargs: Any) -> Any: ...
1761
1993
  def cancel_self_test(self, edition: str, projectId: str, query: MinecraftDeveloperAPICancelSelfTestQuery, **kwargs: Any) -> Any: ...
1762
1994
  def connect_session(self, payload: MinecraftDeveloperAPIConnectSessionBody, **kwargs: Any) -> Any: ...
@@ -1774,6 +2006,28 @@ class MinecraftDeveloperAPI:
1774
2006
  def revoke_review(self, edition: str, projectId: str, query: MinecraftDeveloperAPIRevokeReviewQuery, **kwargs: Any) -> Any: ...
1775
2007
  def submit_review(self, edition: str, projectId: str, payload: MinecraftDeveloperAPISubmitReviewBody, **kwargs: Any) -> Any: ...
1776
2008
 
2009
+ class MinecraftMessagesAPI:
2010
+ def detail(self, messageId: str, **kwargs: Any) -> Any: ...
2011
+ def list(self, query: Optional[MinecraftMessagesAPIListQuery] = ..., **kwargs: Any) -> Any: ...
2012
+ def mark_read(self, payload: MinecraftMessagesAPIMarkReadBody, **kwargs: Any) -> Any: ...
2013
+ def unread(self, **kwargs: Any) -> Any: ...
2014
+
2015
+ class MinecraftMobileModsAPI:
2016
+ def apply_self_test(self, id: str, payload: MinecraftMobileModsAPIApplySelfTestBody, **kwargs: Any) -> Any: ...
2017
+ def cancel_self_test(self, id: str, **kwargs: Any) -> Any: ...
2018
+ def create(self, payload: MinecraftMobileModsAPICreateBody, **kwargs: Any) -> Any: ...
2019
+ def detail(self, id: str, **kwargs: Any) -> Any: ...
2020
+ def feedback(self, id: str, **kwargs: Any) -> Any: ...
2021
+ def list(self, query: Optional[MinecraftMobileModsAPIListQuery] = ..., **kwargs: Any) -> Any: ...
2022
+ def metadata(self, **kwargs: Any) -> Any: ...
2023
+ def preview_asset(self, id: str, assetId: str, **kwargs: Any) -> Any: ...
2024
+ def preview_upload(self, uploadId: str, **kwargs: Any) -> Any: ...
2025
+ def revoke_review(self, id: str, **kwargs: Any) -> Any: ...
2026
+ def status(self, id: str, **kwargs: Any) -> Any: ...
2027
+ def submit_review(self, id: str, payload: MinecraftMobileModsAPISubmitReviewBody, **kwargs: Any) -> Any: ...
2028
+ def update(self, id: str, payload: MinecraftMobileModsAPIUpdateBody, **kwargs: Any) -> Any: ...
2029
+ def upload(self, payload: MinecraftMobileModsAPIUploadBody, **kwargs: Any) -> Any: ...
2030
+
1777
2031
  class OSSAPI:
1778
2032
  def get_ze_content(self, fileName: str, query: Optional[OSSAPIGetZeContentQuery] = ..., **kwargs: Any) -> Any: ...
1779
2033
  def get_zvs_reload_content(self, fileName: str, query: Optional[OSSAPIGetZvsReloadContentQuery] = ..., **kwargs: Any) -> Any: ...
@@ -1987,6 +2241,7 @@ class ClientOptions:
1987
2241
 
1988
2242
  class ECAPIClient:
1989
2243
  admin: AdminAPI
2244
+ announcements: AnnouncementsAPI
1990
2245
  audit: AuditAPI
1991
2246
  auth: AuthAPI
1992
2247
  catalog: CatalogAPI
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecapi-sdk
3
- Version: 3.7.2
3
+ Version: 3.7.4
4
4
  Summary: ECAPI SDK for Python
5
5
  Author: EaseCation
6
6
  License: MIT
File without changes
File without changes