mirror of
https://github.com/remnawave/python-sdk.git
synced 2026-05-13 12:16:42 +00:00
feat: обновить версию SDK до 2.6.1 и добавить поддержку тегов узлов и обновления паролей
This commit is contained in:
parent
5f20e55bd1
commit
6c9fa202ad
16 changed files with 133 additions and 41 deletions
|
|
@ -50,6 +50,7 @@ pip install git+https://github.com/remnawave/python-sdk.git@development
|
|||
|
||||
| Contract Version | Remnawave Panel Version |
|
||||
| ---------------- | ----------------------- |
|
||||
| 2.6.1 | >=2.6.0 |
|
||||
| 2.4.4 | >=2.4.0 |
|
||||
| 2.3.2 | >=2.3.0, <2.4.0 |
|
||||
| 2.3.0 | >=2.3.0, <2.3.2 |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[project]
|
||||
name = "remnawave"
|
||||
version = "2.4.4"
|
||||
description = "A Python SDK for interacting with the Remnawave API v2.4.4."
|
||||
version = "2.6.1"
|
||||
description = "A Python SDK for interacting with the Remnawave API v2.6.1."
|
||||
authors = [
|
||||
{name = "Artem",email = "dev@forestsnet.com"}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from remnawave.models import (
|
|||
DisableNodeResponseDto,
|
||||
EnableNodeResponseDto,
|
||||
GetAllNodesResponseDto,
|
||||
GetAllNodesTagsResponseDto,
|
||||
GetOneNodeResponseDto,
|
||||
ReorderNodeRequestDto,
|
||||
ReorderNodeResponseDto,
|
||||
|
|
@ -29,6 +30,13 @@ from remnawave.rapid import BaseController, delete, get, patch, post
|
|||
|
||||
|
||||
class NodesController(BaseController):
|
||||
@get("/nodes/tags", response_class=GetAllNodesTagsResponseDto)
|
||||
async def get_all_nodes_tags(
|
||||
self,
|
||||
) -> GetAllNodesTagsResponseDto:
|
||||
"""Get all nodes tags"""
|
||||
...
|
||||
|
||||
@post("/nodes", response_class=CreateNodeResponseDto)
|
||||
async def create_node(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ from remnawave.models import (
|
|||
DeletePasskeyResponseDto,
|
||||
GetAllPasskeysResponseDto,
|
||||
GetPasskeyRegistrationOptionsResponseDto,
|
||||
UpdatePasskeyRequestDto,
|
||||
UpdatePasskeyResponseDto,
|
||||
VerifyPasskeyRegistrationRequestDto,
|
||||
VerifyPasskeyRegistrationResponseDto,
|
||||
)
|
||||
from remnawave.rapid import BaseController, delete, get, post
|
||||
from remnawave.rapid import BaseController, delete, get, patch, post
|
||||
|
||||
|
||||
class PasskeysController(BaseController):
|
||||
|
|
@ -42,4 +44,12 @@ class PasskeysController(BaseController):
|
|||
body: Annotated[DeletePasskeyRequestDto, PydanticBody()],
|
||||
) -> DeletePasskeyResponseDto:
|
||||
"""Delete a passkey by ID"""
|
||||
...
|
||||
|
||||
@patch("/passkeys", response_class=UpdatePasskeyResponseDto)
|
||||
async def update_passkey(
|
||||
self,
|
||||
body: Annotated[UpdatePasskeyRequestDto, PydanticBody()],
|
||||
) -> UpdatePasskeyResponseDto:
|
||||
"""Update a passkey name"""
|
||||
...
|
||||
|
|
@ -4,4 +4,5 @@ class OAuth2Provider(StrEnum):
|
|||
"""OAuth2 Provider enum"""
|
||||
GITHUB = "github"
|
||||
POCKETID = "pocketid"
|
||||
YANDEX = "yandex"
|
||||
YANDEX = "yandex"
|
||||
KEYCLOAK = "keycloak"
|
||||
|
|
@ -179,6 +179,7 @@ from .nodes import (
|
|||
EnableNodeResponseDto,
|
||||
ExcludedInbounds,
|
||||
GetAllNodesResponseDto,
|
||||
GetAllNodesTagsResponseDto,
|
||||
GetOneNodeResponseDto,
|
||||
NodeConfigProfileDto,
|
||||
NodeConfigProfileRequestDto,
|
||||
|
|
@ -388,6 +389,8 @@ from .passkeys import (
|
|||
GetAllPasskeysResponseDto,
|
||||
GetPasskeyRegistrationOptionsResponseDto,
|
||||
PasskeyDto,
|
||||
UpdatePasskeyRequestDto,
|
||||
UpdatePasskeyResponseDto,
|
||||
VerifyPasskeyRegistrationRequestDto,
|
||||
VerifyPasskeyRegistrationResponseDto,
|
||||
)
|
||||
|
|
@ -422,6 +425,8 @@ from .remnawave_settings import (
|
|||
BrandingSettings,
|
||||
GetRemnawaveSettingsResponseDto,
|
||||
GitHubOAuth2Settings,
|
||||
GenericOAuth2Settings,
|
||||
KeycloakOAuth2Settings,
|
||||
OAuth2Settings,
|
||||
PasskeySettings,
|
||||
PasswordSettings,
|
||||
|
|
@ -474,6 +479,7 @@ __all__ = [
|
|||
"EnableNodeResponseDto",
|
||||
"ExcludedInbounds",
|
||||
"GetAllNodesResponseDto",
|
||||
"GetAllNodesTagsResponseDto",
|
||||
"GetOneNodeResponseDto",
|
||||
"NodeResponseDto",
|
||||
"NodesResponseDto", # Legacy alias
|
||||
|
|
@ -815,6 +821,8 @@ __all__ = [
|
|||
"GetAllPasskeysResponseDto",
|
||||
"GetPasskeyRegistrationOptionsResponseDto",
|
||||
"PasskeyDto",
|
||||
"UpdatePasskeyRequestDto",
|
||||
"UpdatePasskeyResponseDto",
|
||||
"VerifyPasskeyRegistrationRequestDto",
|
||||
"VerifyPasskeyRegistrationResponseDto",
|
||||
|
||||
|
|
@ -850,7 +858,9 @@ __all__ = [
|
|||
|
||||
"BrandingSettings",
|
||||
"GetRemnawaveSettingsResponseDto",
|
||||
"GenericOAuth2Settings",
|
||||
"GitHubOAuth2Settings",
|
||||
"KeycloakOAuth2Settings",
|
||||
"OAuth2Settings",
|
||||
"PasskeySettings",
|
||||
"PasswordSettings",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class InboundDto(BaseModel):
|
|||
type: str
|
||||
network: Optional[str] = None
|
||||
security: Optional[str] = None
|
||||
port: Optional[int] = None
|
||||
port: Optional[float] = None
|
||||
raw_inbound: Optional[Any] = Field(None, alias="rawInbound")
|
||||
|
||||
class NodesProfileDto(BaseModel):
|
||||
|
|
@ -23,6 +23,7 @@ class NodesProfileDto(BaseModel):
|
|||
class ConfigProfileDto(BaseModel):
|
||||
uuid: UUID
|
||||
name: str
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
config: Dict[str, Any]
|
||||
inbounds: List[InboundDto]
|
||||
nodes: List[NodesProfileDto] = []
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ class ExternalSquadHostOverridesDto(BaseModel):
|
|||
class ExternalSquadDto(BaseModel):
|
||||
"""External squad data model"""
|
||||
uuid: UUID
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
name: str
|
||||
info: ExternalSquadInfoDto
|
||||
templates: List[ExternalSquadTemplateDto]
|
||||
|
|
|
|||
|
|
@ -65,18 +65,18 @@ class HostResponseDto(BaseModel):
|
|||
remark: str
|
||||
address: str
|
||||
port: int
|
||||
path: Optional[str] = None
|
||||
sni: Optional[str] = None
|
||||
host: Optional[str] = None
|
||||
alpn: Optional[str] = None
|
||||
fingerprint: Optional[str] = None
|
||||
x_http_extra_params: Optional[Dict[str, Any]] = Field(None, alias="xHttpExtraParams")
|
||||
mux_params: Optional[Dict[str, Any]] = Field(None, alias="muxParams")
|
||||
sockopt_params: Optional[Dict[str, Any]] = Field(None, alias="sockoptParams")
|
||||
path: str | None = Field(alias="path")
|
||||
sni: str | None = Field(alias="sni")
|
||||
host: str | None = Field(alias="host")
|
||||
alpn: str | None = Field(alias="alpn")
|
||||
fingerprint: str | None = Field(alias="fingerprint")
|
||||
x_http_extra_params: Dict[str, Any] | None = Field(alias="xHttpExtraParams")
|
||||
mux_params: Dict[str, Any] | None = Field(alias="muxParams")
|
||||
sockopt_params: Dict[str, Any] | None = Field(alias="sockoptParams")
|
||||
inbound: HostInboundData
|
||||
server_description: Optional[str] = Field(None, alias="serverDescription")
|
||||
tag: Optional[str] = None
|
||||
vless_route_id: Optional[int] = Field(None, alias="vlessRouteId")
|
||||
server_description: str | None = Field(alias="serverDescription")
|
||||
tag: str | None = Field(alias="tag")
|
||||
vless_route_id: int | None = Field(alias="vlessRouteId")
|
||||
shuffle_host: bool = Field(alias="shuffleHost")
|
||||
mihomo_x25519: bool = Field(alias="mihomoX25519")
|
||||
nodes: List[UUID]
|
||||
|
|
@ -86,7 +86,7 @@ class HostResponseDto(BaseModel):
|
|||
override_sni_from_address: bool = Field(False, alias="overrideSniFromAddress")
|
||||
keep_blank_sni: bool = Field(False, alias="keepBlankSni")
|
||||
allow_insecure: bool = Field(False, alias="allowInsecure")
|
||||
xray_json_template_uuid: Optional[UUID] = Field(None, alias="xrayJsonTemplateUuid")
|
||||
xray_json_template_uuid: UUID | None = Field(alias="xrayJsonTemplateUuid")
|
||||
excluded_internal_squads: List[UUID] = Field(default_factory=list, alias="excludedInternalSquads")
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ class InboundsDto(BaseModel):
|
|||
profile_uuid: UUID = Field(alias="profileUuid")
|
||||
tag: str
|
||||
type: str
|
||||
network: Optional[str] = Field(default=None)
|
||||
security: Optional[str] = Field(default=None)
|
||||
port: Optional[float] = Field(default=None)
|
||||
raw_inbound: Optional[dict] = Field(default=None, alias="rawInbound")
|
||||
network: Optional[str] = None
|
||||
security: Optional[str] = None
|
||||
port: Optional[float] = None
|
||||
raw_inbound: Optional[dict] = Field(None, alias="rawInbound")
|
||||
|
||||
|
||||
class InfoDto(BaseModel):
|
||||
|
|
@ -23,6 +23,7 @@ class InfoDto(BaseModel):
|
|||
|
||||
class InternalSquadDto(BaseModel):
|
||||
uuid: UUID
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
name: str
|
||||
info: Optional[InfoDto] = Field(default=None)
|
||||
inbounds: List[InboundsDto] = Field(default_factory=list)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ class ReorderNodeItem(BaseModel):
|
|||
uuid: UUID
|
||||
|
||||
|
||||
class GetAllNodesTagsResponseDto(BaseModel):
|
||||
"""Response with all nodes tags"""
|
||||
tags: List[str]
|
||||
|
||||
|
||||
class NodeProviderDto(BaseModel):
|
||||
"""Node provider information"""
|
||||
uuid: UUID
|
||||
|
|
@ -79,6 +84,11 @@ class CreateNodeRequestDto(BaseModel):
|
|||
serialization_alias="configProfile"
|
||||
)
|
||||
provider_uuid: Optional[UUID] = Field(None, serialization_alias="providerUuid")
|
||||
tags: Optional[List[Annotated[str, StringConstraints(max_length=36, pattern=r'^[A-Z0-9_:]+$')]]] = Field(
|
||||
None,
|
||||
serialization_alias="tags",
|
||||
max_length=10
|
||||
)
|
||||
|
||||
|
||||
class UpdateNodeRequestDto(BaseModel):
|
||||
|
|
@ -111,6 +121,11 @@ class UpdateNodeRequestDto(BaseModel):
|
|||
None, serialization_alias="configProfile"
|
||||
)
|
||||
provider_uuid: Optional[UUID] = Field(None, serialization_alias="providerUuid")
|
||||
tags: Optional[List[Annotated[str, StringConstraints(max_length=36, pattern=r'^[A-Z0-9_:]+$')]]] = Field(
|
||||
None,
|
||||
serialization_alias="tags",
|
||||
max_length=10
|
||||
)
|
||||
|
||||
|
||||
class ReorderNodeRequestDto(BaseModel):
|
||||
|
|
@ -147,6 +162,7 @@ class NodeResponseDto(BaseModel):
|
|||
config_profile: NodeConfigProfileDto = Field(alias="configProfile")
|
||||
provider_uuid: Optional[UUID] = Field(None, alias="providerUuid")
|
||||
provider: Optional[NodeProviderDto] = None
|
||||
tags: List[str] = Field(default_factory=list, alias="tags")
|
||||
|
||||
|
||||
class CreateNodeResponseDto(NodeResponseDto):
|
||||
|
|
|
|||
|
|
@ -43,4 +43,15 @@ class DeletePasskeyRequestDto(BaseModel):
|
|||
|
||||
class DeletePasskeyResponseDto(BaseModel):
|
||||
"""Response with updated passkeys list after deletion"""
|
||||
passkeys: List[PasskeyDto]
|
||||
passkeys: List[PasskeyDto]
|
||||
|
||||
|
||||
class UpdatePasskeyRequestDto(BaseModel):
|
||||
"""Request to update a passkey"""
|
||||
id: str
|
||||
name: str
|
||||
|
||||
|
||||
class UpdatePasskeyResponseDto(BaseModel):
|
||||
"""Response with updated passkey information"""
|
||||
passkey: PasskeyDto
|
||||
|
|
@ -6,32 +6,55 @@ from pydantic import BaseModel, Field, HttpUrl
|
|||
class PasskeySettings(BaseModel):
|
||||
"""Passkey authentication settings"""
|
||||
enabled: bool
|
||||
rp_id: Optional[str] = Field(None, alias="rpId")
|
||||
origin: Optional[str] = None
|
||||
rp_id: str | None = Field(alias="rpId")
|
||||
origin: str | None
|
||||
|
||||
|
||||
class GitHubOAuth2Settings(BaseModel):
|
||||
"""GitHub OAuth2 settings"""
|
||||
enabled: bool
|
||||
client_id: Optional[str] = Field(None, alias="clientId")
|
||||
client_secret: Optional[str] = Field(None, alias="clientSecret")
|
||||
client_id: str | None = Field(alias="clientId")
|
||||
client_secret: str | None = Field(alias="clientSecret")
|
||||
allowed_emails: List[str] = Field(alias="allowedEmails")
|
||||
|
||||
|
||||
class PocketIdOAuth2Settings(BaseModel):
|
||||
"""PocketID OAuth2 settings"""
|
||||
enabled: bool
|
||||
client_id: Optional[str] = Field(None, alias="clientId")
|
||||
client_secret: Optional[str] = Field(None, alias="clientSecret")
|
||||
plain_domain: Optional[str] = Field(None, alias="plainDomain")
|
||||
client_id: str | None = Field(alias="clientId")
|
||||
client_secret: str | None = Field(alias="clientSecret")
|
||||
plain_domain: str | None = Field(alias="plainDomain")
|
||||
allowed_emails: List[str] = Field(alias="allowedEmails")
|
||||
|
||||
|
||||
class YandexOAuth2Settings(BaseModel):
|
||||
"""Yandex OAuth2 settings"""
|
||||
enabled: bool
|
||||
client_id: Optional[str] = Field(None, alias="clientId")
|
||||
client_secret: Optional[str] = Field(None, alias="clientSecret")
|
||||
client_id: str | None = Field(alias="clientId")
|
||||
client_secret: str | None = Field(alias="clientSecret")
|
||||
allowed_emails: List[str] = Field(alias="allowedEmails")
|
||||
|
||||
|
||||
class KeycloakOAuth2Settings(BaseModel):
|
||||
"""Keycloak OAuth2 settings"""
|
||||
enabled: bool
|
||||
realm: str | None
|
||||
client_id: str | None = Field(alias="clientId")
|
||||
client_secret: str | None = Field(alias="clientSecret")
|
||||
frontend_domain: str | None = Field(alias="frontendDomain")
|
||||
keycloak_domain: str | None = Field(alias="keycloakDomain")
|
||||
allowed_emails: List[str] = Field(alias="allowedEmails")
|
||||
|
||||
|
||||
class GenericOAuth2Settings(BaseModel):
|
||||
"""Generic OAuth2 settings"""
|
||||
enabled: bool
|
||||
client_id: str | None = Field(alias="clientId")
|
||||
client_secret: str | None = Field(alias="clientSecret")
|
||||
with_pkce: bool = Field(alias="withPkce")
|
||||
authorization_url: str | None = Field(alias="authorizationUrl")
|
||||
token_url: str | None = Field(alias="tokenUrl")
|
||||
frontend_domain: str | None = Field(alias="frontendDomain")
|
||||
allowed_emails: List[str] = Field(alias="allowedEmails")
|
||||
|
||||
|
||||
|
|
@ -40,12 +63,14 @@ class OAuth2Settings(BaseModel):
|
|||
github: GitHubOAuth2Settings
|
||||
pocketid: PocketIdOAuth2Settings
|
||||
yandex: YandexOAuth2Settings
|
||||
keycloak: KeycloakOAuth2Settings
|
||||
generic: GenericOAuth2Settings
|
||||
|
||||
|
||||
class TelegramAuthSettings(BaseModel):
|
||||
"""Telegram authentication settings"""
|
||||
enabled: bool
|
||||
bot_token: Optional[str] = Field(None, alias="botToken")
|
||||
bot_token: str | None = Field(alias="botToken")
|
||||
admin_ids: List[str] = Field(alias="adminIds")
|
||||
|
||||
|
||||
|
|
@ -62,9 +87,9 @@ class BrandingSettings(BaseModel):
|
|||
|
||||
class RemnawaveSettingsData(BaseModel):
|
||||
"""Remnawave settings data"""
|
||||
passkey_settings: Optional[PasskeySettings] = Field(None, alias="passkeySettings")
|
||||
oauth2_settings: Optional[OAuth2Settings] = Field(None, alias="oauth2Settings")
|
||||
tg_auth_settings: Optional[TelegramAuthSettings] = Field(None, alias="tgAuthSettings")
|
||||
passkey_settings: PasskeySettings | None = Field(alias="passkeySettings")
|
||||
oauth2_settings: OAuth2Settings | None = Field(alias="oauth2Settings")
|
||||
tg_auth_settings: TelegramAuthSettings | None = Field(alias="tgAuthSettings")
|
||||
password_settings: Optional[PasswordSettings] = Field(None, alias="passwordSettings")
|
||||
branding_settings: Optional[BrandingSettings] = Field(None, alias="brandingSettings")
|
||||
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ class UserSubscription(BaseModel):
|
|||
lifetime_traffic_used: str = Field(alias="lifetimeTrafficUsed")
|
||||
traffic_used_bytes: str = Field(alias="trafficUsedBytes")
|
||||
traffic_limit_bytes: str = Field(alias="trafficLimitBytes")
|
||||
lifetime_traffic_used_bytes: int = Field(alias="lifetimeTrafficUsedBytes")
|
||||
lifetime_traffic_used_bytes: str = Field(alias="lifetimeTrafficUsedBytes")
|
||||
traffic_limit_strategy: TrafficLimitStrategy = Field(alias="trafficLimitStrategy")
|
||||
expires_at: datetime = Field(alias="expiresAt")
|
||||
user_status: UserStatus = Field(alias="userStatus")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class SubscriptionPageConfigDto(BaseModel):
|
|||
uuid: UUID
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
name: str
|
||||
config: Optional[Any] = None
|
||||
config: Any | None
|
||||
|
||||
|
||||
class GetSubscriptionPageConfigsData(BaseModel):
|
||||
|
|
@ -25,9 +25,14 @@ class GetSubscriptionPageConfigsResponseDto(GetSubscriptionPageConfigsData):
|
|||
pass
|
||||
|
||||
|
||||
class GetSubscriptionPageConfigResponseDto(SubscriptionPageConfigDto):
|
||||
class GetSubscriptionPageConfigResponseDto(BaseModel):
|
||||
"""Response with single subscription page config"""
|
||||
pass
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
uuid: UUID
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
name: str
|
||||
config: Any
|
||||
|
||||
|
||||
class CreateSubscriptionPageConfigRequestDto(BaseModel):
|
||||
|
|
|
|||
|
|
@ -9,15 +9,17 @@ from remnawave.enums import TemplateType
|
|||
class TemplateResponseDto(BaseModel):
|
||||
uuid: UUID
|
||||
name: str
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
template_type: TemplateType = Field(alias="templateType")
|
||||
template_json: Optional[Any] = Field(None, alias="templateJson")
|
||||
encoded_template_yaml: Optional[str] = Field(None, alias="encodedTemplateYaml")
|
||||
template_json: Any | None = Field(alias="templateJson")
|
||||
encoded_template_yaml: str | None = Field(alias="encodedTemplateYaml")
|
||||
|
||||
|
||||
class TemplateInfoDto(BaseModel):
|
||||
"""Template info without content - used in list responses"""
|
||||
uuid: UUID
|
||||
name: str
|
||||
view_position: int = Field(alias="viewPosition")
|
||||
template_type: TemplateType = Field(alias="templateType")
|
||||
template_json: Optional[Any] = Field(None, alias="templateJson")
|
||||
encoded_template_yaml: Optional[str] = Field(None, alias="encodedTemplateYaml")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue