Route all HTTP calls through SiloClient instead of direct urllib.request #30

Open
opened 2026-02-16 16:49:10 +00:00 by forbes · 0 comments
Owner

Summary

Several HTTP calls in the FreeCAD layer bypass the SiloClient from the silo-client submodule and use urllib.request directly. This creates inconsistency in authentication handling, SSL configuration, error handling, and timeout management. The silo-client submodule exists specifically to be the single HTTP abstraction — all requests should go through it.

Direct urllib.request Calls That Bypass SiloClient

1. Server readiness check — silo_commands.py:~179-200

Manually constructs SSL context and sets timeout against {base_url}/ready. No auth header.

2. Schema properties fetch — schema_form.py:~273-280

Fetches {api_url}/schemas/kindred-rd/properties?category={cat} with manually built auth headers, SSL context, and timeout. Also hardcodes the schema name.

3. Part number generation — schema_form.py:~293-301

POSTs to {api_url}/generate-part-number with manually built auth headers, SSL context, and timeout. Hardcodes the schema name.

4. SSE event stream — silo_commands.py:~2438-2445

Connects to {api_url}/events with Accept: text/event-stream header. Manually builds auth headers, SSL context, and timeout (90s).

5. Diagnostics — silo_commands.py:~3904-3970

Tests /health, /ready, /auth/me, and /events endpoints all with direct urllib.request calls, each with manually configured SSL and timeouts.

Problems

  1. Auth drift: If SiloClient changes its auth header format (e.g. adding request signing), the direct calls will not pick it up.
  2. SSL inconsistency: Each call site builds its own SSL context via _get_ssl_context() — a parallel implementation to whatever SiloClient does internally.
  3. Error handling fragmentation: SiloClient presumably has unified error handling (retries, status code mapping, logging). Direct calls do ad-hoc try/except with varying behavior.
  4. Timeout scatter: Each call site picks its own timeout (5s, 10s, 90s) as a magic number.
  5. Missing from client surface: If SiloClient does not expose these endpoints yet, they should be added to it — that is the point of the shared client.

Proposed Solution

Add missing methods to silo-client (in the submodule repo)

The following methods should be added to SiloClient:

  • check_ready() — GET /ready
  • get_schema_properties(schema, category) — GET /schemas/{schema}/properties
  • generate_part_number(schema, category) — POST /generate-part-number
  • open_event_stream() — GET /events (returns raw response for SSE parsing)
  • check_health() — GET /health
  • check_auth() — GET /auth/me

Update FreeCAD layer to use them

  • _fetch_server_mode() should call _client.check_ready()
  • _SchemaPropertiesWorker should call _client.get_schema_properties(schema, category)
  • _PartNumberWorker should call _client.generate_part_number(schema, category)
  • SiloEventListener should call _client.open_event_stream()
  • _DiagWorker should call _client.check_health(), _client.check_ready(), _client.check_auth()

Remove from FreeCAD layer

  • _get_ssl_context() helper (delegate to client)
  • All direct urllib.request imports and usage in silo_commands.py and schema_form.py
  • Manual auth header construction in schema_form.py

Acceptance Criteria

  • No direct urllib.request calls remain in the FreeCAD layer
  • All HTTP requests flow through SiloClient methods
  • SSL context is managed exclusively by the client
  • Auth headers are managed exclusively by the client
  • SSE stream connection is initiated through the client (the FreeCAD layer still reads/parses the stream)
  • Diagnostics use client methods with appropriate error reporting
## Summary Several HTTP calls in the FreeCAD layer bypass the `SiloClient` from the `silo-client` submodule and use `urllib.request` directly. This creates inconsistency in authentication handling, SSL configuration, error handling, and timeout management. The `silo-client` submodule exists specifically to be the single HTTP abstraction — all requests should go through it. ## Direct urllib.request Calls That Bypass SiloClient ### 1. Server readiness check — silo_commands.py:~179-200 Manually constructs SSL context and sets timeout against `{base_url}/ready`. No auth header. ### 2. Schema properties fetch — schema_form.py:~273-280 Fetches `{api_url}/schemas/kindred-rd/properties?category={cat}` with manually built auth headers, SSL context, and timeout. Also hardcodes the schema name. ### 3. Part number generation — schema_form.py:~293-301 POSTs to `{api_url}/generate-part-number` with manually built auth headers, SSL context, and timeout. Hardcodes the schema name. ### 4. SSE event stream — silo_commands.py:~2438-2445 Connects to `{api_url}/events` with `Accept: text/event-stream` header. Manually builds auth headers, SSL context, and timeout (90s). ### 5. Diagnostics — silo_commands.py:~3904-3970 Tests `/health`, `/ready`, `/auth/me`, and `/events` endpoints all with direct `urllib.request` calls, each with manually configured SSL and timeouts. ## Problems 1. **Auth drift**: If `SiloClient` changes its auth header format (e.g. adding request signing), the direct calls will not pick it up. 2. **SSL inconsistency**: Each call site builds its own SSL context via `_get_ssl_context()` — a parallel implementation to whatever `SiloClient` does internally. 3. **Error handling fragmentation**: `SiloClient` presumably has unified error handling (retries, status code mapping, logging). Direct calls do ad-hoc try/except with varying behavior. 4. **Timeout scatter**: Each call site picks its own timeout (5s, 10s, 90s) as a magic number. 5. **Missing from client surface**: If `SiloClient` does not expose these endpoints yet, they should be added to it — that is the point of the shared client. ## Proposed Solution ### Add missing methods to silo-client (in the submodule repo) The following methods should be added to `SiloClient`: - `check_ready()` — GET /ready - `get_schema_properties(schema, category)` — GET /schemas/{schema}/properties - `generate_part_number(schema, category)` — POST /generate-part-number - `open_event_stream()` — GET /events (returns raw response for SSE parsing) - `check_health()` — GET /health - `check_auth()` — GET /auth/me ### Update FreeCAD layer to use them - `_fetch_server_mode()` should call `_client.check_ready()` - `_SchemaPropertiesWorker` should call `_client.get_schema_properties(schema, category)` - `_PartNumberWorker` should call `_client.generate_part_number(schema, category)` - `SiloEventListener` should call `_client.open_event_stream()` - `_DiagWorker` should call `_client.check_health()`, `_client.check_ready()`, `_client.check_auth()` ### Remove from FreeCAD layer - `_get_ssl_context()` helper (delegate to client) - All direct `urllib.request` imports and usage in `silo_commands.py` and `schema_form.py` - Manual auth header construction in `schema_form.py` ## Acceptance Criteria - [ ] No direct `urllib.request` calls remain in the FreeCAD layer - [ ] All HTTP requests flow through `SiloClient` methods - [ ] SSL context is managed exclusively by the client - [ ] Auth headers are managed exclusively by the client - [ ] SSE stream connection is initiated through the client (the FreeCAD layer still reads/parses the stream) - [ ] Diagnostics use client methods with appropriate error reporting
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/silo-mod#30