api_server.py
The Flask REST server that exposes the Evercycle API over HTTP.
Global Configuration
- api_server.ALLOWED_ORIGINS: list[str]
List of origins permitted to make CORS requests.
- api_server.token_expiry: datetime | None
Global variable tracking when the current access token expires.
- api_server.refresh_token: str
Global variable holding the refresh token.
- api_server.token_refresh_lock: threading.Lock
Reentrant lock used to prevent concurrent token refresh operations.
Functions
- api_server.is_origin_allowed(origin)
Check if an origin is in the allowed list or matches a wildcard pattern.
- Parameters:
origin (str) – The Origin header value.
- Returns:
True if allowed, False otherwise.
- api_server.add_cors_headers(response)
Flask
after_requesthandler that injects CORS headers for allowed origins.- Parameters:
response – Flask Response object.
- Returns:
Modified Response object.
- api_server.handle_options(path)
Handle CORS preflight OPTIONS requests for any path.
- Parameters:
path (str) – The request path (captured by Flask routing).
- Returns:
Empty 200 response with CORS headers.
- api_server.is_token_valid()
Check if the current token is still valid (with a 60-second buffer).
- Returns:
True if valid, False otherwise.
- api_server.refresh_auth_token()
Refresh the authentication token if needed.
Uses a lock to prevent race conditions. Attempts token refresh via the Evercycle refresh endpoint first. Falls back to re-authentication using
config/auth-signin.jsonif refresh fails or no refresh token exists.- Returns:
True if a valid token is available, False otherwise.
Flask Routes
- api_server.health_check()
- GET /health
Health check endpoint. Always returns
{"status": "ok", ...}.
- api_server.authenticate()
- POST /api/auth
Authenticate with the Evercycle API.
Expects JSON body with
usernameandpassword. On success, stores tokens globally and inauth.properties.
- api_server.call_api(api_name)
- ANY /api/<api_name>
Dynamic proxy endpoint for any configured Evercycle API.
Special handling per API:
get-asset-id(GET or POST): extractsid, monkey-patchesapi_client.call_apito inject the asset ID into the URL path.edit-asset-id(PUT): extractsidfrom body, merges body with defaults from config, overrides path to/v1/asset/{id}.grade(PUT): extractsidandgradefrom body, merges remaining fields with defaults, overrides path to/v1/pricebook/{id}/{grade}.create,single-confirm,create-request(POST): merges request JSON with default body from config, passes merged JSON tocall_api.
Implements a retry loop (max 2 attempts). On auth failure (401, token expired, Unauthorized), it forces a token refresh and retries once.
- Parameters:
api_name (str) – The API config name (e.g.,
get-all).- Returns:
JSON response with
status,dataormessage,raw_output, anddetailed_erroron failure.
- api_server.main()
Entry point for running the Flask development server from the command line.
Parses
--port,--host, and--debugarguments and callsapp.run().