feat: Add analytics, security, and currency SDK modules with comprehensive API endpoints across Elixir and Go SDKs

- Add AnalyticsAPI with churn prediction (predict, metrics, at-risk), market analytics (metrics, competitors, opportunities), predictive maintenance (metrics, assets, alerts, predict), and pricing optimization (metrics, optimize, elasticity) endpoints
- Add SecurityAPI with fraud detection (analyze, alerts, update status, metrics, patterns) and SIM swap protection (verify, history) endpoints
- Add CurrencyAPI with currency conversion (convert, exchange rates, rate
This commit is contained in:
nutcas3
2026-05-03 13:29:44 +03:00
parent 12887765de
commit 9f51d6f20e
44 changed files with 3432 additions and 146 deletions
+31 -1
View File
@@ -9,6 +9,9 @@ from .api import (
SystemAPI,
GraphQLAPI,
)
from .analytics import AnalyticsAPI
from .security import SecurityAPI
from .currency import CurrencyAPI
from .websocket import WebSocketClient
from .types import (
Subscriber,
@@ -21,6 +24,18 @@ from .types import (
RatingPlan,
RealTimeUsage,
PaginatedResponse,
ChurnRiskLevel,
ChurnPrediction,
ChurnMetrics,
FraudType,
FraudSeverity,
FraudAlert,
FraudMetrics,
FraudAlertFilter,
MarketMetrics,
PredictiveMaintenanceMetrics,
PricingOptimizationResult,
PricingMetrics,
)
from .exceptions import (
TelecomError,
@@ -32,7 +47,7 @@ from .exceptions import (
ServerError,
)
__version__ = "1.0.0"
__version__ = "2.0.0"
__all__ = [
# Main SDK client
"TelecomSDK",
@@ -46,6 +61,9 @@ __all__ = [
"RatingPlanAPI",
"SystemAPI",
"GraphQLAPI",
"AnalyticsAPI",
"SecurityAPI",
"CurrencyAPI",
# WebSocket
"WebSocketClient",
# Types
@@ -59,6 +77,18 @@ __all__ = [
"RatingPlan",
"RealTimeUsage",
"PaginatedResponse",
"ChurnRiskLevel",
"ChurnPrediction",
"ChurnMetrics",
"FraudType",
"FraudSeverity",
"FraudAlert",
"FraudMetrics",
"FraudAlertFilter",
"MarketMetrics",
"PredictiveMaintenanceMetrics",
"PricingOptimizationResult",
"PricingMetrics",
# Exceptions
"TelecomError",
"AuthenticationError",
+92
View File
@@ -0,0 +1,92 @@
"""Analytics API client for churn prediction, market analysis, and pricing optimization."""
from typing import List, Optional
from datetime import datetime
from .types import (
ChurnPrediction,
ChurnMetrics,
ChurnRiskLevel,
MarketMetrics,
PredictiveMaintenanceMetrics,
PricingOptimizationResult,
PricingMetrics,
)
class AnalyticsAPI:
"""Analytics API client for churn, market, maintenance, and pricing analytics."""
def __init__(self, client):
self._client = client
def predict_churn(self, profile_id: str) -> ChurnPrediction:
"""Predict churn risk for a profile."""
response = self._client.post("/api/v1/analytics/churn/predict", {"profile_id": profile_id})
return ChurnPrediction(**response)
def get_churn_metrics(self, period: str = "monthly") -> ChurnMetrics:
"""Get churn metrics for a period."""
response = self._client.get("/api/v1/analytics/churn/metrics", params={"period": period})
return ChurnMetrics(**response)
def get_at_risk_customers(
self, risk_level: ChurnRiskLevel, limit: int = 100
) -> List[ChurnPrediction]:
"""Get customers at risk of churning."""
response = self._client.get(
"/api/v1/analytics/churn/at-risk",
params={"risk_level": risk_level.value, "limit": str(limit)},
)
return [ChurnPrediction(**item) for item in response]
def get_market_metrics(self, period: str = "monthly") -> MarketMetrics:
"""Get market penetration metrics."""
response = self._client.get("/api/v1/analytics/market/metrics", params={"period": period})
return MarketMetrics(**response)
def get_competitors(self) -> dict:
"""Get competitor analysis."""
return self._client.get("/api/v1/analytics/market/competitors")
def get_market_opportunities(self) -> dict:
"""Get market opportunities."""
return self._client.get("/api/v1/analytics/market/opportunities")
def get_maintenance_metrics(self, period: str = "monthly") -> PredictiveMaintenanceMetrics:
"""Get predictive maintenance metrics."""
response = self._client.get(
"/api/v1/analytics/maintenance/metrics", params={"period": period}
)
return PredictiveMaintenanceMetrics(**response)
def get_assets_health(self) -> dict:
"""Get assets health status."""
return self._client.get("/api/v1/analytics/maintenance/assets")
def get_maintenance_alerts(self) -> dict:
"""Get maintenance alerts."""
return self._client.get("/api/v1/analytics/maintenance/alerts")
def predict_failure(self, asset_id: str) -> dict:
"""Predict failure for an asset."""
return self._client.post(f"/api/v1/analytics/maintenance/predict/{asset_id}", {})
def get_pricing_metrics(self, period: str = "monthly") -> PricingMetrics:
"""Get pricing optimization metrics."""
response = self._client.get("/api/v1/analytics/pricing/metrics", params={"period": period})
return PricingMetrics(**response)
def optimize_pricing(
self, rate_plan_ids: List[str], strategy: str = "revenue_maximization"
) -> List[PricingOptimizationResult]:
"""Optimize pricing for rate plans."""
response = self._client.post(
"/api/v1/analytics/pricing/optimize",
{"rate_plan_ids": rate_plan_ids, "strategy": strategy},
)
return [PricingOptimizationResult(**item) for item in response]
def get_price_elasticity(self) -> dict:
"""Get price elasticity data."""
return self._client.get("/api/v1/analytics/pricing/elasticity")
+6 -2
View File
@@ -9,8 +9,10 @@ from .api import (
PaymentAPI,
RatingPlanAPI,
SystemAPI,
GraphQLAPI,
)
from .analytics import AnalyticsAPI
from .security import SecurityAPI
from .currency import CurrencyAPI
from .websocket import WebSocketClient
from .types import (
Subscriber,
@@ -99,7 +101,9 @@ class TelecomSDK:
self.payments = PaymentAPI(self.api_client)
self.rating_plans = RatingPlanAPI(self.api_client)
self.system = SystemAPI(self.api_client)
self.graphql = GraphQLAPI(self.api_client)
self.analytics = AnalyticsAPI(self.api_client)
self.security = SecurityAPI(self.api_client)
self.currency = CurrencyAPI(self.api_client)
async def __aenter__(self):
"""Async context manager entry."""
+68
View File
@@ -0,0 +1,68 @@
"""Currency and Billing API client."""
from typing import List, Optional, Dict, Any
from datetime import datetime
class CurrencyAPI:
"""Currency and Billing API client."""
def __init__(self, client):
self._client = client
def convert(self, from_currency: str, to_currency: str, amount: float) -> dict:
"""Convert currency."""
return self._client.post(
"/api/v1/currency/convert",
{"from": from_currency, "to": to_currency, "amount": amount},
)
def get_exchange_rate(self, from_currency: str, to_currency: str) -> dict:
"""Get exchange rate between currencies."""
return self._client.get(f"/api/v1/currency/exchange/{from_currency}/{to_currency}")
def get_exchange_rate_history(
self, from_currency: str, to_currency: str, days: int = 30
) -> dict:
"""Get exchange rate history."""
return self._client.get(
f"/api/v1/currency/exchange/{from_currency}/{to_currency}/history",
params={"days": str(days)},
)
def get_supported_currencies(self) -> dict:
"""Get list of supported currencies."""
return self._client.get("/api/v1/currency/currencies")
def refresh_exchange_rates(self) -> dict:
"""Refresh exchange rates from external sources."""
return self._client.post("/api/v1/currency/exchange/refresh", {})
def process_billing(self, billing_data: Dict[str, Any]) -> dict:
"""Process billing transaction."""
return self._client.post("/api/v1/currency/billing", billing_data)
def get_billing_history(self, profile_id: str, limit: int = 50) -> dict:
"""Get billing history for a profile."""
return self._client.get(
f"/api/v1/currency/billing/history/{profile_id}",
params={"limit": str(limit)},
)
def get_billing_summary(self, profile_id: str, period: str = "monthly") -> dict:
"""Get billing summary for a profile."""
return self._client.get(
f"/api/v1/currency/billing/summary/{profile_id}",
params={"period": period},
)
def process_refund(self, transaction_id: str, reason: str) -> dict:
"""Process a refund for a transaction."""
return self._client.post(
f"/api/v1/currency/billing/refund/{transaction_id}",
{"reason": reason},
)
def get_billing_analytics(self, period: str = "monthly") -> dict:
"""Get billing analytics."""
return self._client.get("/api/v1/currency/billing/analytics", params={"period": period})
+63
View File
@@ -0,0 +1,63 @@
"""Security API client for fraud detection and SIM swap protection."""
from typing import List, Optional, Dict, Any
from datetime import datetime
from .types import (
FraudAlert,
FraudMetrics,
FraudAlertFilter,
FraudType,
FraudSeverity,
)
class SecurityAPI:
"""Security API client for fraud detection and protection."""
def __init__(self, client):
self._client = client
def analyze_transaction(self, transaction: Dict[str, Any]) -> Optional[FraudAlert]:
"""Analyze a transaction for fraud."""
response = self._client.post("/api/v1/security/fraud/analyze", transaction)
if response and response.get("id"):
return FraudAlert(**response)
return None
def get_fraud_alerts(self, filter: Optional[FraudAlertFilter] = None) -> List[FraudAlert]:
"""Get fraud alerts with optional filtering."""
payload = {}
if filter:
payload = filter.model_dump(exclude_none=True)
response = self._client.post("/api/v1/security/fraud/alerts", payload)
return [FraudAlert(**item) for item in response]
def update_alert_status(
self, alert_id: str, status: str, actions: Optional[List[str]] = None
) -> dict:
"""Update fraud alert status."""
payload = {"status": status}
if actions:
payload["actions"] = actions
return self._client.put(f"/api/v1/security/fraud/alerts/{alert_id}", payload)
def get_fraud_metrics(self, period: str = "monthly") -> FraudMetrics:
"""Get fraud detection metrics."""
response = self._client.get("/api/v1/security/fraud/metrics", params={"period": period})
return FraudMetrics(**response)
def get_fraud_patterns(self) -> dict:
"""Get detected fraud patterns."""
return self._client.get("/api/v1/security/fraud/patterns")
def verify_sim_swap(self, profile_id: str, msisdn: str) -> dict:
"""Verify SIM swap request."""
return self._client.post(
"/api/v1/security/simswap/verify",
{"profile_id": profile_id, "msisdn": msisdn},
)
def get_sim_swap_history(self, profile_id: str) -> dict:
"""Get SIM swap history for a profile."""
return self._client.get(f"/api/v1/security/simswap/history/{profile_id}")
+207 -3
View File
@@ -79,13 +79,11 @@ class HealthStatus(BaseModel):
checks: Dict[str, Dict[str, Any]]
uptime: float = Field(ge=0.0)
class WebSocketMessage(BaseModel):
type: str
data: Dict[str, Any]
timestamp: datetime
class UsageEvent(BaseModel):
id: str
subscriber_id: str
@@ -95,7 +93,6 @@ class UsageEvent(BaseModel):
timestamp: datetime
metadata: Optional[Dict[str, Any]] = None
class RatingPlan(BaseModel):
plan_id: str
name: str
@@ -137,5 +134,212 @@ class PaginatedResponse(BaseModel):
total: int = Field(ge=0)
page: int = Field(ge=1)
page_size: int = Field(ge=1, le=100)
class ChurnRiskLevel(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class ChurnPrediction(BaseModel):
profile_id: str
risk_level: ChurnRiskLevel
risk_score: float = Field(ge=0.0, le=100.0)
predicted_churn_date: Optional[datetime] = None
reasons: List[str]
recommendations: List[str]
last_updated: datetime
class ChurnMetrics(BaseModel):
period: str
total_subscribers: int = Field(ge=0)
churned_subscribers: int = Field(ge=0)
churn_rate: float = Field(ge=0.0)
monthly_churn_rate: float = Field(ge=0.0)
annual_churn_rate: float = Field(ge=0.0)
average_tenure_days: float = Field(ge=0.0)
risk_distribution: Dict[ChurnRiskLevel, int]
generated_at: datetime
class FraudType(str, Enum):
ACCOUNT_TAKEOVER = "account_takeover"
SUBSCRIPTION_FRAUD = "subscription_fraud"
PAYMENT_FRAUD = "payment_fraud"
USAGE_ANOMALY = "usage_anomaly"
SIM_SWAP = "sim_swap"
class FraudSeverity(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class FraudAlert(BaseModel):
id: str
type: FraudType
severity: FraudSeverity
profile_id: str
description: str
risk_score: float = Field(ge=0.0, le=100.0)
evidence: List[str]
ip_address: str
timestamp: datetime
status: str
actions_taken: List[str]
metadata: Dict[str, Any]
class FraudMetrics(BaseModel):
period: str
total_alerts: int = Field(ge=0)
resolved_alerts: int = Field(ge=0)
false_positives: int = Field(ge=0)
resolution_rate_pct: float = Field(ge=0.0)
false_positive_rate_pct: float = Field(ge=0.0)
by_type: Dict[FraudType, int]
by_severity: Dict[FraudSeverity, int]
generated_at: datetime
class FraudAlertFilter(BaseModel):
type: Optional[FraudType] = None
severity: Optional[FraudSeverity] = None
status: Optional[str] = None
from_date: Optional[datetime] = None
to_date: Optional[datetime] = None
limit: Optional[int] = Field(None, ge=1, le=1000)
class MarketMetrics(BaseModel):
period: str
total_market_size: int = Field(ge=0)
our_subscribers: int = Field(ge=0)
market_share_pct: float = Field(ge=0.0)
growth_rate_pct: float = Field(ge=0.0)
by_country: Dict[str, "CountryMetrics"]
by_carrier: Dict[str, "MarketCarrierMetrics"]
by_demographic: Dict[str, "DemoMetrics"]
competitor_analysis: Dict[str, "CompetitorMetrics"]
market_opportunities: List["MarketOpportunity"]
generated_at: datetime
class CountryMetrics(BaseModel):
country: str
market_size: int = Field(ge=0)
our_subscribers: int = Field(ge=0)
market_share_pct: float = Field(ge=0.0)
growth_rate_pct: float = Field(ge=0.0)
average_revenue: float = Field(ge=0.0)
class MarketCarrierMetrics(BaseModel):
carrier_id: str
carrier_name: str
subscribers: int = Field(ge=0)
market_share_pct: float = Field(ge=0.0)
average_revenue: float = Field(ge=0.0)
quality_score: float = Field(ge=0.0, le=100.0)
class DemoMetrics(BaseModel):
segment: str
subscribers: int = Field(ge=0)
market_share_pct: float = Field(ge=0.0)
average_revenue: float = Field(ge=0.0)
growth_rate_pct: float = Field(ge=0.0)
class CompetitorMetrics(BaseModel):
name: str
market_share_pct: float = Field(ge=0.0)
subscribers: int = Field(ge=0)
average_price: float = Field(ge=0.0)
strengths: List[str]
weaknesses: List[str]
class MarketOpportunity(BaseModel):
id: str
type: str
description: str
potential_size: int = Field(ge=0)
confidence: float = Field(ge=0.0, le=100.0)
required_actions: List[str]
class PredictiveMaintenanceMetrics(BaseModel):
period: str
total_assets: int = Field(ge=0)
healthy_assets: int = Field(ge=0)
at_risk_assets: int = Field(ge=0)
critical_assets: int = Field(ge=0)
overall_health_score: float = Field(ge=0.0, le=100.0)
by_asset_type: Dict[str, "AssetTypeMetrics"]
predicted_failures: List["PredictedFailure"]
maintenance_schedule: List["MaintenanceTask"]
generated_at: datetime
class AssetTypeMetrics(BaseModel):
asset_type: str
total: int = Field(ge=0)
healthy: int = Field(ge=0)
at_risk: int = Field(ge=0)
critical: int = Field(ge=0)
health_score: float = Field(ge=0.0, le=100.0)
class PredictedFailure(BaseModel):
asset_id: str
asset_type: str
failure_type: str
predicted_date: datetime
confidence: float = Field(ge=0.0, le=100.0)
recommended_actions: List[str]
class MaintenanceTask(BaseModel):
id: str
asset_id: str
task_type: str
priority: str
scheduled_date: datetime
estimated_duration_minutes: int = Field(ge=0)
description: str
status: str
class PricingOptimizationResult(BaseModel):
rate_plan_id: str
current_price: float = Field(ge=0.0)
optimal_price: float = Field(ge=0.0)
strategy: str
expected_revenue: float = Field(ge=0.0)
expected_demand: int = Field(ge=0)
price_change_pct: float
reasoning: List[str]
risks: List[str]
recommendations: List[str]
confidence: float = Field(ge=0.0, le=100.0)
generated_at: datetime
class PricingMetrics(BaseModel):
period: str
total_rate_plans: int = Field(ge=0)
optimized_rate_plans: int = Field(ge=0)
average_price_change_pct: float
expected_revenue_impact_pct: float
churn_rate_reduction_pct: float
price_elasticity: float
competitive_index: float
optimization_roi_pct: float
generated_at: datetime
has_next: bool
has_prev: bool