Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to `winuvloop` are documented here.

## 0.2.4 - 2026-04-25

- Add FastAPI/Uvicorn, aiohttp, async CLI, and compatibility-test examples to
the README.
- Add upstream uvloop and winloop benchmark references to the README.
- Add framework and protocol keywords to improve PyPI discoverability.

## 0.2.3 - 2026-04-25

- Add `backend_version()` for support logs and diagnostics.
Expand Down
129 changes: 129 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ The wrapper stays deliberately small: platform detection, clear diagnostics,
common API re-exports, typing stubs, and platform-specific dependency markers.
Runtime behavior comes from the selected upstream backend.

## Why Performance Can Matter

The upstream projects publish benchmark guidance for the workloads they own.
[`uvloop`](https://github.com/MagicStack/uvloop#performance) reports making
asyncio 2-4x faster on its echo-server benchmarks. On Windows,
[`winloop`](https://github.com/Vizonex/Winloop#benchmarks) reports a TCP
connection benchmark of 0.493s with `WinLoopPolicy`, compared with 2.510s for
`WindowsProactorEventLoopPolicy` and 2.723s for
`WindowsSelectorEventLoopPolicy`.

Those are upstream benchmark numbers, not a universal promise for every
application. The practical point for `winuvloop` is simpler: one dependency
lets a cross-platform project select the optimized backend that upstream
projects already benchmark and maintain for each operating system family.

## When To Use It

Use `winuvloop` when:
Expand Down Expand Up @@ -143,6 +158,120 @@ The module re-exports the common backend API:

Backend-specific attributes are delegated to the selected upstream module.

## Framework Examples

`winuvloop` is most useful at process entry points: command-line scripts,
application launchers, benchmark runners, and local development helpers. Install
the optimized loop before a framework creates its event loop, or use
`winuvloop.run()` when you own the top-level coroutine.

These examples do not mean `winuvloop` depends on the frameworks shown here.
Install FastAPI, Uvicorn, aiohttp, or any other framework separately in your
application.

### FastAPI And Uvicorn

For a FastAPI application launched from Python, install the selected backend
before calling `uvicorn.run()`. Pass `loop="asyncio"` so Uvicorn uses the event
loop policy that `winuvloop.install()` already selected:

```python
# serve.py
import uvicorn

import winuvloop


winuvloop.install()

uvicorn.run(
"myapp:app",
host="127.0.0.1",
port=8000,
loop="asyncio",
)
```

Then run the launcher instead of invoking `uvicorn` directly:

```bash
python serve.py
```

If your deployment platform already configures the event loop, prefer the
platform's documented setting. `winuvloop` is the portable option when you want
the same launcher to select `uvloop` on Linux/macOS and `winloop` on Windows.

### aiohttp Web Server

For an `aiohttp.web` application, use `winuvloop.run()` around the application
runner:

```python
import asyncio

from aiohttp import web

import winuvloop


async def hello(request: web.Request) -> web.Response:
return web.Response(text="hello")


async def main() -> None:
app = web.Application()
app.router.add_get("/", hello)

runner = web.AppRunner(app)
await runner.setup()

site = web.TCPSite(runner, "127.0.0.1", 8080)
await site.start()

await asyncio.Event().wait()


winuvloop.run(main())
```

### Async CLI Or Worker

For scripts, CLIs, and workers, keep the entry point boring:

```python
import winuvloop


async def main() -> int:
...
return 0


raise SystemExit(winuvloop.run(main()))
```

This keeps examples and internal tools platform-neutral while still selecting
the optimized backend for the current runner.

### Tests And Support Logs

For compatibility tests, assert the selected backend rather than hard-coding an
operating system in every test:

```python
import sys

import winuvloop


def test_optimized_backend_is_available() -> None:
expected = "winloop" if sys.platform == "win32" else "uvloop"

assert winuvloop.backend_name() == expected
assert winuvloop.backend_version() is not None
```

For issue reports, include this diagnostic snippet:

```bash
Expand Down
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "uv_build"

[project]
name = "winuvloop"
version = "0.2.3"
version = "0.2.4"
description = "Use uvloop on Linux/macOS and winloop on Windows through one small asyncio compatibility import."
readme = "README.md"
requires-python = ">=3.8.1"
Expand All @@ -20,11 +20,16 @@ keywords = [
"uvloop",
"winloop",
"asyncio-run",
"aiohttp",
"fastapi",
"uvicorn",
"windows",
"linux",
"macos",
"cross-platform",
"asgi",
"websocket",
"http",
"performance",
]
classifiers = [
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading