Spaces:
Sleeping
Sleeping
File size: 7,350 Bytes
d80bf0f 403c184 a3a4e3f d80bf0f a758bd8 a3a4e3f d80bf0f a3a4e3f d80bf0f 403c184 d80bf0f 403c184 d80bf0f 403c184 d80bf0f 403c184 d80bf0f 403c184 d80bf0f 7e3a96a d80bf0f e7c4b2b 7e3a96a d118535 7e3a96a a3a4e3f d80bf0f a3a4e3f a758bd8 a3a4e3f a758bd8 a3a4e3f a758bd8 a3a4e3f d80bf0f a3a4e3f d80bf0f a3a4e3f d80bf0f a3a4e3f d80bf0f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
"""
Configuration management for Hugging Face Spaces deployment
Handles environment variables and application settings
"""
import os
from typing import Dict, Any
from dotenv import load_dotenv
# Load environment variables from .env file if it exists (for local development)
load_dotenv()
class Config:
"""Application configuration management"""
def __init__(self):
# No automatic environment variable loading - tokens come from Gradio interface only
self.wildberries_api_token = None
# Official Wildberries API URLs based on documentation
self.wildberries_base_url = "https://statistics-api.wildberries.ru"
self.wildberries_content_url = "https://content-api.wildberries.ru"
self.wildberries_analytics_url = "https://seller-analytics-api.wildberries.ru"
self.wildberries_common_url = "https://common-api.wildberries.ru"
self.wildberries_marketplace_url = "https://marketplace-api.wildberries.ru"
self.wildberries_supplies_url = "https://supplies-api.wildberries.ru"
# Rate limiting settings (based on official documentation)
# Statistics API: Maximum of 300 requests per minute
self.rate_limit_requests = 300 # requests per minute
self.rate_limit_window = 60 # seconds
# Request timeout settings
self.request_timeout = 30 # seconds
self.max_retries = 3
self.retry_backoff_factor = 2
# Application settings
self.demo_mode = True # Always start in demo mode, users provide tokens via UI
self.debug_mode = os.getenv("DEBUG", "false").lower() == "true"
# Hugging Face Spaces specific settings
self.hf_space_id = os.getenv("SPACE_ID")
self.hf_space_author = os.getenv("SPACE_AUTHOR_NAME")
# Gradio settings
self.gradio_analytics = os.getenv("GRADIO_ANALYTICS_ENABLED", "false").lower() == "true"
self.gradio_theme = os.getenv("GRADIO_THEME", "soft")
def get_api_headers(self, api_token: str = None) -> Dict[str, str]:
"""Get headers for Wildberries API requests"""
headers = {
"Content-Type": "application/json",
"User-Agent": "Wildberries-Analytics-Dashboard/1.0"
}
if api_token:
headers["Authorization"] = f"Bearer {api_token}"
return headers
def get_rate_limit_config(self) -> Dict[str, Any]:
"""Get rate limiting configuration"""
return {
"requests_per_minute": self.rate_limit_requests,
"window_seconds": self.rate_limit_window,
"backoff_factor": self.retry_backoff_factor
}
def is_configured(self, api_token: str = None) -> bool:
"""Check if the application is properly configured with API token"""
return api_token is not None and len(api_token.strip()) > 0
def get_endpoints(self) -> Dict[str, str]:
"""Get API endpoint configurations based on working API calls"""
return {
# Statistics API endpoints - Correct sales endpoint
"sales": f"{self.wildberries_base_url}/api/v1/supplier/sales",
"orders": f"{self.wildberries_base_url}/api/v5/supplier/reportDetailByPeriod",
"stocks": f"{self.wildberries_base_url}/api/v1/supplier/stocks",
"incomes": f"{self.wildberries_base_url}/api/v5/supplier/reportDetailByPeriod",
"reportDetailByPeriod": f"{self.wildberries_base_url}/api/v5/supplier/reportDetailByPeriod",
# Analytics API endpoints
"analytics": f"{self.wildberries_analytics_url}/api/v2/nm-report/detail",
# Content API endpoints
"content": f"{self.wildberries_content_url}/content/v1/cards/cursor/list",
# Common API endpoints
"news": f"{self.wildberries_common_url}/api/communications/v2/news",
"seller_info": f"{self.wildberries_common_url}/api/v1/seller-info",
# Connection check endpoints for each service
"ping_statistics": f"{self.wildberries_base_url}/ping",
"ping_content": f"{self.wildberries_content_url}/ping",
"ping_analytics": f"{self.wildberries_analytics_url}/ping",
"ping_common": f"{self.wildberries_common_url}/ping",
"ping_marketplace": f"{self.wildberries_marketplace_url}/ping",
"ping_supplies": f"{self.wildberries_supplies_url}/ping"
}
def validate_token(self, token: str) -> bool:
"""Validate the format of a Wildberries API token (JWT format)"""
if not token:
return False
# Wildberries tokens are JWT format based on official documentation
try:
# Check if it looks like a JWT (three parts separated by dots)
parts = token.split('.')
if len(parts) != 3:
return False
# Check minimum length (JWT tokens are typically longer)
if len(token) < 50:
return False
return True
except Exception:
return False
def get_demo_settings(self) -> Dict[str, Any]:
"""Get settings for demo mode"""
return {
"demo_products_count": 15,
"demo_sales_days": 30,
"demo_revenue_range": (10000, 500000), # rubles
"demo_stock_range": (0, 1000),
"demo_categories": [
"Одежда", "Обувь", "Аксессуары", "Красота",
"Дом и сад", "Спорт", "Электроника", "Книги"
]
}
def __repr__(self) -> str:
"""String representation of configuration"""
return f"""
Wildberries Analytics Dashboard Configuration:
- Demo Mode: {self.demo_mode}
- Debug Mode: {self.debug_mode}
- API Configured: {self.is_configured()}
- Rate Limit: {self.rate_limit_requests}/min
- HF Space: {self.hf_space_author}/{self.hf_space_id if self.hf_space_id else 'local'}
"""
# Global configuration instance
_config = None
def get_config() -> Config:
"""Get the global configuration instance"""
global _config
if _config is None:
_config = Config()
return _config
def reload_config() -> Config:
"""Reload configuration (useful for testing)"""
global _config
_config = Config()
return _config
# Environment validation for Hugging Face Spaces
def validate_hf_environment():
"""Validate that we're running in a proper HF Spaces environment"""
config = get_config()
issues = []
if not config.wildberries_api_token:
issues.append("WILDBERRIES_API_TOKEN not set - running in demo mode")
if config.wildberries_api_token and not config.validate_token(config.wildberries_api_token):
issues.append("WILDBERRIES_API_TOKEN appears to be invalid format")
return issues
# Export commonly used configurations
DEFAULT_CONFIG = get_config()
API_ENDPOINTS = DEFAULT_CONFIG.get_endpoints()
RATE_LIMIT_CONFIG = DEFAULT_CONFIG.get_rate_limit_config()
DEMO_SETTINGS = DEFAULT_CONFIG.get_demo_settings() |