remnawave-client 2.0.8__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.
Files changed (53) hide show
  1. remnawave_client-2.0.8/PKG-INFO +122 -0
  2. remnawave_client-2.0.8/README.md +112 -0
  3. remnawave_client-2.0.8/pyproject.toml +80 -0
  4. remnawave_client-2.0.8/src/remnawave/__init__.py +9 -0
  5. remnawave_client-2.0.8/src/remnawave/_generated/__init__.py +1 -0
  6. remnawave_client-2.0.8/src/remnawave/_generated/enums.py +68 -0
  7. remnawave_client-2.0.8/src/remnawave/_generated/groups.py +165 -0
  8. remnawave_client-2.0.8/src/remnawave/_generated/methods/__init__.py +1 -0
  9. remnawave_client-2.0.8/src/remnawave/_generated/methods/api_tokens_management.py +56 -0
  10. remnawave_client-2.0.8/src/remnawave/_generated/methods/auth.py +101 -0
  11. remnawave_client-2.0.8/src/remnawave/_generated/methods/bandwidth_stats.py +78 -0
  12. remnawave_client-2.0.8/src/remnawave/_generated/methods/config_profiles.py +131 -0
  13. remnawave_client-2.0.8/src/remnawave/_generated/methods/hosts.py +98 -0
  14. remnawave_client-2.0.8/src/remnawave/_generated/methods/hosts_bulk_actions.py +89 -0
  15. remnawave_client-2.0.8/src/remnawave/_generated/methods/hwid_user_devices.py +68 -0
  16. remnawave_client-2.0.8/src/remnawave/_generated/methods/infra_billing.py +238 -0
  17. remnawave_client-2.0.8/src/remnawave/_generated/methods/internal_squads.py +135 -0
  18. remnawave_client-2.0.8/src/remnawave/_generated/methods/keygen.py +28 -0
  19. remnawave_client-2.0.8/src/remnawave/_generated/methods/nodes.py +150 -0
  20. remnawave_client-2.0.8/src/remnawave/_generated/methods/subscription.py +125 -0
  21. remnawave_client-2.0.8/src/remnawave/_generated/methods/subscriptions.py +73 -0
  22. remnawave_client-2.0.8/src/remnawave/_generated/methods/subscriptions_settings.py +46 -0
  23. remnawave_client-2.0.8/src/remnawave/_generated/methods/subscriptions_template.py +51 -0
  24. remnawave_client-2.0.8/src/remnawave/_generated/methods/system.py +84 -0
  25. remnawave_client-2.0.8/src/remnawave/_generated/methods/users.py +287 -0
  26. remnawave_client-2.0.8/src/remnawave/_generated/methods/users_bulk_actions.py +155 -0
  27. remnawave_client-2.0.8/src/remnawave/_generated/methods/users_stats.py +42 -0
  28. remnawave_client-2.0.8/src/remnawave/_generated/models.py +1030 -0
  29. remnawave_client-2.0.8/src/remnawave/_generated/renames.py +19 -0
  30. remnawave_client-2.0.8/src/remnawave/_generated/webhooks.py +11 -0
  31. remnawave_client-2.0.8/src/remnawave/client.py +118 -0
  32. remnawave_client-2.0.8/src/remnawave/exceptions.py +67 -0
  33. remnawave_client-2.0.8/src/remnawave/execution/__init__.py +22 -0
  34. remnawave_client-2.0.8/src/remnawave/execution/auth.py +5 -0
  35. remnawave_client-2.0.8/src/remnawave/execution/backoff.py +74 -0
  36. remnawave_client-2.0.8/src/remnawave/execution/bearer.py +15 -0
  37. remnawave_client-2.0.8/src/remnawave/execution/executor.py +220 -0
  38. remnawave_client-2.0.8/src/remnawave/execution/group.py +51 -0
  39. remnawave_client-2.0.8/src/remnawave/execution/retry.py +14 -0
  40. remnawave_client-2.0.8/src/remnawave/http/__init__.py +18 -0
  41. remnawave_client-2.0.8/src/remnawave/http/httpx.py +60 -0
  42. remnawave_client-2.0.8/src/remnawave/http/transport.py +30 -0
  43. remnawave_client-2.0.8/src/remnawave/operations/__init__.py +20 -0
  44. remnawave_client-2.0.8/src/remnawave/operations/builder.py +79 -0
  45. remnawave_client-2.0.8/src/remnawave/operations/operation.py +33 -0
  46. remnawave_client-2.0.8/src/remnawave/operations/pagination.py +52 -0
  47. remnawave_client-2.0.8/src/remnawave/operations/parser.py +104 -0
  48. remnawave_client-2.0.8/src/remnawave/py.typed +0 -0
  49. remnawave_client-2.0.8/src/remnawave/serialization/__init__.py +13 -0
  50. remnawave_client-2.0.8/src/remnawave/serialization/adaptix.py +66 -0
  51. remnawave_client-2.0.8/src/remnawave/serialization/serializer.py +8 -0
  52. remnawave_client-2.0.8/src/remnawave/types/__init__.py +374 -0
  53. remnawave_client-2.0.8/src/remnawave/webhooks.py +58 -0
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: remnawave-client
3
+ Version: 2.0.8
4
+ Summary: Sync and async client for the Remnawave API
5
+ License-Expression: MIT
6
+ Requires-Dist: httpx>=0.28.1
7
+ Requires-Dist: adaptix>=3.0.0b12
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown
10
+
11
+ # remnawave-client
12
+
13
+ Sync and async client for the [Remnawave](https://docs.rw) API, generated from
14
+ the panel's OpenAPI specification.
15
+
16
+ - Every endpoint typed end to end — `mypy --strict` clean, `py.typed` shipped
17
+ - The same surface synchronously and asynchronously
18
+ - Listings walked lazily through `iter_*`
19
+ - Webhook events parsed and their signatures verified
20
+ - Transport, serializer, auth and retry policy are all replaceable
21
+
22
+ ```bash
23
+ pip install remnawave-client
24
+ ```
25
+
26
+ Requires Python 3.11 or newer.
27
+
28
+ ## Versions
29
+
30
+ The library version equals the API version it was generated from. A tag exists
31
+ for every minor release of the panel from 2.0 onwards, so pin the one matching
32
+ your deployment:
33
+
34
+ ```bash
35
+ pip install remnawave-client==3.0.0
36
+ ```
37
+
38
+ ```
39
+ 2.0.8 2.1.19 2.2.6 2.3.2 2.4.4 2.5.7 2.6.4
40
+ 2.7.4 2.8.1 3.0.0 3.1.0 3.2.3 3.3.2 3.4.3
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ ```python
46
+ from remnawave import Remnawave
47
+
48
+ with Remnawave("https://panel.example.com", token) as rw:
49
+ user = rw.users.get_user_by_username("zen")
50
+ print(user.username, user.status, user.expire_at)
51
+
52
+ for u in rw.users.iter_users():
53
+ print(u.username)
54
+ ```
55
+
56
+ The async client mirrors it:
57
+
58
+ ```python
59
+ import asyncio
60
+
61
+ from remnawave import AsyncRemnawave
62
+
63
+ async def main() -> None:
64
+ async with AsyncRemnawave("https://panel.example.com", token) as rw:
65
+ stats = rw.system.get_stats()
66
+ nodes = rw.nodes.get_nodes()
67
+ async for user in rw.users.iter_users():
68
+ print(user.username)
69
+
70
+ asyncio.run(main())
71
+ ```
72
+
73
+ More in [`examples/`](examples/): pagination, partial updates, error handling,
74
+ webhooks and swapping out the client's parts.
75
+
76
+ ## Errors
77
+
78
+ Everything the library raises inherits from `RemnawaveError`. Below it the
79
+ hierarchy splits by cause: `ApiError` for anything the panel answered with,
80
+ `TransportError` when the request never got a reply, `SerializationError` when
81
+ the payload did not match the schema.
82
+
83
+ ```python
84
+ from remnawave.exceptions import NotFoundError
85
+
86
+ try:
87
+ rw.users.get_user_by_id(42)
88
+ except NotFoundError as error:
89
+ print(error.status, error.error_code) # 404 'A025'
90
+ ```
91
+
92
+ `error_code` is the panel's own code and is more specific than the HTTP
93
+ status — branch on it when you need to tell cases apart.
94
+
95
+ ## Webhooks
96
+
97
+ ```python
98
+ from remnawave.webhooks import SIGNATURE_HEADER, WebhookReceiver
99
+
100
+ hooks = WebhookReceiver(secret=os.environ["WEBHOOK_SECRET_HEADER"])
101
+ event = hooks.receive(request.body, request.headers[SIGNATURE_HEADER])
102
+
103
+ if event.scope == "user":
104
+ print(event.event, event.data.username)
105
+ ```
106
+
107
+ Pass the raw request body: the signature covers those exact bytes, so
108
+ re-serialising parsed JSON breaks verification.
109
+
110
+ ## Regenerating
111
+
112
+ `src/remnawave/_generated/` is machine-written and must not be edited by hand.
113
+ To target another panel version, drop its specification into `specs/` and run:
114
+
115
+ ```bash
116
+ python -m tools.codegen 3.4.3
117
+ ```
118
+
119
+ Where the specification is wrong or awkward, `overlay.yaml` patches it before
120
+ generation: type names, forced field types, fields kept out of `repr`. Editing
121
+ the generated code directly would be lost on the next run; editing the vendored
122
+ specification would be lost on the next update.
@@ -0,0 +1,112 @@
1
+ # remnawave-client
2
+
3
+ Sync and async client for the [Remnawave](https://docs.rw) API, generated from
4
+ the panel's OpenAPI specification.
5
+
6
+ - Every endpoint typed end to end — `mypy --strict` clean, `py.typed` shipped
7
+ - The same surface synchronously and asynchronously
8
+ - Listings walked lazily through `iter_*`
9
+ - Webhook events parsed and their signatures verified
10
+ - Transport, serializer, auth and retry policy are all replaceable
11
+
12
+ ```bash
13
+ pip install remnawave-client
14
+ ```
15
+
16
+ Requires Python 3.11 or newer.
17
+
18
+ ## Versions
19
+
20
+ The library version equals the API version it was generated from. A tag exists
21
+ for every minor release of the panel from 2.0 onwards, so pin the one matching
22
+ your deployment:
23
+
24
+ ```bash
25
+ pip install remnawave-client==3.0.0
26
+ ```
27
+
28
+ ```
29
+ 2.0.8 2.1.19 2.2.6 2.3.2 2.4.4 2.5.7 2.6.4
30
+ 2.7.4 2.8.1 3.0.0 3.1.0 3.2.3 3.3.2 3.4.3
31
+ ```
32
+
33
+ ## Quick start
34
+
35
+ ```python
36
+ from remnawave import Remnawave
37
+
38
+ with Remnawave("https://panel.example.com", token) as rw:
39
+ user = rw.users.get_user_by_username("zen")
40
+ print(user.username, user.status, user.expire_at)
41
+
42
+ for u in rw.users.iter_users():
43
+ print(u.username)
44
+ ```
45
+
46
+ The async client mirrors it:
47
+
48
+ ```python
49
+ import asyncio
50
+
51
+ from remnawave import AsyncRemnawave
52
+
53
+ async def main() -> None:
54
+ async with AsyncRemnawave("https://panel.example.com", token) as rw:
55
+ stats = rw.system.get_stats()
56
+ nodes = rw.nodes.get_nodes()
57
+ async for user in rw.users.iter_users():
58
+ print(user.username)
59
+
60
+ asyncio.run(main())
61
+ ```
62
+
63
+ More in [`examples/`](examples/): pagination, partial updates, error handling,
64
+ webhooks and swapping out the client's parts.
65
+
66
+ ## Errors
67
+
68
+ Everything the library raises inherits from `RemnawaveError`. Below it the
69
+ hierarchy splits by cause: `ApiError` for anything the panel answered with,
70
+ `TransportError` when the request never got a reply, `SerializationError` when
71
+ the payload did not match the schema.
72
+
73
+ ```python
74
+ from remnawave.exceptions import NotFoundError
75
+
76
+ try:
77
+ rw.users.get_user_by_id(42)
78
+ except NotFoundError as error:
79
+ print(error.status, error.error_code) # 404 'A025'
80
+ ```
81
+
82
+ `error_code` is the panel's own code and is more specific than the HTTP
83
+ status — branch on it when you need to tell cases apart.
84
+
85
+ ## Webhooks
86
+
87
+ ```python
88
+ from remnawave.webhooks import SIGNATURE_HEADER, WebhookReceiver
89
+
90
+ hooks = WebhookReceiver(secret=os.environ["WEBHOOK_SECRET_HEADER"])
91
+ event = hooks.receive(request.body, request.headers[SIGNATURE_HEADER])
92
+
93
+ if event.scope == "user":
94
+ print(event.event, event.data.username)
95
+ ```
96
+
97
+ Pass the raw request body: the signature covers those exact bytes, so
98
+ re-serialising parsed JSON breaks verification.
99
+
100
+ ## Regenerating
101
+
102
+ `src/remnawave/_generated/` is machine-written and must not be edited by hand.
103
+ To target another panel version, drop its specification into `specs/` and run:
104
+
105
+ ```bash
106
+ python -m tools.codegen 3.4.3
107
+ ```
108
+
109
+ Where the specification is wrong or awkward, `overlay.yaml` patches it before
110
+ generation: type names, forced field types, fields kept out of `repr`. Editing
111
+ the generated code directly would be lost on the next run; editing the vendored
112
+ specification would be lost on the next update.
@@ -0,0 +1,80 @@
1
+ [project]
2
+ name = "remnawave-client"
3
+ version = "2.0.8"
4
+ description = "Sync and async client for the Remnawave API"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = "MIT"
8
+ dependencies = [
9
+ "httpx>=0.28.1",
10
+ "adaptix>=3.0.0b12",
11
+ ]
12
+
13
+ [dependency-groups]
14
+ dev = [
15
+ "pytest>=9.1.1",
16
+ "pytest-asyncio>=1.4.0",
17
+ "mypy>=2.3.1",
18
+ "ruff>=0.16.4",
19
+ "jinja2>=3.1",
20
+ "pyyaml>=6.0",
21
+ "types-PyYAML>=6.0",
22
+ "pytest-cov>=6.0",
23
+ ]
24
+
25
+ [build-system]
26
+ requires = ["uv_build>=0.9.21,<0.10.0"]
27
+ build-backend = "uv_build"
28
+
29
+ [tool.uv.build-backend]
30
+ # Пакет называется remnawave, а дистрибутив remnawave-client,
31
+ # поэтому имя модуля задаём явно.
32
+ module-name = "remnawave"
33
+
34
+ [tool.pytest.ini_options]
35
+ asyncio_mode = "auto"
36
+ addopts = "--cov --cov-report=term-missing --cov-fail-under=100"
37
+
38
+ [tool.coverage.run]
39
+ source = ["src/remnawave"]
40
+ omit = ["src/remnawave/_generated/*"]
41
+
42
+ [tool.coverage.report]
43
+ show_missing = true
44
+ exclude_lines = [
45
+ "pragma: no cover",
46
+ "if TYPE_CHECKING:",
47
+ ': \.\.\.$', # Protocols/overloads
48
+ ]
49
+
50
+ [tool.ruff]
51
+ line-length = 80
52
+ target-version = "py311"
53
+
54
+ [tool.ruff.lint]
55
+ select = ["ALL"]
56
+ ignore = [
57
+ "RUF001",
58
+ "RUF002",
59
+ "RUF003",
60
+ "CPY001",
61
+ "D",
62
+ "COM812",
63
+ "ASYNC109",
64
+ ]
65
+
66
+ [tool.ruff.lint.per-file-ignores]
67
+ "src/remnawave/_generated/**" = ["PLR0913", "ANN401", "S105"]
68
+ "examples/**" = ["T201", "INP001"]
69
+ "src/remnawave/types/**" = ["E501"]
70
+ "tests/**" = [
71
+ "S101",
72
+ "PLR2004",
73
+ "EM101",
74
+ "TRY003",
75
+ ]
76
+
77
+ [tool.mypy]
78
+ python_version = "3.11"
79
+ strict = true
80
+ files = ["src", "tests", "tools", "examples"]
@@ -0,0 +1,9 @@
1
+ from remnawave.client import (
2
+ AsyncRemnawave as AsyncRemnawave,
3
+ )
4
+ from remnawave.client import (
5
+ Remnawave as Remnawave,
6
+ )
7
+
8
+ __version__ = "2.0.8"
9
+ API_VERSION = "2.0.8"
@@ -0,0 +1 @@
1
+ # @generated by tools/codegen -- do not edit
@@ -0,0 +1,68 @@
1
+ # @generated by tools/codegen -- do not edit
2
+ from enum import StrEnum
3
+
4
+
5
+ class OAuth2CallbackRequestProvider(StrEnum):
6
+ GITHUB = "github"
7
+ POCKETID = "pocketid"
8
+ YANDEX = "yandex"
9
+
10
+
11
+ class UserStatus(StrEnum):
12
+ ACTIVE = "ACTIVE"
13
+ DISABLED = "DISABLED"
14
+ LIMITED = "LIMITED"
15
+ EXPIRED = "EXPIRED"
16
+
17
+
18
+ class UserTrafficLimitStrategy(StrEnum):
19
+ NO_RESET = "NO_RESET"
20
+ DAY = "DAY"
21
+ WEEK = "WEEK"
22
+ MONTH = "MONTH"
23
+
24
+
25
+ class SubscriptionControllerGetSubscriptionByClientType(StrEnum):
26
+ STASH = "stash"
27
+ SINGBOX = "singbox"
28
+ SINGBOX_LEGACY = "singbox-legacy"
29
+ MIHOMO = "mihomo"
30
+ JSON = "json"
31
+ V2RAY_JSON = "v2ray-json"
32
+ CLASH = "clash"
33
+
34
+
35
+ class TemplateTemplateType(StrEnum):
36
+ STASH = "STASH"
37
+ SINGBOX = "SINGBOX"
38
+ SINGBOX_LEGACY = "SINGBOX_LEGACY"
39
+ MIHOMO = "MIHOMO"
40
+ XRAY_JSON = "XRAY_JSON"
41
+ CLASH = "CLASH"
42
+
43
+
44
+ class HostSecurityLayer(StrEnum):
45
+ DEFAULT = "DEFAULT"
46
+ TLS = "TLS"
47
+ NONE = "NONE"
48
+
49
+
50
+ class CreateHostRequestAlpn(StrEnum):
51
+ H3 = "h3"
52
+ H2 = "h2"
53
+ HTTP_1_1 = "http/1.1"
54
+ H2_HTTP_1_1 = "h2,http/1.1"
55
+ H3_H2_HTTP_1_1 = "h3,h2,http/1.1"
56
+ H3_H2 = "h3,h2"
57
+
58
+
59
+ class CreateHostRequestFingerprint(StrEnum):
60
+ CHROME = "chrome"
61
+ FIREFOX = "firefox"
62
+ SAFARI = "safari"
63
+ IOS = "ios"
64
+ ANDROID = "android"
65
+ EDGE = "edge"
66
+ QQ = "qq"
67
+ RANDOM = "random"
68
+ RANDOMIZED = "randomized"
@@ -0,0 +1,165 @@
1
+ # @generated by tools/codegen -- do not edit
2
+
3
+ from remnawave._generated.methods.api_tokens_management import (
4
+ ApiTokensManagementApi,
5
+ AsyncApiTokensManagementApi,
6
+ )
7
+ from remnawave._generated.methods.auth import (
8
+ AsyncAuthApi,
9
+ AuthApi,
10
+ )
11
+ from remnawave._generated.methods.bandwidth_stats import (
12
+ AsyncBandwidthStatsApi,
13
+ BandwidthStatsApi,
14
+ )
15
+ from remnawave._generated.methods.config_profiles import (
16
+ AsyncConfigProfilesApi,
17
+ ConfigProfilesApi,
18
+ )
19
+ from remnawave._generated.methods.hosts import (
20
+ AsyncHostsApi,
21
+ HostsApi,
22
+ )
23
+ from remnawave._generated.methods.hosts_bulk_actions import (
24
+ AsyncHostsBulkActionsApi,
25
+ HostsBulkActionsApi,
26
+ )
27
+ from remnawave._generated.methods.hwid_user_devices import (
28
+ AsyncHwidUserDevicesApi,
29
+ HwidUserDevicesApi,
30
+ )
31
+ from remnawave._generated.methods.infra_billing import (
32
+ AsyncInfraBillingApi,
33
+ InfraBillingApi,
34
+ )
35
+ from remnawave._generated.methods.internal_squads import (
36
+ AsyncInternalSquadsApi,
37
+ InternalSquadsApi,
38
+ )
39
+ from remnawave._generated.methods.keygen import (
40
+ AsyncKeygenApi,
41
+ KeygenApi,
42
+ )
43
+ from remnawave._generated.methods.nodes import (
44
+ AsyncNodesApi,
45
+ NodesApi,
46
+ )
47
+ from remnawave._generated.methods.subscription import (
48
+ AsyncSubscriptionApi,
49
+ SubscriptionApi,
50
+ )
51
+ from remnawave._generated.methods.subscriptions import (
52
+ AsyncSubscriptionsApi,
53
+ SubscriptionsApi,
54
+ )
55
+ from remnawave._generated.methods.subscriptions_settings import (
56
+ AsyncSubscriptionsSettingsApi,
57
+ SubscriptionsSettingsApi,
58
+ )
59
+ from remnawave._generated.methods.subscriptions_template import (
60
+ AsyncSubscriptionsTemplateApi,
61
+ SubscriptionsTemplateApi,
62
+ )
63
+ from remnawave._generated.methods.system import (
64
+ AsyncSystemApi,
65
+ SystemApi,
66
+ )
67
+ from remnawave._generated.methods.users import (
68
+ AsyncUsersApi,
69
+ UsersApi,
70
+ )
71
+ from remnawave._generated.methods.users_bulk_actions import (
72
+ AsyncUsersBulkActionsApi,
73
+ UsersBulkActionsApi,
74
+ )
75
+ from remnawave._generated.methods.users_stats import (
76
+ AsyncUsersStatsApi,
77
+ UsersStatsApi,
78
+ )
79
+ from remnawave.execution import AsyncExecutor, SyncExecutor
80
+
81
+
82
+ class SyncGroups:
83
+ api_tokens_management: ApiTokensManagementApi
84
+ auth: AuthApi
85
+ bandwidth_stats: BandwidthStatsApi
86
+ config_profiles: ConfigProfilesApi
87
+ hosts: HostsApi
88
+ hosts_bulk_actions: HostsBulkActionsApi
89
+ hwid_user_devices: HwidUserDevicesApi
90
+ infra_billing: InfraBillingApi
91
+ internal_squads: InternalSquadsApi
92
+ keygen: KeygenApi
93
+ nodes: NodesApi
94
+ subscription: SubscriptionApi
95
+ subscriptions: SubscriptionsApi
96
+ subscriptions_settings: SubscriptionsSettingsApi
97
+ subscriptions_template: SubscriptionsTemplateApi
98
+ system: SystemApi
99
+ users: UsersApi
100
+ users_bulk_actions: UsersBulkActionsApi
101
+ users_stats: UsersStatsApi
102
+
103
+ def _attach(self, executor: SyncExecutor) -> None:
104
+ self.api_tokens_management = ApiTokensManagementApi(executor)
105
+ self.auth = AuthApi(executor)
106
+ self.bandwidth_stats = BandwidthStatsApi(executor)
107
+ self.config_profiles = ConfigProfilesApi(executor)
108
+ self.hosts = HostsApi(executor)
109
+ self.hosts_bulk_actions = HostsBulkActionsApi(executor)
110
+ self.hwid_user_devices = HwidUserDevicesApi(executor)
111
+ self.infra_billing = InfraBillingApi(executor)
112
+ self.internal_squads = InternalSquadsApi(executor)
113
+ self.keygen = KeygenApi(executor)
114
+ self.nodes = NodesApi(executor)
115
+ self.subscription = SubscriptionApi(executor)
116
+ self.subscriptions = SubscriptionsApi(executor)
117
+ self.subscriptions_settings = SubscriptionsSettingsApi(executor)
118
+ self.subscriptions_template = SubscriptionsTemplateApi(executor)
119
+ self.system = SystemApi(executor)
120
+ self.users = UsersApi(executor)
121
+ self.users_bulk_actions = UsersBulkActionsApi(executor)
122
+ self.users_stats = UsersStatsApi(executor)
123
+
124
+
125
+ class AsyncGroups:
126
+ api_tokens_management: AsyncApiTokensManagementApi
127
+ auth: AsyncAuthApi
128
+ bandwidth_stats: AsyncBandwidthStatsApi
129
+ config_profiles: AsyncConfigProfilesApi
130
+ hosts: AsyncHostsApi
131
+ hosts_bulk_actions: AsyncHostsBulkActionsApi
132
+ hwid_user_devices: AsyncHwidUserDevicesApi
133
+ infra_billing: AsyncInfraBillingApi
134
+ internal_squads: AsyncInternalSquadsApi
135
+ keygen: AsyncKeygenApi
136
+ nodes: AsyncNodesApi
137
+ subscription: AsyncSubscriptionApi
138
+ subscriptions: AsyncSubscriptionsApi
139
+ subscriptions_settings: AsyncSubscriptionsSettingsApi
140
+ subscriptions_template: AsyncSubscriptionsTemplateApi
141
+ system: AsyncSystemApi
142
+ users: AsyncUsersApi
143
+ users_bulk_actions: AsyncUsersBulkActionsApi
144
+ users_stats: AsyncUsersStatsApi
145
+
146
+ def _attach(self, executor: AsyncExecutor) -> None:
147
+ self.api_tokens_management = AsyncApiTokensManagementApi(executor)
148
+ self.auth = AsyncAuthApi(executor)
149
+ self.bandwidth_stats = AsyncBandwidthStatsApi(executor)
150
+ self.config_profiles = AsyncConfigProfilesApi(executor)
151
+ self.hosts = AsyncHostsApi(executor)
152
+ self.hosts_bulk_actions = AsyncHostsBulkActionsApi(executor)
153
+ self.hwid_user_devices = AsyncHwidUserDevicesApi(executor)
154
+ self.infra_billing = AsyncInfraBillingApi(executor)
155
+ self.internal_squads = AsyncInternalSquadsApi(executor)
156
+ self.keygen = AsyncKeygenApi(executor)
157
+ self.nodes = AsyncNodesApi(executor)
158
+ self.subscription = AsyncSubscriptionApi(executor)
159
+ self.subscriptions = AsyncSubscriptionsApi(executor)
160
+ self.subscriptions_settings = AsyncSubscriptionsSettingsApi(executor)
161
+ self.subscriptions_template = AsyncSubscriptionsTemplateApi(executor)
162
+ self.system = AsyncSystemApi(executor)
163
+ self.users = AsyncUsersApi(executor)
164
+ self.users_bulk_actions = AsyncUsersBulkActionsApi(executor)
165
+ self.users_stats = AsyncUsersStatsApi(executor)
@@ -0,0 +1 @@
1
+ # @generated by tools/codegen -- do not edit
@@ -0,0 +1,56 @@
1
+ # @generated by tools/codegen -- do not edit
2
+ """API Tokens Management."""
3
+
4
+ from remnawave._generated.models import (
5
+ ApiToken,
6
+ CreateApiTokenRequest,
7
+ FindAllApiTokens,
8
+ )
9
+ from remnawave.execution import AsyncGroup, SyncGroup
10
+ from remnawave.operations import (
11
+ Operation,
12
+ )
13
+
14
+ CREATE: Operation[ApiToken] = Operation(
15
+ "POST",
16
+ "/api/tokens",
17
+ ApiToken,
18
+ )
19
+ FIND_ALL: Operation[FindAllApiTokens] = Operation(
20
+ "GET",
21
+ "/api/tokens",
22
+ FindAllApiTokens,
23
+ )
24
+ DELETE: Operation[bool] = Operation(
25
+ "DELETE",
26
+ "/api/tokens/{uuid}",
27
+ bool,
28
+ )
29
+
30
+
31
+ class ApiTokensManagementApi(SyncGroup):
32
+ def create(self, body: CreateApiTokenRequest) -> ApiToken:
33
+ """Create a new API token."""
34
+ return self._executor.execute(CREATE, body=body)
35
+
36
+ def find_all(self) -> FindAllApiTokens:
37
+ """Get all API tokens."""
38
+ return self._executor.execute(FIND_ALL)
39
+
40
+ def delete(self, uuid: str) -> bool:
41
+ """Delete an API token by UUID."""
42
+ return self._executor.execute(DELETE, path={"uuid": uuid})
43
+
44
+
45
+ class AsyncApiTokensManagementApi(AsyncGroup):
46
+ async def create(self, body: CreateApiTokenRequest) -> ApiToken:
47
+ """Create a new API token."""
48
+ return await self._executor.execute(CREATE, body=body)
49
+
50
+ async def find_all(self) -> FindAllApiTokens:
51
+ """Get all API tokens."""
52
+ return await self._executor.execute(FIND_ALL)
53
+
54
+ async def delete(self, uuid: str) -> bool:
55
+ """Delete an API token by UUID."""
56
+ return await self._executor.execute(DELETE, path={"uuid": uuid})