Technical Architecture & ComponentsΒΆ

Technical Blueprint This document describes HOW Reqivo is built internally.

External References:


1. πŸ—οΈ High-Level DesignΒΆ

Reqivo follows a strict 3 separate layers architecture. Dependency flows always top-down: Client uses Protocol and Transport, but Transport never knows about Protocol or Client.

    USER CODE
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LAYER 1: CLIENT     β”‚ 🧠 "The Brain"
β”‚  (Session, Request)  β”‚ β€’ Maintains State (Cookies, Auth)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β€’ Decides WHAT to do
           β”‚
           β”‚ 1. Request bytes needed
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  LAYER 2: PROTOCOL   β”‚ πŸ“œ "The Translator"
β”‚ (HttpParser, Body)   β”‚ β€’ Pure Logic (No I/O)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β€’ Converts Objects <-> Bytes
           β”‚
           β”‚ 2. Delivers raw bytes
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LAYER 3: TRANSPORT   β”‚ 🚚 "The Truck"
β”‚ (Connection, Pool)   β”‚ β€’ Socket I/O & TLS
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β€’ Moves bytes A -> B
           β”‚
           β”‚ 3. Network traffic
           β–Ό
      INTERNET

Design PrinciplesΒΆ

  1. Separation of Concerns: Each layer has a single purpose.

  2. Protocol Agnostic Transport: Transport layer moves bytes, doesn’t know what HTTP is.

  3. State Isolation: Persistent state lives only in the Client layer (Session).


2. 🧩 Component Map¢

Layer 1: CLIENT (Logic & State)ΒΆ

Location: src/reqivo/client/

This is the only layer the end user imports directly.

  • Session (session.py): β€œThe Brain”.

    • Responsibility: Maintains persistent state between requests.

    • Data: Cookie Jar, Authentication credentials, Default Headers.

    • Resources: Manages ConnectionPool lifecycle.

  • Request (request.py): β€œThe Builder”.

    • Responsibility: Ephemeral object preparing data for sending.

    • Action: Validates inputs, serializes body, and delegates sending to session/transport.

  • Response (response.py): β€œThe Result”.

    • Responsibility: Parse and expose response comfortably.

    • Optimization: Uses __slots__ to reduce memory in high-throughput apps.

  • WebSocket (websocket.py): RFC 6455 Client.

    • Handles initial handshake (HTTP Upgrade).

    • Manages frame send/receive loop.

Layer 2: PROTOCOL (Communication Rules)ΒΆ

Location: src/reqivo/http/

Pure HTTP/1.1 implementation. No I/O, only memory data manipulation.

  • HttpParser (http11.py):

    • State machine for parsing responses.

    • Detects message boundaries (Content-Length vs Chunked).

  • Headers (headers.py):

    • Specialized case-insensitive dictionary (Content-Type == content-type).

  • Body (body.py):

    • Utilities for reading streams (fixed-length, chunked).

Layer 3: TRANSPORT (The Network)ΒΆ

Location: src/reqivo/transport/

In charge of moving bytes from A to B.

  • Connection (connection.py):

    • Wrapper over native socket.socket.

    • Handles TLS handshake (ssl.wrap_socket).

    • Applies socket-level timeouts.

  • ConnectionPool (connection_pool.py):

    • Store of active connections.

    • LIFO (Last-In, First-Out) Strategy: Reuses most recent connection to improve cache locality and reduce server timeout closures.


3. πŸ”„ Data FlowΒΆ

Request Lifecycle (Sync)ΒΆ

  USER              SESSION           POOL             CONNECTION         INTERNET
   β”‚                   β”‚                β”‚                  β”‚                 β”‚
   β”‚ 1. get(url)       β”‚                β”‚                  β”‚                 β”‚
   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚                β”‚                  β”‚                 β”‚
   β”‚                   β”‚ 2. get_conn()  β”‚                  β”‚                 β”‚
   β”‚                   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚                  β”‚                 β”‚
   β”‚                   β”‚                β”‚ 3. Pop LIFO      β”‚                 β”‚
   β”‚                   β”‚                β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚                 β”‚
   β”‚                   β”‚                β”‚                  β”‚                 β”‚
   β”‚                   β”‚   4. send()    β”‚                  β”‚ 5. write()      β”‚
   β”‚                   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚
   β”‚                   β”‚                β”‚                  β”‚                 β”‚
   β”‚                   β”‚                β”‚                  β”‚ 6. read()       β”‚
   β”‚                   β”‚   7. parse()   β”‚                  │◄─────────────────
   β”‚                   │◄───────────────────────────────────                 β”‚
   β”‚                   β”‚                β”‚                  β”‚                 β”‚
   β”‚                   β”‚ 8. put_conn()  β”‚                  β”‚                 β”‚
   β”‚                   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚                  β”‚                 β”‚
   β”‚ 9. Response       β”‚                β”‚                  β”‚                 β”‚
   │◄───────────────────                β”‚                  β”‚                 β”‚
  1. Preparation: Session combines user headers + cookie jar + auth headers.

  2. Acquisition: Connection requested from ConnectionPool. If one alive exists for that host (LIFO), it’s used; else, open socket + TLS.

  3. Transmission: Raw bytes sent via socket.

  4. Reception: Bytes read until headers complete.

  5. Parsing: HttpParser validates and structures response.

  6. Release: Connection returned to pool for reuse.


4. ⚑ Concurrency Model¢

Reqivo is Async-First. This means the β€œtrue” implementation is asynchronous.

Sync/Async DualityΒΆ

To avoid duplicating complex logic, Reqivo uses a Synchronous Wrapper pattern:

  1. Base Code: All Protocol and Utilities code is shared (pure CPU-bound).

  2. Native IO: Two Transport implementations exist:

    • AsyncConnection: Uses asyncio.StreamReader/Writer.

    • Connection: Uses blocking socket.

  3. Client:

    • AsyncSession: Uses AsyncConnection and await.

    • Session: Uses Connection and blocks current thread.

Note: Unlike other libraries wrapping async code in a hidden loop (overhead), Reqivo implements the synchronous transport layer natively with blocking sockets for maximum performance in sync contexts.


5. πŸ›‘οΈ Security & RobustnessΒΆ

Error HandlingΒΆ

The system transforms low-level errors (socket.timeout, ssl.SSLError) into semantic Reqivo exceptions before reaching Client layer.

  • ConnectTimeout: Failure establishing TCP/TLS.

  • ReadTimeout: Failure waiting for data (TTFB or body gap).

  • TlsError: Certificate validation failure.

Resource SafetyΒΆ

  • Context Managers: Using with Session() guarantees socket closure.

  • Finalizers: ConnectionPool attempts to clean up connections when collected by GC (best effort).