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_apiat 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.propertiesand JSON configs inevercycle-api/config/.
- api_client.py (Generic HTTP Client)
Low-level
requests.Sessionwrapper.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.propertiesinto 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
Client calls
POST /api/authwith Evercycle credentials.api_server.pyforwards the request tohttps://api.evercycle.io/v1/auth/signin.Tokens (
AccessToken,IdToken,RefreshToken) are stored inauth.propertiesinside theevercycle-apidirectory.Subsequent calls to
/api/<api_name>triggerrefresh_auth_token().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.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_ORIGINSrestricts actualAccess-Control-Allow-Originto: *http://localhost:3000*http://127.0.0.1:3000*https://ui.veraetime.net*https://*.ngrok.io*https://*.ngrok-free.appPreflight
OPTIONSrequests return permissive headers for any origin to avoid preflight failures, but credentialed requests still require a matching origin on the actual call.