From 21e0b8b65cb1507bdbbcf5e669474e121bb65753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= Date: Thu, 4 Jan 2024 00:40:10 +0100 Subject: [PATCH] Expose `host` for several apps. (#59) * Expose `host` for several apps. * Fix tests, introduce pytest-xdist * Fix coverage? * Fix some more I guess --- CHANGELOG.md | 2 ++ pdm.lock | 26 +++++++++++++++++++++++++- pyproject.toml | 1 + src/uapi/flask.py | 5 +++-- src/uapi/quart.py | 2 ++ src/uapi/starlette.py | 7 ++++++- tests/quart.py | 2 +- tests/starlette.py | 2 +- tox.ini | 13 ++++++++----- 9 files changed, 49 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 893bce8..d3a4216 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ The **third number** is for emergencies when we need to start branches for older ([#58](https://github.com/Tinche/uapi/pull/58)) - Dictionaries are now supported in the OpenAPI schema, rendering to object schemas with `additionalProperties`. ([#58](https://github.com/Tinche/uapi/pull/58)) +- {meth}`uapi.flask.FlaskApp.run`, {meth}`uapi.quart.QuartApp.run` and {meth}`uapi.starlette.StarletteApp.run` now expose `host` parameters. + ([#59](https://github.com/Tinche/uapi/pull/59)) ## [v23.3.0](https://github.com/tinche/uapi/compare/v23.2.0...v23.3.0) - 2023-12-20 diff --git a/pdm.lock b/pdm.lock index 7f4be3b..e1ac289 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "docs", "lint", "test", "frameworks"] strategy = ["cross_platform"] lock_version = "4.4.1" -content_hash = "sha256:a15d35d87dbaa62f1b15e8fbfae8b6d56419f3a2425245d7f49e16854e1cd8d9" +content_hash = "sha256:41090707373f4b14467254321d4f75dd7a511baa4db674a494a3ff9b28b82b94" [[package]] name = "aiofiles" @@ -419,6 +419,16 @@ files = [ {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, ] +[[package]] +name = "execnet" +version = "2.0.2" +requires_python = ">=3.7" +summary = "execnet: rapid multi-Python deployment" +files = [ + {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, + {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, +] + [[package]] name = "flask" version = "3.0.0" @@ -1038,6 +1048,20 @@ files = [ {file = "pytest_mypy_plugins-3.0.0-py3-none-any.whl", hash = "sha256:a1e3f51b68898bc25713cc53718a28d9dc0cfd51d28a537ef18c7df3b123ed84"}, ] +[[package]] +name = "pytest-xdist" +version = "3.5.0" +requires_python = ">=3.7" +summary = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" +dependencies = [ + "execnet>=1.1", + "pytest>=6.2.0", +] +files = [ + {file = "pytest-xdist-3.5.0.tar.gz", hash = "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a"}, + {file = "pytest_xdist-3.5.0-py3-none-any.whl", hash = "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24"}, +] + [[package]] name = "python-multipart" version = "0.0.6" diff --git a/pyproject.toml b/pyproject.toml index 3611e30..02f137c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,7 @@ test = [ "uapi[lint, frameworks]", "python-multipart>=0.0.6", "pytest-mypy-plugins>=3.0.0", + "pytest-xdist>=3.5.0", ] frameworks = [ "aiohttp==3.9.0b0", diff --git a/src/uapi/flask.py b/src/uapi/flask.py index 7c1a82a..7862cbd 100644 --- a/src/uapi/flask.py +++ b/src/uapi/flask.py @@ -143,8 +143,9 @@ def adapter(**kwargs): return f - def run(self, import_name: str, port: int = 8000): - self.to_framework_app(import_name).run(port=port) + def run(self, import_name: str, host: str | None = None, port: int = 8000): + """Start serving the app using the Flask development server.""" + self.to_framework_app(import_name).run(host=host, port=port) @staticmethod def _path_param_parser(p: str) -> tuple[str, list[str]]: diff --git a/src/uapi/quart.py b/src/uapi/quart.py index c4a06ca..f6b23f0 100644 --- a/src/uapi/quart.py +++ b/src/uapi/quart.py @@ -164,6 +164,7 @@ async def adapter(**kwargs): async def run( self, import_name: str, + host: str = "127.0.0.1", port: int = 8000, handle_signals: bool = True, log_level: str | int | None = None, @@ -176,6 +177,7 @@ async def run( config = Config( self.to_framework_app(import_name), + host=host, port=port, access_log=False, log_level=log_level, diff --git a/src/uapi/starlette.py b/src/uapi/starlette.py index 3f3b5a8..a20d987 100644 --- a/src/uapi/starlette.py +++ b/src/uapi/starlette.py @@ -178,6 +178,7 @@ async def adapted( async def run( self, + host: str = "127.0.0.1", port: int = 8000, handle_signals: bool = True, log_level: str | int | None = None, @@ -189,7 +190,11 @@ async def run( from uvicorn import Config, Server config = Config( - self.to_framework_app(), port=port, access_log=False, log_level=log_level + self.to_framework_app(), + host=host, + port=port, + access_log=False, + log_level=log_level, ) if handle_signals: diff --git a/tests/quart.py b/tests/quart.py index 0b39d31..b2348a5 100644 --- a/tests/quart.py +++ b/tests/quart.py @@ -68,4 +68,4 @@ def request_method_native(req_method: Method) -> Response: async def run_on_quart(app: App, port: int) -> None: - await app.run(__name__, port, handle_signals=False, log_level="critical") + await app.run(__name__, port=port, handle_signals=False, log_level="critical") diff --git a/tests/starlette.py b/tests/starlette.py index 6e87e75..39a3d1b 100644 --- a/tests/starlette.py +++ b/tests/starlette.py @@ -68,4 +68,4 @@ def request_method_native(req_method: Method) -> Response: async def run_on_starlette(app: App, port: int) -> None: - await app.run(port, handle_signals=False) + await app.run(port=port, handle_signals=False) diff --git a/tox.ini b/tox.ini index 4191fe0..f074225 100644 --- a/tox.ini +++ b/tox.ini @@ -1,16 +1,16 @@ # Keep docs in sync with docs env and .readthedocs.yml. [gh-actions] python = - 3.10: py310, lint + 3.10: py310 3.11: py311 - 3.12: py312 + 3.12: py312, lint [tox] envlist = py310, py311, py312, lint isolated_build = True [testenv:lint] -basepython = python3.10 +basepython = python3.12 allowlist_externals = make pdm @@ -21,9 +21,12 @@ commands = [testenv] setenv = PDM_IGNORE_SAVED_PYTHON="1" + COVERAGE_PROCESS_START={toxinidir}/pyproject.toml +commands_pre = + pdm sync -G test + python -c 'import pathlib; pathlib.Path("{env_site_packages_dir}/cov.pth").write_text("import coverage; coverage.process_startup()")' commands = - pdm install -G test - pdm run coverage run -m pytest tests --mypy-only-local-stub {posargs} + pdm run coverage run -m pytest tests --mypy-only-local-stub -n auto {posargs} allowlist_externals = pdm package = wheel wheel_build_env = .pkg