mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 02:52:53 +00:00
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:
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
@@ -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."""
|
||||
|
||||
@@ -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})
|
||||
@@ -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}")
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user