feat: API client now reads URL/token from config before each scheduled request

- Added _refresh_endpoints_from_config() method that checks for URL/token changes
- Called before each scheduled request to ensure config changes are immediately applied
- URL changes trigger endpoint URL updates for fastapi_main, reports_sync, reports_last_sync
- Token changes update authentication configuration and enable/disable endpoints accordingly
- Interval changes are also detected and applied dynamically
- Combined with existing immediate trigger on config save, this ensures seamless config updates
parent 5f5391c7
...@@ -2263,11 +2263,94 @@ class APIClient(ThreadedComponent): ...@@ -2263,11 +2263,94 @@ class APIClient(ThreadedComponent):
logger.info("APIClient thread ended") logger.info("APIClient thread ended")
def _execute_scheduled_requests(self): def _execute_scheduled_requests(self):
"""Execute API requests that are due""" """Execute API requests that are due
This method also refreshes endpoint configuration from database before each
scheduled request to ensure any URL/token changes are immediately applied.
"""
# Refresh endpoint configuration from database before checking scheduled requests
# This ensures URL/token changes are picked up without requiring restart
self._refresh_endpoints_from_config()
for endpoint in self.endpoints.values(): for endpoint in self.endpoints.values():
if endpoint.should_execute(): if endpoint.should_execute():
self._execute_endpoint_request(endpoint) self._execute_endpoint_request(endpoint)
def _refresh_endpoints_from_config(self):
"""Refresh endpoint configuration from database/config before each scheduled request.
This ensures that URL and token changes made from the dashboard are immediately
applied to the next scheduled API request without requiring application restart.
"""
try:
# Get current API configuration from config manager
api_config = self.config_manager.get_section_config("api") or {}
# Get current values
current_url = api_config.get("fastapi_url", "").strip()
current_token = api_config.get("api_token", "").strip()
current_interval = api_config.get("api_interval", 1800)
# Get the fastapi_main endpoint
fastapi_endpoint = self.endpoints.get("fastapi_main")
if not fastapi_endpoint:
return
# Check if URL has changed
current_endpoint_url = fastapi_endpoint.url
new_endpoint_url = current_url.rstrip('/') + "/api/updates" if current_url else None
if new_endpoint_url and current_endpoint_url != new_endpoint_url:
logger.info(f"URL change detected - updating endpoint from '{current_endpoint_url}' to '{new_endpoint_url}'")
fastapi_endpoint.url = new_endpoint_url
# Also update reports_sync and reports_last_sync URLs
reports_sync = self.endpoints.get("reports_sync")
reports_last_sync = self.endpoints.get("reports_last_sync")
if reports_sync:
reports_sync.url = current_url.rstrip('/') + "/api/reports/sync"
if reports_last_sync:
reports_last_sync.url = current_url.rstrip('/') + "/api/reports/last-sync"
# Check if token has changed
current_auth_token = ""
if fastapi_endpoint.auth and fastapi_endpoint.auth.get('type') == 'bearer':
current_auth_token = fastapi_endpoint.auth.get('token', '').strip()
if current_token != current_auth_token:
logger.info(f"Token change detected - updating authentication (token length: {len(current_token)} chars)")
if current_token:
fastapi_endpoint.auth = {
"type": "bearer",
"token": current_token
}
# Enable endpoint when token is available
fastapi_endpoint.enabled = True
fastapi_endpoint.retry_attempts = 10
fastapi_endpoint.retry_delay = 30
# Also update auth for reports endpoints
for ep_name in ['reports_sync', 'reports_last_sync']:
ep = self.endpoints.get(ep_name)
if ep:
ep.auth = {"type": "bearer", "token": current_token}
ep.enabled = True
else:
# No token - disable endpoint
fastapi_endpoint.auth = None
fastapi_endpoint.enabled = False
logger.info("No token configured - disabling API endpoint")
# Update interval if changed
if current_interval and fastapi_endpoint.interval != current_interval:
logger.info(f"Interval change detected - updating from {fastapi_endpoint.interval}s to {current_interval}s")
fastapi_endpoint.interval = current_interval
except Exception as e:
logger.error(f"Failed to refresh endpoints from config: {e}")
def _get_last_fixture_timestamp(self) -> Optional[str]: def _get_last_fixture_timestamp(self) -> Optional[str]:
"""Get the server activation timestamp of the last active fixture in the database""" """Get the server activation timestamp of the last active fixture in the database"""
try: try:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment