Merge pull request #31 from remnawave:development

Improve error handling in API requests
This commit is contained in:
Artem 2025-12-11 08:49:27 +01:00 committed by GitHub
commit f7b5bf1801
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 32 additions and 9 deletions

View file

@ -1,6 +1,6 @@
[project]
name = "remnawave"
version = "2.3.2"
version = "2.3.2rc1"
description = "A Python SDK for interacting with the Remnawave API v2.3.2."
authors = [
{name = "Artem",email = "dev@forestsnet.com"}

View file

@ -207,6 +207,9 @@ from .subscriptions_settings import (
SubscriptionSettingsResponseDto,
UpdateSubscriptionSettingsRequestDto,
UpdateSubscriptionSettingsResponseDto,
CustomRemarksDto,
HwidSettingsDto,
# Backward compatibility aliases
CustomRemarks,
HwidSettings,
)
@ -492,6 +495,9 @@ __all__ = [
"GetSubscriptionSettingsResponseDto",
"SubscriptionSettingsResponseDto",
"UpdateSubscriptionSettingsRequestDto",
"CustomRemarksDto",
"HwidSettingsDto",
# Backward compatibility aliases
"CustomRemarks",
"HwidSettings",
"UpdateSubscriptionSettingsResponseDto",

View file

@ -4,6 +4,7 @@ from typing import Dict, List, Optional
from uuid import UUID
from pydantic import BaseModel, Field
from remnawave.models import CustomRemarksDto, HwidSettingsDto
class TemplateType(StrEnum):
@ -54,6 +55,8 @@ class ExternalSquadDto(BaseModel):
subscription_settings: Optional[ExternalSquadSubscriptionSettingsDto] = Field(None, alias="subscriptionSettings")
host_overrides: Optional[ExternalSquadHostOverridesDto] = Field(None, alias="hostOverrides")
response_headers: Optional[Dict[str, str]] = Field(None, alias="responseHeaders")
hwid_settings: Optional[HwidSettingsDto] = Field(None, alias="hwidSettings")
custom_remarks: Optional[CustomRemarksDto] = Field(None, alias="customRemarks")
created_at: datetime = Field(alias="createdAt")
updated_at: datetime = Field(alias="updatedAt")
@ -87,6 +90,8 @@ class UpdateExternalSquadRequestDto(BaseModel):
templates: Optional[List[ExternalSquadTemplateDto]] = None
subscription_settings: Optional[ExternalSquadSubscriptionSettingsDto] = Field(None, serialization_alias="subscriptionSettings")
host_overrides: Optional[ExternalSquadHostOverridesDto] = Field(None, serialization_alias="hostOverrides")
hwid_settings: Optional[HwidSettingsDto] = Field(None, alias="hwidSettings")
custom_remarks: Optional[CustomRemarksDto] = Field(None, alias="customRemarks")
response_headers: Optional[Dict[str, str]] = Field(None, serialization_alias="responseHeaders")

View file

@ -55,7 +55,7 @@ class ResponseRules(BaseModel):
rules: List[ResponseRule]
class CustomRemarks(BaseModel):
class CustomRemarksDto(BaseModel):
"""Custom remarks for different user states"""
expired_users: List[str] = Field(alias="expiredUsers", min_length=1)
limited_users: List[str] = Field(alias="limitedUsers", min_length=1)
@ -64,7 +64,7 @@ class CustomRemarks(BaseModel):
empty_internal_squads: List[str] = Field(alias="emptyInternalSquads", min_length=1)
class HwidSettings(BaseModel):
class HwidSettingsDto(BaseModel):
"""HWID (Hardware ID) settings"""
enabled: bool
fallback_device_limit: int = Field(alias="fallbackDeviceLimit")
@ -82,7 +82,7 @@ class SubscriptionSettingsResponseDto(BaseModel):
serve_json_at_base_subscription: bool = Field(alias="serveJsonAtBaseSubscription")
show_custom_remarks: bool = Field(alias="isShowCustomRemarks")
custom_remarks: CustomRemarks = Field(alias="customRemarks")
custom_remarks: CustomRemarksDto = Field(alias="customRemarks")
happ_announce: Optional[str] = Field(None, alias="happAnnounce")
happ_routing: Optional[str] = Field(None, alias="happRouting")
@ -90,7 +90,7 @@ class SubscriptionSettingsResponseDto(BaseModel):
randomize_hosts: bool = Field(alias="randomizeHosts")
response_rules: Optional[ResponseRules] = Field(None, alias="responseRules")
hwid_settings: Optional[HwidSettings] = Field(None, alias="hwidSettings")
hwid_settings: Optional[HwidSettingsDto] = Field(None, alias="hwidSettings")
created_at: datetime = Field(alias="createdAt")
updated_at: datetime = Field(alias="updatedAt")
@ -118,7 +118,7 @@ class UpdateSubscriptionSettingsRequestDto(BaseModel):
)
is_show_custom_remarks: Optional[bool] = Field(None, serialization_alias="isShowCustomRemarks")
custom_remarks: Optional[CustomRemarks] = Field(None, serialization_alias="customRemarks")
custom_remarks: Optional[CustomRemarksDto] = Field(None, serialization_alias="customRemarks")
happ_announce: Optional[Annotated[str, StringConstraints(max_length=200)]] = Field(
None, serialization_alias="happAnnounce"
@ -130,4 +130,9 @@ class UpdateSubscriptionSettingsRequestDto(BaseModel):
randomize_hosts: Optional[bool] = Field(None, serialization_alias="randomizeHosts")
response_rules: Optional[ResponseRules] = Field(None, serialization_alias="responseRules")
hwid_settings: Optional[HwidSettings] = Field(None, serialization_alias="hwidSettings")
hwid_settings: Optional[HwidSettingsDto] = Field(None, serialization_alias="hwidSettings")
# Backward compatibility aliases
CustomRemarks = CustomRemarksDto
HwidSettings = HwidSettingsDto

View file

@ -1,5 +1,5 @@
from datetime import datetime
from typing import Annotated, List, Optional
from typing import Annotated, List, Literal, Optional
from uuid import UUID
from pydantic import (
@ -177,6 +177,13 @@ class UserResponseDto(BaseModel):
"""Generate Happ Crypto Link"""
crypto_link = create_happ_crypto_link(self.subscription_url)
return HappCrypto(cryptoLink=crypto_link)
def happ_with_version(self, version: Literal["v3", "v4"] = "v4") -> HappCrypto:
return self._generate_happ(version=version)
def _generate_happ(self, version):
crypto_link = create_happ_crypto_link(content=self.subscription_url, method=version)
return HappCrypto(cryptoLink=crypto_link)
class RevokeUserRequestDto(BaseModel):

View file

@ -52,6 +52,6 @@ def create_happ_crypto_link(content: str, method: Literal["v3", "v4"] = "v4") ->
content.encode("utf-8"), padding.PKCS1v15() # RSA_PKCS1_PADDING
)
return "happ://crypt{" + method.lower().replace("v", "") + "/" + base64.b64encode(encrypted).decode()
return "happ://crypt" + method.lower().replace("v", "") + "/" + base64.b64encode(encrypted).decode()
except Exception:
return ""