remnawave-api 1.0.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.
- remnawave_api-1.0.0/LICENSE +21 -0
- remnawave_api-1.0.0/PKG-INFO +94 -0
- remnawave_api-1.0.0/README.md +77 -0
- remnawave_api-1.0.0/pyproject.toml +34 -0
- remnawave_api-1.0.0/remnawave_api/.DS_Store +0 -0
- remnawave_api-1.0.0/remnawave_api/__init__.py +90 -0
- remnawave_api-1.0.0/remnawave_api/controllers/__init__.py +37 -0
- remnawave_api-1.0.0/remnawave_api/controllers/api_tokens_management.py +33 -0
- remnawave_api-1.0.0/remnawave_api/controllers/auth.py +37 -0
- remnawave_api-1.0.0/remnawave_api/controllers/bandwidthstats.py +17 -0
- remnawave_api-1.0.0/remnawave_api/controllers/hosts.py +64 -0
- remnawave_api-1.0.0/remnawave_api/controllers/hosts_bulk_actions.py +60 -0
- remnawave_api-1.0.0/remnawave_api/controllers/inbounds.py +18 -0
- remnawave_api-1.0.0/remnawave_api/controllers/inbounds_bulk_actions.py +50 -0
- remnawave_api-1.0.0/remnawave_api/controllers/keygen.py +11 -0
- remnawave_api-1.0.0/remnawave_api/controllers/nodes.py +95 -0
- remnawave_api-1.0.0/remnawave_api/controllers/subscription.py +54 -0
- remnawave_api-1.0.0/remnawave_api/controllers/subscriptions_settings.py +29 -0
- remnawave_api-1.0.0/remnawave_api/controllers/subscriptions_template.py +31 -0
- remnawave_api-1.0.0/remnawave_api/controllers/system.py +29 -0
- remnawave_api-1.0.0/remnawave_api/controllers/users.py +131 -0
- remnawave_api-1.0.0/remnawave_api/controllers/users_bulk_actions.py +89 -0
- remnawave_api-1.0.0/remnawave_api/controllers/users_stats.py +21 -0
- remnawave_api-1.0.0/remnawave_api/controllers/xray_config.py +23 -0
- remnawave_api-1.0.0/remnawave_api/enums/__init__.py +18 -0
- remnawave_api-1.0.0/remnawave_api/enums/alpn.py +10 -0
- remnawave_api-1.0.0/remnawave_api/enums/client_type.py +10 -0
- remnawave_api-1.0.0/remnawave_api/enums/error_code.py +80 -0
- remnawave_api-1.0.0/remnawave_api/enums/fingerprint.py +13 -0
- remnawave_api-1.0.0/remnawave_api/enums/security_layer.py +7 -0
- remnawave_api-1.0.0/remnawave_api/enums/template_type.py +10 -0
- remnawave_api-1.0.0/remnawave_api/enums/users.py +15 -0
- remnawave_api-1.0.0/remnawave_api/exceptions/__init__.py +23 -0
- remnawave_api-1.0.0/remnawave_api/exceptions/general.py +61 -0
- remnawave_api-1.0.0/remnawave_api/exceptions/handler.py +130 -0
- remnawave_api-1.0.0/remnawave_api/models/__init__.py +167 -0
- remnawave_api-1.0.0/remnawave_api/models/api_tokens_management.py +10 -0
- remnawave_api-1.0.0/remnawave_api/models/auth.py +26 -0
- remnawave_api-1.0.0/remnawave_api/models/bandwidthstats.py +21 -0
- remnawave_api-1.0.0/remnawave_api/models/hosts.py +91 -0
- remnawave_api-1.0.0/remnawave_api/models/hosts_bulk_actions.py +31 -0
- remnawave_api-1.0.0/remnawave_api/models/inbounds.py +38 -0
- remnawave_api-1.0.0/remnawave_api/models/inbounds_bulk_actions.py +17 -0
- remnawave_api-1.0.0/remnawave_api/models/keygen.py +5 -0
- remnawave_api-1.0.0/remnawave_api/models/nodes.py +113 -0
- remnawave_api-1.0.0/remnawave_api/models/subscription.py +26 -0
- remnawave_api-1.0.0/remnawave_api/models/subscriptions_settings.py +57 -0
- remnawave_api-1.0.0/remnawave_api/models/subscriptions_template.py +21 -0
- remnawave_api-1.0.0/remnawave_api/models/system.py +70 -0
- remnawave_api-1.0.0/remnawave_api/models/users.py +131 -0
- remnawave_api-1.0.0/remnawave_api/models/users_bulk_actions.py +52 -0
- remnawave_api-1.0.0/remnawave_api/models/users_stats.py +17 -0
- remnawave_api-1.0.0/remnawave_api/models/xray_config.py +5 -0
- remnawave_api-1.0.0/remnawave_api/rapid/__init__.py +5 -0
- remnawave_api-1.0.0/remnawave_api/rapid/annotations.py +5 -0
- remnawave_api-1.0.0/remnawave_api/rapid/client.py +210 -0
- remnawave_api-1.0.0/remnawave_api/rapid/decorators.py +54 -0
- remnawave_api-1.0.0/remnawave_api/utils/__init__.py +0 -0
- remnawave_api-1.0.0/remnawave_api/utils/serializer.py +7 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 sm1ky
|
|
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,94 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: remnawave_api
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python SDK for interacting with the Remnawave API.
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: sm1ky
|
|
7
|
+
Author-email: sm1ky@forestsnet.com
|
|
8
|
+
Requires-Python: >=3.11,<4.0
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Requires-Dist: orjson (>=3.10.15,<4.0.0)
|
|
15
|
+
Requires-Dist: rapid-api-client (==0.6.0)
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# Remnawave SDK
|
|
19
|
+
|
|
20
|
+
A Python SDK client for interacting with the [Remnawave API](https://remna.st).
|
|
21
|
+
This library simplifies working with the API by providing convenient controllers, Pydantic models for requests and responses, and fast serialization with `orjson`.
|
|
22
|
+
|
|
23
|
+
## ✨ Key Features
|
|
24
|
+
|
|
25
|
+
- **Controller-based design**: Split functionality into separate controllers for flexibility. Use only what you need!
|
|
26
|
+
- **Pydantic models**: Strongly-typed requests and responses for better reliability.
|
|
27
|
+
- **Fast serialization**: Powered by `orjson` for efficient JSON handling.
|
|
28
|
+
- **Modular usage**: Import individual controllers or the full SDK as needed.
|
|
29
|
+
|
|
30
|
+
## 📦 Installation
|
|
31
|
+
|
|
32
|
+
Currently, the SDK is available via Git. You can install it directly using `pip`:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install git+https://github.com/sm1ky/remnawave_api.git
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### Dependencies
|
|
41
|
+
- `orjson` (>=3.10.15, <4.0.0)
|
|
42
|
+
- `rapid-api-client` (==0.6.0)
|
|
43
|
+
|
|
44
|
+
## 🚀 Usage
|
|
45
|
+
|
|
46
|
+
Here’s a quick example to get you started:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import os
|
|
50
|
+
import asyncio
|
|
51
|
+
|
|
52
|
+
from remnawave import RemnawaveSDK
|
|
53
|
+
from remnawave.models import UsersResponseDto, UserResponseDto
|
|
54
|
+
|
|
55
|
+
async def main():
|
|
56
|
+
# URL to your panel (ex. https://vpn.com or http://127.0.0.1:3000)
|
|
57
|
+
base_url: str = os.getenv("REMNAWAVE_BASE_URL")
|
|
58
|
+
# Bearer Token from panel (section: API Tokens)
|
|
59
|
+
token: str = os.getenv("REMNAWAVE_TOKEN")
|
|
60
|
+
|
|
61
|
+
# Initialize the SDK
|
|
62
|
+
remnawave = RemnawaveSDK(base_url=base_url, token=token)
|
|
63
|
+
|
|
64
|
+
# Fetch all users
|
|
65
|
+
response: UsersResponseDto = await remnawave.users.get_all_users_v2()
|
|
66
|
+
total_users: int = response.total
|
|
67
|
+
users: list[UserResponseDto] = response.users
|
|
68
|
+
print("Total users: ", total_users)
|
|
69
|
+
print("List of users: ", users)
|
|
70
|
+
|
|
71
|
+
# Disable a specific user
|
|
72
|
+
test_uuid: str = "e4d3f3d2-4f4f-4f4f-4f4f-4f4f4f4f4f4f"
|
|
73
|
+
disabled_user: UserResponseDto = await remnawave.users.disable_user(test_uuid)
|
|
74
|
+
print("Disabled user: ", disabled_user)
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
asyncio.run(main())
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🧪 Running Tests
|
|
83
|
+
|
|
84
|
+
To run the test suite, use Poetry:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
poetry run pytest
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## ❤️ About
|
|
91
|
+
|
|
92
|
+
This SDK was originally developed by [@kesevone](https://github.com/kesevone) for integration with Remnawave's API.
|
|
93
|
+
|
|
94
|
+
Maintained and extended by [@sm1ky](https://github.com/sm1ky).
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Remnawave SDK
|
|
2
|
+
|
|
3
|
+
A Python SDK client for interacting with the [Remnawave API](https://remna.st).
|
|
4
|
+
This library simplifies working with the API by providing convenient controllers, Pydantic models for requests and responses, and fast serialization with `orjson`.
|
|
5
|
+
|
|
6
|
+
## ✨ Key Features
|
|
7
|
+
|
|
8
|
+
- **Controller-based design**: Split functionality into separate controllers for flexibility. Use only what you need!
|
|
9
|
+
- **Pydantic models**: Strongly-typed requests and responses for better reliability.
|
|
10
|
+
- **Fast serialization**: Powered by `orjson` for efficient JSON handling.
|
|
11
|
+
- **Modular usage**: Import individual controllers or the full SDK as needed.
|
|
12
|
+
|
|
13
|
+
## 📦 Installation
|
|
14
|
+
|
|
15
|
+
Currently, the SDK is available via Git. You can install it directly using `pip`:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install git+https://github.com/sm1ky/remnawave_api.git
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
- `orjson` (>=3.10.15, <4.0.0)
|
|
25
|
+
- `rapid-api-client` (==0.6.0)
|
|
26
|
+
|
|
27
|
+
## 🚀 Usage
|
|
28
|
+
|
|
29
|
+
Here’s a quick example to get you started:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import os
|
|
33
|
+
import asyncio
|
|
34
|
+
|
|
35
|
+
from remnawave import RemnawaveSDK
|
|
36
|
+
from remnawave.models import UsersResponseDto, UserResponseDto
|
|
37
|
+
|
|
38
|
+
async def main():
|
|
39
|
+
# URL to your panel (ex. https://vpn.com or http://127.0.0.1:3000)
|
|
40
|
+
base_url: str = os.getenv("REMNAWAVE_BASE_URL")
|
|
41
|
+
# Bearer Token from panel (section: API Tokens)
|
|
42
|
+
token: str = os.getenv("REMNAWAVE_TOKEN")
|
|
43
|
+
|
|
44
|
+
# Initialize the SDK
|
|
45
|
+
remnawave = RemnawaveSDK(base_url=base_url, token=token)
|
|
46
|
+
|
|
47
|
+
# Fetch all users
|
|
48
|
+
response: UsersResponseDto = await remnawave.users.get_all_users_v2()
|
|
49
|
+
total_users: int = response.total
|
|
50
|
+
users: list[UserResponseDto] = response.users
|
|
51
|
+
print("Total users: ", total_users)
|
|
52
|
+
print("List of users: ", users)
|
|
53
|
+
|
|
54
|
+
# Disable a specific user
|
|
55
|
+
test_uuid: str = "e4d3f3d2-4f4f-4f4f-4f4f-4f4f4f4f4f4f"
|
|
56
|
+
disabled_user: UserResponseDto = await remnawave.users.disable_user(test_uuid)
|
|
57
|
+
print("Disabled user: ", disabled_user)
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
asyncio.run(main())
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 🧪 Running Tests
|
|
66
|
+
|
|
67
|
+
To run the test suite, use Poetry:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
poetry run pytest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## ❤️ About
|
|
74
|
+
|
|
75
|
+
This SDK was originally developed by [@kesevone](https://github.com/kesevone) for integration with Remnawave's API.
|
|
76
|
+
|
|
77
|
+
Maintained and extended by [@sm1ky](https://github.com/sm1ky).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "remnawave_api"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "A Python SDK for interacting with the Remnawave API."
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "sm1ky",email = "sm1ky@forestsnet.com"}
|
|
7
|
+
]
|
|
8
|
+
license = { text = "MIT" }
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11,<4.0"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"rapid-api-client (==0.6.0)",
|
|
13
|
+
"orjson (>=3.10.15,<4.0.0)",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[tool.poetry.group.test.dependencies]
|
|
17
|
+
ruff = "^0.4.4"
|
|
18
|
+
black = "^24.4.2"
|
|
19
|
+
pytest = ">=8.0"
|
|
20
|
+
pytest-asyncio = "^0.25.3"
|
|
21
|
+
pytest-mock = ">=3.9"
|
|
22
|
+
httpx = ">=0.27.2,<0.28.0"
|
|
23
|
+
python-dotenv = "^1.0.1"
|
|
24
|
+
pytz = "^2025.1"
|
|
25
|
+
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
addopts = [ "-n", "logical", "-ra", "--strict-config", "--strict-markers" ]
|
|
28
|
+
testpaths = ["tests"]
|
|
29
|
+
log_cli_level = "INFO"
|
|
30
|
+
xfail_strict = true
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
34
|
+
build-backend = "poetry.core.masonry.api"
|
|
Binary file
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from remnawave_api.controllers import (
|
|
7
|
+
APITokensManagementController,
|
|
8
|
+
AuthController,
|
|
9
|
+
BandWidthStatsController,
|
|
10
|
+
HostsBulkActionsController,
|
|
11
|
+
HostsController,
|
|
12
|
+
InboundsBulkActionsController,
|
|
13
|
+
InboundsController,
|
|
14
|
+
KeygenController,
|
|
15
|
+
NodesController,
|
|
16
|
+
SubscriptionController,
|
|
17
|
+
SubscriptionsSettingsController,
|
|
18
|
+
SubscriptionsTemplateController,
|
|
19
|
+
SystemController,
|
|
20
|
+
UsersBulkActionsController,
|
|
21
|
+
UsersController,
|
|
22
|
+
UsersStatsController,
|
|
23
|
+
XrayConfigController,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class RemnawaveSDK:
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
client: Optional[httpx.AsyncClient] = None,
|
|
31
|
+
base_url: Optional[str] = None,
|
|
32
|
+
token: Optional[str] = None,
|
|
33
|
+
):
|
|
34
|
+
self._client = client
|
|
35
|
+
self._token = token
|
|
36
|
+
self.base_url = base_url
|
|
37
|
+
|
|
38
|
+
self._validate_params()
|
|
39
|
+
|
|
40
|
+
if self._client is None:
|
|
41
|
+
self._client = self._prepare_client()
|
|
42
|
+
|
|
43
|
+
self.api_tokens_management = APITokensManagementController(self._client)
|
|
44
|
+
self.auth = AuthController(self._client)
|
|
45
|
+
self.bandwidthstats = BandWidthStatsController(self._client)
|
|
46
|
+
self.hosts = HostsController(self._client)
|
|
47
|
+
self.hosts_bulk_actions = HostsBulkActionsController(self._client)
|
|
48
|
+
self.inbounds = InboundsController(self._client)
|
|
49
|
+
self.inbounds_bulk_actions = InboundsBulkActionsController(self._client)
|
|
50
|
+
self.keygen = KeygenController(self._client)
|
|
51
|
+
self.nodes = NodesController(self._client)
|
|
52
|
+
self.subscription = SubscriptionController(self._client)
|
|
53
|
+
self.subscriptions_settings = SubscriptionsSettingsController(self._client)
|
|
54
|
+
self.subscriptions_template = SubscriptionsTemplateController(self._client)
|
|
55
|
+
self.system = SystemController(self._client)
|
|
56
|
+
self.users = UsersController(self._client)
|
|
57
|
+
self.users_bulk_actions = UsersBulkActionsController(self._client)
|
|
58
|
+
self.users_stats = UsersStatsController(self._client)
|
|
59
|
+
self.xray_config = XrayConfigController(self._client)
|
|
60
|
+
|
|
61
|
+
def _validate_params(self) -> None:
|
|
62
|
+
if self._client is None:
|
|
63
|
+
if self.base_url is None or self._token is None:
|
|
64
|
+
raise ValueError(
|
|
65
|
+
"base_url and token must be provided if client is not provided"
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
if self.base_url is not None or self._token is not None:
|
|
69
|
+
logging.warning(
|
|
70
|
+
"base_url and token will be ignored if client is provided"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def _prepare_client(self) -> httpx.AsyncClient:
|
|
74
|
+
return httpx.AsyncClient(
|
|
75
|
+
base_url=self._prepare_url(), headers=self._prepare_headers()
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def _prepare_headers(self) -> dict:
|
|
79
|
+
if not self._token.startswith("Bearer "):
|
|
80
|
+
self._token = "Bearer " + self._token
|
|
81
|
+
return {"Authorization": self._token}
|
|
82
|
+
|
|
83
|
+
def _prepare_url(self) -> str:
|
|
84
|
+
if self.base_url.endswith("/"):
|
|
85
|
+
self.base_url[:-1]
|
|
86
|
+
|
|
87
|
+
if not self.base_url.endswith("/api"):
|
|
88
|
+
self.base_url += "/api"
|
|
89
|
+
|
|
90
|
+
return self.base_url
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from .api_tokens_management import APITokensManagementController
|
|
2
|
+
from .auth import AuthController
|
|
3
|
+
from .bandwidthstats import BandWidthStatsController
|
|
4
|
+
from .hosts import HostsController
|
|
5
|
+
from .hosts_bulk_actions import HostsBulkActionsController
|
|
6
|
+
from .inbounds import InboundsController
|
|
7
|
+
from .inbounds_bulk_actions import InboundsBulkActionsController
|
|
8
|
+
from .keygen import KeygenController
|
|
9
|
+
from .nodes import NodesController
|
|
10
|
+
from .subscription import SubscriptionController
|
|
11
|
+
from .subscriptions_settings import SubscriptionsSettingsController
|
|
12
|
+
from .subscriptions_template import SubscriptionsTemplateController
|
|
13
|
+
from .system import SystemController
|
|
14
|
+
from .users import UsersController
|
|
15
|
+
from .users_bulk_actions import UsersBulkActionsController
|
|
16
|
+
from .users_stats import UsersStatsController
|
|
17
|
+
from .xray_config import XrayConfigController
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"APITokensManagementController",
|
|
21
|
+
"AuthController",
|
|
22
|
+
"BandWidthStatsController",
|
|
23
|
+
"HostsController",
|
|
24
|
+
"HostsBulkActionsController",
|
|
25
|
+
"InboundsController",
|
|
26
|
+
"InboundsBulkActionsController",
|
|
27
|
+
"KeygenController",
|
|
28
|
+
"NodesController",
|
|
29
|
+
"SubscriptionController",
|
|
30
|
+
"SubscriptionsSettingsController",
|
|
31
|
+
"SubscriptionsTemplateController",
|
|
32
|
+
"SystemController",
|
|
33
|
+
"UsersController",
|
|
34
|
+
"UsersBulkActionsController",
|
|
35
|
+
"UsersStatsController",
|
|
36
|
+
"XrayConfigController",
|
|
37
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from httpx import Response
|
|
4
|
+
from rapid_api_client import Path
|
|
5
|
+
from rapid_api_client.annotations import PydanticBody
|
|
6
|
+
|
|
7
|
+
from remnawave_api.models import CreateApiTokenRequestDto
|
|
8
|
+
from remnawave_api.rapid import BaseController, delete, get, post
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class APITokensManagementController(BaseController):
|
|
12
|
+
@post("/tokens/create", response_class=Response)
|
|
13
|
+
async def create(
|
|
14
|
+
self,
|
|
15
|
+
body: Annotated[CreateApiTokenRequestDto, PydanticBody()],
|
|
16
|
+
) -> Response:
|
|
17
|
+
"""Create new API token"""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
@delete("/tokens/delete/{uuid}", response_class=Response)
|
|
21
|
+
async def delete(
|
|
22
|
+
self,
|
|
23
|
+
uuid: Annotated[str, Path(description="UUID of the API token")],
|
|
24
|
+
) -> Response:
|
|
25
|
+
"""Delete API token"""
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
@get("/tokens", response_class=Response)
|
|
29
|
+
async def find_all(
|
|
30
|
+
self,
|
|
31
|
+
) -> Response:
|
|
32
|
+
"""Get all API tokens"""
|
|
33
|
+
...
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from rapid_api_client.annotations import PydanticBody
|
|
4
|
+
|
|
5
|
+
from remnawave_api.models import (
|
|
6
|
+
LoginRequestDto,
|
|
7
|
+
LoginResponseDto,
|
|
8
|
+
RegisterRequestDto,
|
|
9
|
+
RegisterResponseDto,
|
|
10
|
+
StatusResponseDto,
|
|
11
|
+
)
|
|
12
|
+
from remnawave_api.rapid import BaseController, get, post
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AuthController(BaseController):
|
|
16
|
+
@post("/auth/login", response_class=LoginResponseDto)
|
|
17
|
+
async def login(
|
|
18
|
+
self,
|
|
19
|
+
body: Annotated[LoginRequestDto, PydanticBody()],
|
|
20
|
+
) -> LoginResponseDto:
|
|
21
|
+
"""Login"""
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
@post("/auth/register", response_class=RegisterResponseDto)
|
|
25
|
+
async def register(
|
|
26
|
+
self,
|
|
27
|
+
body: Annotated[RegisterRequestDto, PydanticBody()],
|
|
28
|
+
) -> RegisterResponseDto:
|
|
29
|
+
"""Register"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
@get("/auth/status", response_class=StatusResponseDto)
|
|
33
|
+
async def get_status(
|
|
34
|
+
self,
|
|
35
|
+
) -> StatusResponseDto:
|
|
36
|
+
"""Get status"""
|
|
37
|
+
...
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from rapid_api_client import Query
|
|
4
|
+
|
|
5
|
+
from remnawave_api.models import NodesUsageResponseDto
|
|
6
|
+
from remnawave_api.rapid import BaseController, get
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BandWidthStatsController(BaseController):
|
|
10
|
+
@get("/nodes/usage/range", response_class=NodesUsageResponseDto)
|
|
11
|
+
async def get_nodes_usage_by_range(
|
|
12
|
+
self,
|
|
13
|
+
start: Annotated[str, Query(description="Start date in ISO format")],
|
|
14
|
+
end: Annotated[str, Query(description="End date in ISO format")],
|
|
15
|
+
) -> NodesUsageResponseDto:
|
|
16
|
+
"""Get Nodes Usage By Range"""
|
|
17
|
+
...
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from typing import Annotated, List
|
|
2
|
+
|
|
3
|
+
from rapid_api_client import Path
|
|
4
|
+
from rapid_api_client.annotations import PydanticBody
|
|
5
|
+
|
|
6
|
+
from remnawave_api.models import (
|
|
7
|
+
CreateHostRequestDto,
|
|
8
|
+
DeleteHostResponseDto,
|
|
9
|
+
HostResponseDto,
|
|
10
|
+
HostsResponseDto,
|
|
11
|
+
ReorderHostRequestDto,
|
|
12
|
+
ReorderHostResponseDto,
|
|
13
|
+
UpdateHostRequestDto,
|
|
14
|
+
)
|
|
15
|
+
from remnawave_api.rapid import AttributeBody, BaseController, delete, get, post
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class HostsController(BaseController):
|
|
19
|
+
@post("/hosts/create", response_class=HostResponseDto)
|
|
20
|
+
async def create_host(
|
|
21
|
+
self,
|
|
22
|
+
body: Annotated[CreateHostRequestDto, PydanticBody()],
|
|
23
|
+
) -> HostResponseDto:
|
|
24
|
+
"""Create Host"""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
@post("/hosts/update", response_class=HostResponseDto)
|
|
28
|
+
async def update_host(
|
|
29
|
+
self,
|
|
30
|
+
body: Annotated[UpdateHostRequestDto, PydanticBody()],
|
|
31
|
+
) -> HostResponseDto:
|
|
32
|
+
"""Update Host"""
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
@get("/hosts/all", response_class=HostsResponseDto)
|
|
36
|
+
async def get_all_hosts(
|
|
37
|
+
self,
|
|
38
|
+
) -> HostsResponseDto:
|
|
39
|
+
"""Get All Hosts"""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
@get("/hosts/get-one/{uuid}", response_class=HostResponseDto)
|
|
43
|
+
async def get_one_host(
|
|
44
|
+
self,
|
|
45
|
+
uuid: Annotated[str, Path(description="UUID of the host")],
|
|
46
|
+
) -> HostResponseDto:
|
|
47
|
+
"""Get One Host"""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
@post("/hosts/reorder", response_class=ReorderHostResponseDto)
|
|
51
|
+
async def reorder_hosts(
|
|
52
|
+
self,
|
|
53
|
+
hosts: Annotated[List[ReorderHostRequestDto], AttributeBody()],
|
|
54
|
+
) -> ReorderHostResponseDto:
|
|
55
|
+
"""Reorder Hosts"""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
@delete("/hosts/delete/{uuid}", response_class=DeleteHostResponseDto)
|
|
59
|
+
async def delete_host(
|
|
60
|
+
self,
|
|
61
|
+
uuid: Annotated[str, Path(description="UUID of the host")],
|
|
62
|
+
) -> DeleteHostResponseDto:
|
|
63
|
+
"""Delete Host"""
|
|
64
|
+
...
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from typing import Annotated, List
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
|
|
4
|
+
from rapid_api_client import PydanticBody
|
|
5
|
+
|
|
6
|
+
from remnawave_api.models import (
|
|
7
|
+
BulkDeleteHostsResponseDto,
|
|
8
|
+
BulkDisableHostsResponseDto,
|
|
9
|
+
BulkEnableHostsResponseDto,
|
|
10
|
+
SetInboundToManyHostsRequestDto,
|
|
11
|
+
SetInboundToManyHostsResponseDto,
|
|
12
|
+
SetPortToManyHostsResponseDto,
|
|
13
|
+
)
|
|
14
|
+
from remnawave_api.rapid import AttributeBody, BaseController, post
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HostsBulkActionsController(BaseController):
|
|
18
|
+
@post("/hosts/bulk/delete", response_class=BulkDeleteHostsResponseDto)
|
|
19
|
+
async def delete_hosts(
|
|
20
|
+
self,
|
|
21
|
+
uuids: Annotated[List[UUID], AttributeBody()],
|
|
22
|
+
) -> BulkDeleteHostsResponseDto:
|
|
23
|
+
"""Delete many hosts"""
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
@post("/hosts/bulk/disable", response_class=BulkDisableHostsResponseDto)
|
|
27
|
+
async def disable_hosts(
|
|
28
|
+
self,
|
|
29
|
+
uuids: Annotated[List[UUID], AttributeBody()],
|
|
30
|
+
) -> BulkDisableHostsResponseDto:
|
|
31
|
+
"""Disable many hosts"""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
@post("/hosts/bulk/enable", response_class=BulkEnableHostsResponseDto)
|
|
35
|
+
async def enable_hosts(
|
|
36
|
+
self,
|
|
37
|
+
uuids: Annotated[List[UUID], AttributeBody()],
|
|
38
|
+
) -> BulkEnableHostsResponseDto:
|
|
39
|
+
"""Enable many hosts"""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
@post(
|
|
43
|
+
"/hosts/bulk/set-inbound",
|
|
44
|
+
response_class=SetInboundToManyHostsResponseDto,
|
|
45
|
+
)
|
|
46
|
+
async def set_inbound_to_hosts(
|
|
47
|
+
self,
|
|
48
|
+
body: Annotated[SetInboundToManyHostsRequestDto, PydanticBody()],
|
|
49
|
+
) -> SetInboundToManyHostsResponseDto:
|
|
50
|
+
"""Set inbound to many hosts"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
@post("/hosts/bulk/set-port", response_class=SetPortToManyHostsResponseDto)
|
|
54
|
+
async def set_port_to_hosts(
|
|
55
|
+
self,
|
|
56
|
+
uuids: Annotated[List[UUID], AttributeBody()],
|
|
57
|
+
port: Annotated[float, AttributeBody()],
|
|
58
|
+
) -> SetPortToManyHostsResponseDto:
|
|
59
|
+
"""Set port to many hosts"""
|
|
60
|
+
...
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from remnawave_api.models import FullInboundsResponseDto, InboundsResponseDto
|
|
2
|
+
from remnawave_api.rapid import BaseController, get
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class InboundsController(BaseController):
|
|
6
|
+
@get("/inbounds", response_class=InboundsResponseDto)
|
|
7
|
+
async def get_inbounds(
|
|
8
|
+
self,
|
|
9
|
+
) -> InboundsResponseDto:
|
|
10
|
+
"""Get Inbounds"""
|
|
11
|
+
...
|
|
12
|
+
|
|
13
|
+
@get("/inbounds/full", response_class=FullInboundsResponseDto)
|
|
14
|
+
async def get_full_inbounds(
|
|
15
|
+
self,
|
|
16
|
+
) -> FullInboundsResponseDto:
|
|
17
|
+
"""Get Full Inbounds"""
|
|
18
|
+
...
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
from uuid import UUID
|
|
3
|
+
|
|
4
|
+
from remnawave_api.models import (
|
|
5
|
+
AddInboundToNodesResponseDto,
|
|
6
|
+
AddInboundToUsersResponseDto,
|
|
7
|
+
RemoveInboundFromNodesResponseDto,
|
|
8
|
+
RemoveInboundFromUsersResponseDto,
|
|
9
|
+
)
|
|
10
|
+
from remnawave_api.rapid import AttributeBody, BaseController, post
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class InboundsBulkActionsController(BaseController):
|
|
14
|
+
@post("/inbounds/bulk/add-to-users", response_class=AddInboundToUsersResponseDto)
|
|
15
|
+
async def add_inbound_to_users(
|
|
16
|
+
self,
|
|
17
|
+
inbound_uuid: Annotated[UUID, AttributeBody()],
|
|
18
|
+
) -> AddInboundToUsersResponseDto:
|
|
19
|
+
"""Add Inbound To Users"""
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
@post(
|
|
23
|
+
"/inbounds/bulk/remove-from-users",
|
|
24
|
+
response_class=RemoveInboundFromUsersResponseDto,
|
|
25
|
+
)
|
|
26
|
+
async def remove_inbound_from_users(
|
|
27
|
+
self,
|
|
28
|
+
inbound_uuid: Annotated[UUID, AttributeBody()],
|
|
29
|
+
) -> RemoveInboundFromUsersResponseDto:
|
|
30
|
+
"""Remove Inbound From Users"""
|
|
31
|
+
...
|
|
32
|
+
|
|
33
|
+
@post("/inbounds/bulk/add-to-nodes", response_class=AddInboundToNodesResponseDto)
|
|
34
|
+
async def add_inbound_to_nodes(
|
|
35
|
+
self,
|
|
36
|
+
inbound_uuid: Annotated[UUID, AttributeBody()],
|
|
37
|
+
) -> AddInboundToNodesResponseDto:
|
|
38
|
+
"""Add Inbound To All Nodes"""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
@post(
|
|
42
|
+
"/inbounds/bulk/remove-from-nodes",
|
|
43
|
+
response_class=RemoveInboundFromNodesResponseDto,
|
|
44
|
+
)
|
|
45
|
+
async def remove_inbound_from_nodes(
|
|
46
|
+
self,
|
|
47
|
+
inbound_uuid: Annotated[UUID, AttributeBody()],
|
|
48
|
+
) -> RemoveInboundFromNodesResponseDto:
|
|
49
|
+
"""Remove Inbound From All Nodes"""
|
|
50
|
+
...
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from remnawave_api.models import PubKeyResponseDto
|
|
2
|
+
from remnawave_api.rapid import BaseController, get
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class KeygenController(BaseController):
|
|
6
|
+
@get("/keygen/get", response_class=PubKeyResponseDto)
|
|
7
|
+
async def generate_key(
|
|
8
|
+
self,
|
|
9
|
+
) -> PubKeyResponseDto:
|
|
10
|
+
"""Get Public Key"""
|
|
11
|
+
...
|