A partial log_config (no "version" key) is deep-merged over uvicorn's
default config before our patching, so users pass only their
customizations, e.g. log_config={"loggers": {"myapp": {"level":
"DEBUG"}}}. Previously such dicts crashed at startup: dictConfig
requires a version, and our root entry referenced a "default" handler
that might not exist; that reference is now only added when the handler
exists. The stock default formatter is replaced only when untouched,
so an overlaid fmt survives. Dicts with version and non-dict configs
behave as before. Documented in the README logging section, with tests
under fastapi-vue/tests (each patched config validated through
dictConfig).
Bind sockets ourselves and pass them to uvicorn (Server.serve(sockets) or the
ChangeReload/Multiprocess supervisors, same API uvicorn.run uses). localhost
expands to 127.0.0.1 and ::1 so clients reach the server regardless of how
localhost resolves; individual bind failures degrade with a warning. Reload
mode now serves all endpoints instead of only the first, multi-endpoint
configs no longer run lifespan twice, and unix sockets are cleaned up on
exit.