Skip to main content

Async-first Python speed test library for measuring network throughput

Project description

pyasyncspeedtest

An async-first Python library for measuring network throughput via HTTP-based speed tests. Designed to be embedded into async applications, services, and workers.

Why This Exists

Most speedtest tools are designed as end-user CLI applications and rely on synchronous HTTP clients or threading. This makes them awkward to integrate into async Python applications (FastAPI services, async workers, aiohttp-based tools) without blocking the event loop or spawning threads.

pyasyncspeedtest provides a reusable async library that integrates cleanly with asyncio-based applications. It uses aiohttp for all network operations and follows async Python conventions.

Features

  • Async server discovery and latency-based selection
  • Concurrent download and upload speed measurement
  • Geographic distance filtering using Haversine calculation
  • Configurable test durations and server selection criteria
  • Optional source address binding for multi-homed hosts
  • Minimal dependencies (only aiohttp)
  • No threads, no global state, no blocking I/O

Non-goals

This library measures application-level HTTP performance, not low-level network behavior. It does not:

  • Perform kernel-level TCP benchmarking
  • Measure raw socket throughput
  • Replace iperf, netperf, or similar tools
  • Claim to measure congestion control behavior or packet loss
  • Provide CLI-first user experience (library-first design)

Results reflect HTTP transfer speeds as seen by an async Python application, including all protocol overhead.

Installation

pip install pyasyncspeedtest

Requires Python 3.10 or later.

Basic Usage

import asyncio

from pyasyncspeedtest import AsyncSpeedtest


async def main():
    st = AsyncSpeedtest()
    print("Finding best server...")
    server = await st.get_best_server()

    if server:
        print(f"Server: {server['name']}, {server['country']}")

        print("Testing download speed...")
        await st.measure_download_speed()

        print("Testing upload speed...")
        await st.measure_upload_speed()

        print(f"Download: {st.download * 8 / 1e6:.2f} Mbps")
        print(f"Upload: {st.upload * 8 / 1e6:.2f} Mbps")
        print(f"Ping: {st.ping:.1f} ms")

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

Advanced configuration:

st = AsyncSpeedtest(
    source_address="192.168.1.100",
    download_test_duration=20,
    upload_test_duration=15,
    max_server_distance=1000  # kilometers
)

API Stability

The public API is intentionally small:

  • AsyncSpeedtest class and its public methods
  • run_speedtest() convenience function
  • SpeedTestResult, SpeedTestConfig, ServerInfo dataclasses
  • SpeedTestError and subclasses for error handling

Internals (server list parsing, timing implementation, HTTP request details) are not stable and may change between minor releases. The library is pre-1.0 and the API may evolve based on usage feedback.

Error Handling

  • Network failures (timeouts, DNS errors) are caught and logged; methods return gracefully
  • Invalid usage (e.g., measuring speed before selecting a server) raises RuntimeError with clear messages
  • No silent failures; errors are either raised or logged at appropriate levels
  • Empty server lists or malformed responses are handled defensively

Async & Performance Notes

  • Uses aiohttp.ClientSession with proper connection pooling
  • Explicit ClientTimeout objects (no deprecated timeout APIs)
  • High-resolution timers (time.perf_counter()) for accurate measurements
  • Bounded concurrency (configurable number of concurrent download streams)
  • Safe for use in existing event loops (no asyncio.run() internally)
  • Module-scoped logger; does not configure root logger

Testing

Unit tests use mocked network responses to validate parsing logic, distance calculations, and error handling:

pytest tests/

Tests do not make real network requests by default. Integration tests that contact actual Speedtest.net servers are excluded from the default test run.

License

MIT License. See LICENSE file for details.

Contributing

Contributions are welcome. Please:

  • Keep changes small and focused
  • Prioritize correctness and clarity over features
  • Discuss significant API changes in an issue before opening a PR
  • Ensure tests pass and add tests for new functionality

This library aims to remain simple and focused. Large feature additions may be declined if they add complexity without clear value for the async embedding use case.

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

pyasyncspeedtest-0.1.0.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

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

pyasyncspeedtest-0.1.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pyasyncspeedtest-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d43743058dc992ef6afcffb641501eb138530cd63644598c170c109af4afdb9b
MD5 f98e54b86f2ee960d08de10cab9326ab
BLAKE2b-256 05a7d39cd7499991eaa4a4800308eea39a943917d7b941ae0fcc6174a1de9225

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyasyncspeedtest-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1960fbc4a6b91e3c4c05f9dda57a3c554826b03bf6ab46927f265238a771d8b9
MD5 feb00aaa6c7ef87b133d7753c5994024
BLAKE2b-256 e4cddad8700ae219a2ea1235aa2d9199c9776b6e37823c9d403a76b3a0ce2b6b

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