Print correct URL for datasette -p 0 --root by pre-binding the socket#2703
Open
alvinttang wants to merge 1 commit intosimonw:mainfrom
Open
Print correct URL for datasette -p 0 --root by pre-binding the socket#2703alvinttang wants to merge 1 commit intosimonw:mainfrom
alvinttang wants to merge 1 commit intosimonw:mainfrom
Conversation
Closes simonw#873. When `datasette -p 0 --root` was used, the printed auth-token URL contained the literal placeholder port 0 instead of the OS-assigned port that uvicorn would later bind to. Same applied to `--open`. Fix: when `port == 0` and we need to print/open a URL before the server starts (because of --root or --open), pre-bind a TCP socket on (host, 0), read the assigned port via getsockname(), and hand the bound socket to uvicorn via Server.run(sockets=[...]). uvicorn.run()'s own `fd=` parameter assumes AF_UNIX so we use the Config/Server API in this branch only; the existing uvicorn.run() path is unchanged. Adds a regression test that launches `datasette --memory -p 0 --root`, parses the printed URL, asserts the port is non-zero, and confirms a server is actually listening on that port.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #873 (open since 2018).
datasette/cli.py::serveprinted the--rootauth-token URL (and built the--openURL) using the user-suppliedportvalue before handing off touvicorn.run(). With-p 0, uvicorn would assign a real port internally, but Datasette had already echoedhttp://127.0.0.1:0/....Fix
When
port == 0AND we need the URL upfront (--rootor--open) AND not using--uds, pre-bind a TCP socket on(host, 0), read the assigned port viagetsockname(), then pass the bound socket to uvicorn viauvicorn.Server(config).run(sockets=[sock]). (uvicorn.run()'sfd=shortcut assumes AF_UNIX, so we use the lower-level Config/Server API on this single branch; the defaultuvicorn.run()path is untouched for everyone else.) Handles IPv6 hosts. SSL flags preserved.26 LOC of production change.
Test
tests/test_cli_serve_server.py::test_serve_root_url_uses_actual_port_when_port_is_zero— spawnspython -m datasette --memory -p 0 --rootas a subprocess, parses the printedauth-tokenURL with regex, asserts the port is non-zero, then issues an HTTPX request to that port and asserts 200 on/_memory.json.pytest tests/test_cli.py tests/test_cli_serve_server.py tests/test_cli_serve_get.py tests/test_internals_datasette_client.py→ 93 passed. Manual e2e:datasette --memory -p 0 --rootnow printshttp://127.0.0.1:50940/...andlsofconfirms the process is listening on the same port.ruff+black --checkclean.Risk notes
SO_REUSEADDRmatches uvicorn's ownConfig.bind_socket.--udspath explicitly excluded. Behaviour for the common case (port != 0or no--root/--open) is byte-identical.Uvicorn running on socket ('127.0.0.1', <port>)instead of thehttp://...line. The URL printed to stdout is correct, which is what the issue is about.Refs #873
📚 Documentation preview 📚: https://datasette--2703.org.readthedocs.build/en/2703/