Created
March 14, 2025 13:42
-
-
Save evnchn/bcd713061c77e9071dc78db34e7724ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Pieced together from: | |
| # (1) https://github.com/Vizonex/Winloop?tab=readme-ov-file#how-to-use-winloop-with-fastapi | |
| # (2) https://www.reddit.com/r/nicegui/comments/1dlx3or/fastapi_nicegui_integration/ | |
| # (3) https://github.com/pgjones/hypercorn?tab=readme-ov-file#quickstart | |
| from fastapi import FastAPI | |
| from fastapi.responses import HTMLResponse | |
| import winloop | |
| from hypercorn.config import Config | |
| from hypercorn.asyncio import serve | |
| import asyncio | |
| import datetime | |
| from nicegui import ui | |
| app = FastAPI() | |
| @app.on_event("startup") | |
| def make_assertion(): | |
| # Check to make sure that we bypassed the original eventloop Policy.... | |
| assert isinstance(asyncio.get_event_loop_policy(), winloop.EventLoopPolicy) | |
| # not WinLoopPolicy. (1) is outdated. I'll see when I can update it. | |
| @app.get("/test") | |
| async def test_get_request(): | |
| return HTMLResponse("<html><body><h1>FAST API WORKS WITH WINLOOP!</h1></body></html>") | |
| @app.get("/date") | |
| def test_dynamic_response(): | |
| return str(datetime.datetime.now()) | |
| @app.get("/str") | |
| def test_str_response(): | |
| return str(asyncio.get_event_loop_policy()) | |
| def init(fastapi_app: FastAPI) -> None: | |
| @ui.page("/") | |
| def index(): | |
| ui.label("Hello, world!") # | |
| ui.label(str(asyncio.get_event_loop_policy())) | |
| ui.run_with( | |
| fastapi_app, | |
| storage_secret='hmm', | |
| ) | |
| TRY_HTTP2_TLS = False | |
| TRY_HTTP3 = False | |
| if __name__ == "__main__": | |
| init(app) | |
| winloop.install() | |
| config = Config() | |
| config.bind = ["127.0.0.1:4004"] | |
| if TRY_HTTP2_TLS: | |
| # NOTE: WebSocket fails 3 times and works the 4th time? | |
| # Invalid websocket upgrade (further occurrences of this error will be logged with level INFO) | |
| config.certfile = r"C:\Users\User\mycert.crt" | |
| config.keyfile = r"C:\Users\User\mykey.key" | |
| if TRY_HTTP2_TLS and TRY_HTTP3: | |
| # NOTE: this does not work, connection refused? | |
| config.quic_bind = ["127.0.0.1:4099"] | |
| asyncio.run(serve(app, config)) | |
| # Conclusion of NiceGUI + WinLoop + Hypercorn: | |
| # HTTP 1.1: Works fine. | |
| # HTTP 2: WebSocket fails 3 times and works the 4th time. | |
| # HTTP 3: Connection refused. | |
| # It's the same without WinLoop. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment