Skip to main content

Lightweight, hackable HTTP client with adapter switching and middleware

Project description

lightreq

pipeline test coverage

lightreq is a lightweight, extensible and composable HTTP client for Python built around the chain-of-responsibility pattern. It provides a simple unified interface over different HTTP backend adapters (like urllib and requests) and features a middleware layer architecture to easily inject logic before or after making HTTP requests

Features

  • Unified Interface. Use the same clean API regardless of the underlying HTTP engine
  • Adapters. Comes with built-in adapters for urllib (no external dependencies) and requests (with connection pooling)
  • Middleware Architecture. Easily compose behaviors like retries and logging mechanism during your HTTP requests
  • Built-in Middlewares. Includes basic out-of-the-box logging and retry middlewares
  • Helpful Response Object. Unified Response object provide easy access to status codes, headers, plain text, and JSON body

Installation

To install lightreq itself, you can use pip:

pip install lightreq

You can use the built-in urllib adapter without any external dependencies, but if you want to use the requests adapter (highly recommended for production for connection pooling), you will need to install the requests library:

pip install requests

Quick Start

from src.client import HttpClient
from src.middleware import logging, retry

# init client using the 'requests' adapter and applying basic middlewares
client = HttpClient(
    adapter="requests",
    middleware=[logging(), retry(retries=3)]
)

# performed a GET request
response = client.get(url="https://jsonplaceholder.typicode.com/todos/1")

# extract HTTP properties from the unified Response object
print(response.is_ok())       # True
print(response.status_code)   # 200
print(response.json())        # {'userId': 1, 'id': 1, 'title': 'delectus aut autem', ...}
print(response.elapsed)       # 0.123 (time taken in seconds)
print(response.body)          # b'{\n  "userId": 1, ...}' (in raw bytes)

# close active adapter connections
client.close()

Architecture

Adapters

Adapters possibly considered as the core engine of the lightreq. They define how exactly an HTTP request is dispatched, and it's consisted of:

  • UrllibAdapter ("urllib"): Ideal for environments where external dependencies are strictly prohibited
  • RequestsAdapter ("requests"): Ideal for more complex applications requiring connection pooling or advanced session persistence

At the moment, it only supported 2 adapters, but it's designed to be extensible to support more adapters in the future such as aiohttp and httpx. Stay tuned!

Middleware

Middlewares act as wrappers around your core request handler. They are executed in a chain, which lets them intercept and modify the Request object before being sent, or intercept the Response object before returning it to the client

You can create custom middleware using closures like, such as:

def my_custom_middleware(next_handler):
    def handler(request):
        # Do something before the request is sent
        print("Sending request to:", request.url)
        
        # Pass to the next handler/middleware
        response = next_handler(request)
        
        # Do something with the response
        print("Received status code:", response.status_code)
        
        return response
    return handler

Caution: The order of middleware matters. They are executed in the order they are defined, and it's important to ensure that they are properly chained together. For example, if you have a retry middleware, it should be placed before any logging middleware to ensure that retries are logged correctly. Keep in mind that the execution flow will:

logging middleware -> retry middleware -> adapter (actual HTTP request)

API Reference

HttpClient

The core client interface of the lightreq. Compromised of:

  • __init__(adapter="urllib", middleware=None, **config): Initializes the client.
  • get(url, **kwargs), post(url, **kwargs), put(url, **kwargs), delete(url, **kwargs): Convenience methods for common HTTP verbs. But somehow, it only supported 4 common HTTP methods
  • close(): Cleans up the adapter (for example closes connection pools)

Response

A custom object providing standard methods for interacting with HTTP responses, compromised of:

  • status_code: (int) The HTTP status code
  • headers: (dict) Dictionary of HTTP response headers
  • body: (bytes) Raw response body
  • elapsed: (float) The time taken to complete the request
  • text(): Returns the string decoded response body
  • json(): Parses the response body as JSON
  • is_ok(): Checks if the status is within the 2xx range
  • raise_for_status(): Throws an Exception if the status code indicates an error (4xx or 5xx)

Background

I built this library because I wanted to implement an HTTP client from scratch with zero external dependencies. Along the way, it evolved into an extensible architecture that can be managed with other libraries (like my favorite, requests). Ultimately, this project serves as an educational exercise for the sake of unlearning how we manage HTTP requests and responses

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lightreq-0.1.0.tar.gz (6.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lightreq-0.1.0-py3-none-any.whl (4.7 kB view details)

Uploaded Python 3

File details

Details for the file lightreq-0.1.0.tar.gz.

File metadata

  • Download URL: lightreq-0.1.0.tar.gz
  • Upload date:
  • Size: 6.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for lightreq-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6a391ff1accd1630433dc820287d311a0ef31570b518c09270a2aaf59c60be75
MD5 1d95de7b072666e808ed7c3ec6a2746b
BLAKE2b-256 ffd301a42cb4d18bf91c230e8418fd8fc8f07a5b73dba61193570ef47ffb861a

See more details on using hashes here.

File details

Details for the file lightreq-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lightreq-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 4.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for lightreq-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a269fd548ae4124576d81f1d8fad0b2b7804fbd29d16fefb7d99a1b6bd4f468
MD5 f89dd52f49175e9e7b78251bce264405
BLAKE2b-256 041ade225d7dcf26fe9eae3649ce00c6f6bf461413a57f53cc1526bb085d0223

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page