Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions backend/python/app/sources/client/freshdesk/freshdesk.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@

class FreshDeskConfigurationError(Exception):
"""Custom exception for FreshDesk configuration errors"""

def __init__(self, message: str, details: Optional[Dict[str, Any]] = None) -> None:
super().__init__(message)
self.details = details or {}


class FreshDeskResponse(BaseModel):
"""Standardized FreshDesk API response wrapper"""

success: bool
data: Optional[Dict[str, Any]] = None
error: Optional[str] = None
message: Optional[str] = None

def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary for JSON serialization"""
return self.model_dump()
# Use dict(...) directly for faster conversion than model_dump()
return dict(self)

def to_json(self) -> str:
"""Convert to JSON string"""
Expand Down Expand Up @@ -71,24 +74,25 @@ class FreshDeskApiKeyConfig(BaseModel):
api_key: The API key for authentication
ssl: Whether to use SSL (default: True)
"""

domain: str
api_key: str
ssl: bool = True

@field_validator('domain')
@field_validator("domain")
@classmethod
def validate_domain(cls, v: str) -> str:
"""Validate domain field"""
if not v or not v.strip():
raise ValueError("domain cannot be empty or None")

# Validate domain format - should not include protocol
if v.startswith(('http://', 'https://')):
if v.startswith(("http://", "https://")):
raise ValueError("domain should not include protocol (http:// or https://)")

return v

@field_validator('api_key')
@field_validator("api_key")
@classmethod
def validate_api_key(cls, v: str) -> str:
"""Validate api_key field"""
Expand All @@ -104,9 +108,9 @@ def create_client(self) -> FreshDeskRESTClientViaApiKey:
def to_dict(self) -> dict:
"""Convert the configuration to a dictionary"""
return {
'domain': self.domain,
'ssl': self.ssl,
'has_api_key': bool(self.api_key)
"domain": self.domain,
"ssl": self.ssl,
"has_api_key": bool(self.api_key),
}


Expand Down Expand Up @@ -144,7 +148,9 @@ def build_with_config(
return cls(config.create_client())

@classmethod
def build_with_api_key_config(cls, config: FreshDeskApiKeyConfig) -> "FreshDeskClient":
def build_with_api_key_config(
cls, config: FreshDeskApiKeyConfig
) -> "FreshDeskClient":
"""Build FreshDeskClient with API key configuration

Args:
Expand All @@ -157,10 +163,7 @@ def build_with_api_key_config(cls, config: FreshDeskApiKeyConfig) -> "FreshDeskC

@classmethod
def build_with_api_key(
cls,
domain: str,
api_key: str,
ssl: bool = True
cls, domain: str, api_key: str, ssl: bool = True
) -> "FreshDeskClient":
"""Build FreshDeskClient with API key directly

Expand All @@ -172,11 +175,7 @@ def build_with_api_key(
Returns:
FreshDeskClient: Configured client instance
"""
config = FreshDeskApiKeyConfig(
domain=domain,
api_key=api_key,
ssl=ssl
)
config = FreshDeskApiKeyConfig(domain=domain, api_key=api_key, ssl=ssl)
return cls.build_with_config(config)

@classmethod
Expand Down