Architecture

High-Level Flow

+------------------+     HTTPS      +------------------+
|   Web Browser    | <----------->  |  Caddy (Host)    |
|  or API Consumer |                | 70.88.205.138    |
+------------------+                +------------------+
                                           |
                                           | reverse proxy
                                           v
+------------------+     HTTP       +------------------+
|  CT 400          | <----------->  |  Flask Server    |
| evercycle-api    |   port 5000    |  api_server.py   |
| 10.1.10.173      |                +------------------+
+------------------+                       |
                                           | requests
                                           v
+------------------+     HTTPS      +------------------+
|  Auth cache      |                | Evercycle Cloud  |
| auth.properties  |                | api.evercycle.io |
+------------------+                +------------------+

Component Responsibilities

api_server.py (Flask REST Server)
  • Exposes HTTP endpoints for health checks, auth, listing, and dynamic API proxying.

  • Manages token lifecycle (acquire, refresh, expiry check) via a background lock.

  • Patches EvercycleApiClient.call_api at runtime for certain endpoints (e.g., get-asset-id) to inject path parameters into the URL.

evercycle_api.py (CLI Client)
  • Command-line tool for auth, listing, and calling APIs.

  • Reads/writes auth.properties and JSON configs in evercycle-api/config/.

api_client.py (Generic HTTP Client)
  • Low-level requests.Session wrapper.

  • Supports endpoint discovery, interactive mode, and request/response history.

api_runner.py (Config Generator & Runner)
  • Parses markdown API specs to generate JSON configs.

  • Runs individual or all APIs in sequence.

  • Auto-injects tokens from auth.properties into config headers after sign-in.

evercycle_api_runner.py (Interactive TUI)
  • Menu-driven interactive tool for calling endpoints.

  • Prompts for headers, path params, query params, and body fields at runtime.

Data Flow for an Authenticated Request

  1. Client calls POST /api/auth with Evercycle credentials.

  2. api_server.py forwards the request to https://api.evercycle.io/v1/auth/signin.

  3. Tokens (AccessToken, IdToken, RefreshToken) are stored in auth.properties inside the evercycle-api directory.

  4. Subsequent calls to /api/<api_name> trigger refresh_auth_token().

  5. If the token is expired, the server attempts a refresh using the Evercycle refresh endpoint; if that fails, it re-authenticates using config/auth-signin.json.

  6. The API call is executed by EvercycleApiClient.call_api, which: * Loads the JSON config for the requested API * Substitutes path parameters * Injects auth headers * Dispatches the HTTP request * Returns the JSON response

CORS Architecture

  • flask_cors.CORS(app) is applied globally.

  • ALLOWED_ORIGINS restricts actual Access-Control-Allow-Origin to: * http://localhost:3000 * http://127.0.0.1:3000 * https://ui.veraetime.net * https://*.ngrok.io * https://*.ngrok-free.app

  • Preflight OPTIONS requests return permissive headers for any origin to avoid preflight failures, but credentialed requests still require a matching origin on the actual call.