Skip to content

sonic182/aiosonic

Repository files navigation

github status Coverage Status PyPI version Documentation Status Discord

aiosonic - lightweight Python asyncio HTTP/WebSocket client

A very fast, lightweight Python asyncio HTTP/1.1, HTTP/2, and WebSocket client.

The repository is hosted on GitHub.

For full documentation, please see aiosonic docs.

Features

  • Keepalive support and smart pool of connections
  • Multipart file uploads
  • Handling of chunked responses and requests
  • Connection timeouts and automatic decompression
  • Automatic redirect following
  • Fully type-annotated
  • WebSocket support
  • (Nearly) 100% test coverage
  • HTTP/2 (BETA; enabled with a flag)

Requirements

  • Python >= 3.8 (or PyPy 3.8+)

Installation

pip install aiosonic

Getting Started

Below is an example demonstrating basic HTTP client usage:

import asyncio
import aiosonic
import json

async def run():
    client = aiosonic.HTTPClient()

    # Sample GET request
    response = await client.get('https://www.google.com/')
    assert response.status_code == 200
    assert 'Google' in (await response.text())

    # POST data as multipart form
    url = "https://postman-echo.com/post"
    posted_data = {'foo': 'bar'}
    response = await client.post(url, data=posted_data)
    assert response.status_code == 200
    data = json.loads(await response.content())
    assert data['form'] == posted_data

    # POST data as JSON
    response = await client.post(url, json=posted_data)
    assert response.status_code == 200
    data = json.loads(await response.content())
    assert data['json'] == posted_data

    # GET request with timeouts
    from aiosonic.timeout import Timeouts
    timeouts = Timeouts(sock_read=10, sock_connect=3)
    response = await client.get('https://www.google.com/', timeouts=timeouts)
    assert response.status_code == 200
    assert 'Google' in (await response.text())

    print('HTTP client success')

if __name__ == '__main__':
    asyncio.run(run())

WebSocket Usage

Below is an example demonstrating how to use aiosonic's WebSocket support:

import asyncio
from aiosonic import WebSocketClient

async def main():
    # Replace with your WebSocket server URL
    ws_url = "ws://localhost:8080"
    async with WebSocketClient() as client:
        async with await client.connect(ws_url) as ws:
            # Send a text message
            await ws.send_text("Hello WebSocket")
            
            # Receive an echo response
            response = await ws.receive_text()
            print("Received:", response)
            
            # Send a ping and wait for the pong
            await ws.ping(b"keep-alive")
            pong = await ws.receive_pong()
            print("Pong received:", pong)
            
            # Gracefully close the connection
            await ws.close(code=1000, reason="Normal closure")

if __name__ == "__main__":
    asyncio.run(main())

Benchmarks

A simple performance benchmark script is included in the tests folder. For example:

python tests/performance.py

Example output:

doing tests...
{
 "aiosonic": "1000 requests in 105.53 ms",
 "aiosonic cyclic": "1000 requests in 104.08 ms",
 "aiohttp": "1000 requests in 184.51 ms",
 "requests": "1000 requests in 1644.21 ms"
}
aiosonic is 74.84% faster than aiohttp
aiosonic is 1457.99% faster than requests
aiosonic is -1.38% faster than aiosonic cyclic

Note:
These benchmarks are basic and machine-dependent. They are intended as a rough comparison.

  • HTTP/2:
    • GET requests
    • Requests with data sending
    • Stable HTTP/2 release
  • Better documentation
  • International domains and URLs (IDNA + cache)
  • Basic/Digest authentication
  • HTTP proxy support
  • Sessions with cookie persistence
  • Elegant key/value cookies

Development

Install development dependencies with Poetry:

poetry install

It is recommended to install Poetry in a separate virtual environment (via apt, pacman, etc.) rather than in your development environment. You can configure Poetry to use an in-project virtual environment by running:

poetry config virtualenvs.in-project true

Running Tests

poetry run pytest

Contributing

  1. Fork the repository.
  2. Create a branch named feature/your_feature.
  3. Commit your changes, push, and submit a pull request.

Thanks for contributing!

Contributors

Contributors