Skip to content

Commit 2908c32

Browse files
authored
Add framework examples and benchmark references
Add optional framework usage examples, upstream benchmark references, and PyPI discovery keywords without adding dependencies. Release as 0.2.4.
1 parent 15cc979 commit 2908c32

4 files changed

Lines changed: 143 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to `winuvloop` are documented here.
44

5+
## 0.2.4 - 2026-04-25
6+
7+
- Add FastAPI/Uvicorn, aiohttp, async CLI, and compatibility-test examples to
8+
the README.
9+
- Add upstream uvloop and winloop benchmark references to the README.
10+
- Add framework and protocol keywords to improve PyPI discoverability.
11+
512
## 0.2.3 - 2026-04-25
613

714
- Add `backend_version()` for support logs and diagnostics.

README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ The wrapper stays deliberately small: platform detection, clear diagnostics,
4848
common API re-exports, typing stubs, and platform-specific dependency markers.
4949
Runtime behavior comes from the selected upstream backend.
5050

51+
## Why Performance Can Matter
52+
53+
The upstream projects publish benchmark guidance for the workloads they own.
54+
[`uvloop`](https://github.com/MagicStack/uvloop#performance) reports making
55+
asyncio 2-4x faster on its echo-server benchmarks. On Windows,
56+
[`winloop`](https://github.com/Vizonex/Winloop#benchmarks) reports a TCP
57+
connection benchmark of 0.493s with `WinLoopPolicy`, compared with 2.510s for
58+
`WindowsProactorEventLoopPolicy` and 2.723s for
59+
`WindowsSelectorEventLoopPolicy`.
60+
61+
Those are upstream benchmark numbers, not a universal promise for every
62+
application. The practical point for `winuvloop` is simpler: one dependency
63+
lets a cross-platform project select the optimized backend that upstream
64+
projects already benchmark and maintain for each operating system family.
65+
5166
## When To Use It
5267

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

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

161+
## Framework Examples
162+
163+
`winuvloop` is most useful at process entry points: command-line scripts,
164+
application launchers, benchmark runners, and local development helpers. Install
165+
the optimized loop before a framework creates its event loop, or use
166+
`winuvloop.run()` when you own the top-level coroutine.
167+
168+
These examples do not mean `winuvloop` depends on the frameworks shown here.
169+
Install FastAPI, Uvicorn, aiohttp, or any other framework separately in your
170+
application.
171+
172+
### FastAPI And Uvicorn
173+
174+
For a FastAPI application launched from Python, install the selected backend
175+
before calling `uvicorn.run()`. Pass `loop="asyncio"` so Uvicorn uses the event
176+
loop policy that `winuvloop.install()` already selected:
177+
178+
```python
179+
# serve.py
180+
import uvicorn
181+
182+
import winuvloop
183+
184+
185+
winuvloop.install()
186+
187+
uvicorn.run(
188+
"myapp:app",
189+
host="127.0.0.1",
190+
port=8000,
191+
loop="asyncio",
192+
)
193+
```
194+
195+
Then run the launcher instead of invoking `uvicorn` directly:
196+
197+
```bash
198+
python serve.py
199+
```
200+
201+
If your deployment platform already configures the event loop, prefer the
202+
platform's documented setting. `winuvloop` is the portable option when you want
203+
the same launcher to select `uvloop` on Linux/macOS and `winloop` on Windows.
204+
205+
### aiohttp Web Server
206+
207+
For an `aiohttp.web` application, use `winuvloop.run()` around the application
208+
runner:
209+
210+
```python
211+
import asyncio
212+
213+
from aiohttp import web
214+
215+
import winuvloop
216+
217+
218+
async def hello(request: web.Request) -> web.Response:
219+
return web.Response(text="hello")
220+
221+
222+
async def main() -> None:
223+
app = web.Application()
224+
app.router.add_get("/", hello)
225+
226+
runner = web.AppRunner(app)
227+
await runner.setup()
228+
229+
site = web.TCPSite(runner, "127.0.0.1", 8080)
230+
await site.start()
231+
232+
await asyncio.Event().wait()
233+
234+
235+
winuvloop.run(main())
236+
```
237+
238+
### Async CLI Or Worker
239+
240+
For scripts, CLIs, and workers, keep the entry point boring:
241+
242+
```python
243+
import winuvloop
244+
245+
246+
async def main() -> int:
247+
...
248+
return 0
249+
250+
251+
raise SystemExit(winuvloop.run(main()))
252+
```
253+
254+
This keeps examples and internal tools platform-neutral while still selecting
255+
the optimized backend for the current runner.
256+
257+
### Tests And Support Logs
258+
259+
For compatibility tests, assert the selected backend rather than hard-coding an
260+
operating system in every test:
261+
262+
```python
263+
import sys
264+
265+
import winuvloop
266+
267+
268+
def test_optimized_backend_is_available() -> None:
269+
expected = "winloop" if sys.platform == "win32" else "uvloop"
270+
271+
assert winuvloop.backend_name() == expected
272+
assert winuvloop.backend_version() is not None
273+
```
274+
146275
For issue reports, include this diagnostic snippet:
147276

148277
```bash

pyproject.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "uv_build"
44

55
[project]
66
name = "winuvloop"
7-
version = "0.2.3"
7+
version = "0.2.4"
88
description = "Use uvloop on Linux/macOS and winloop on Windows through one small asyncio compatibility import."
99
readme = "README.md"
1010
requires-python = ">=3.8.1"
@@ -20,11 +20,16 @@ keywords = [
2020
"uvloop",
2121
"winloop",
2222
"asyncio-run",
23+
"aiohttp",
24+
"fastapi",
25+
"uvicorn",
2326
"windows",
2427
"linux",
2528
"macos",
2629
"cross-platform",
2730
"asgi",
31+
"websocket",
32+
"http",
2833
"performance",
2934
]
3035
classifiers = [

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)