mirror of
https://github.com/evroon/bracket.git
synced 2026-01-23 05:28:45 -05:00
Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.35.0 to 0.38.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/Kludex/uvicorn/releases">uvicorn's releases</a>.</em></p> <blockquote> <h2>Version 0.38.0</h2> <h2>What's Changed</h2> <ul> <li>Support Python 3.14 by <a href="https://github.com/Kludex"><code>@Kludex</code></a> in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2723">Kludex/uvicorn#2723</a></li> </ul> <hr /> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/NGANAMODEIJunior"><code>@NGANAMODEIJunior</code></a> made their first contribution in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2713">Kludex/uvicorn#2713</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/Kludex/uvicorn/compare/0.37.0...0.38.0">https://github.com/Kludex/uvicorn/compare/0.37.0...0.38.0</a></p> <h2>Version 0.37.0</h2> <h2>What's Changed</h2> <ul> <li>Add <code>--timeout-worker-healthcheck</code> setting by <a href="https://github.com/Kludex"><code>@Kludex</code></a> in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2711">Kludex/uvicorn#2711</a></li> <li>Add <code>os.PathLike[str]</code> type to <code>ssl_ca_certs</code> by <a href="https://github.com/rnv812"><code>@rnv812</code></a> in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2676">Kludex/uvicorn#2676</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/LincolnPuzey"><code>@LincolnPuzey</code></a> made their first contribution in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2669">Kludex/uvicorn#2669</a></li> <li><a href="https://github.com/rnv812"><code>@rnv812</code></a> made their first contribution in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2676">Kludex/uvicorn#2676</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/Kludex/uvicorn/compare/0.36.1...0.37.0">https://github.com/Kludex/uvicorn/compare/0.36.1...0.37.0</a></p> <h2>Version 0.36.1</h2> <h2>What's Changed</h2> <ul> <li>Raise an exception when calling removed <code>Config.setup_event_loop()</code> by <a href="https://github.com/Kludex"><code>@Kludex</code></a> in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2709">Kludex/uvicorn#2709</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/Kludex/uvicorn/compare/0.36.0...0.36.1">https://github.com/Kludex/uvicorn/compare/0.36.0...0.36.1</a></p> <h2>Version 0.36.0</h2> <h2>Added</h2> <ul> <li>Support custom IOLOOPs by <a href="https://github.com/gnir-work"><code>@gnir-work</code></a> in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2435">Kludex/uvicorn#2435</a></li> <li>Allow to provide importable string in <code>--http</code>, <code>--ws</code> and <code>--loop</code> by <a href="https://github.com/Kludex"><code>@Kludex</code></a> in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2658">Kludex/uvicorn#2658</a></li> </ul> <hr /> <h3>New Contributors</h3> <ul> <li><a href="https://github.com/gnir-work"><code>@gnir-work</code></a> made their first contribution in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2435">Kludex/uvicorn#2435</a></li> <li><a href="https://github.com/musicinmybrain"><code>@musicinmybrain</code></a> made their first contribution in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2659">Kludex/uvicorn#2659</a></li> <li><a href="https://github.com/secrett2633"><code>@secrett2633</code></a> made their first contribution in <a href="https://redirect.github.com/Kludex/uvicorn/pull/2684">Kludex/uvicorn#2684</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/Kludex/uvicorn/compare/0.35.0...0.36.0">https://github.com/Kludex/uvicorn/compare/0.35.0...0.36.0</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md">uvicorn's changelog</a>.</em></p> <blockquote> <h2>0.38.0 (October 18, 2025)</h2> <h3>Added</h3> <ul> <li>Support Python 3.14 (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2723">#2723</a>)</li> </ul> <h2>0.37.0 (September 23, 2025)</h2> <h3>Added</h3> <ul> <li>Add <code>--timeout-worker-healthcheck</code> option (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2711">#2711</a>)</li> <li>Add <code>os.PathLike[str]</code> type to <code>ssl_ca_certs</code> (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2676">#2676</a>)</li> </ul> <h2>0.36.1 (September 23, 2025)</h2> <h3>Fixed</h3> <ul> <li>Raise an exception when calling removed <code>Config.setup_event_loop()</code> (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2709">#2709</a>)</li> </ul> <h2>0.36.0 (September 20, 2025)</h2> <h3>Added</h3> <ul> <li>Support custom IOLOOPs (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2435">#2435</a>)</li> <li>Allow to provide importable string in <code>--http</code>, <code>--ws</code> and <code>--loop</code> (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2658">#2658</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="3850ad6520"><code>3850ad6</code></a> Version 0.38.0 (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2733">#2733</a>)</li> <li><a href="9b3f17a549"><code>9b3f17a</code></a> Support Python 3.14 (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2723">#2723</a>)</li> <li><a href="ce79f95d06"><code>ce79f95</code></a> Revert "Add Marcelo Trylesinski to the license (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2699">#2699</a>)" (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2730">#2730</a>)</li> <li><a href="dbf8797b47"><code>dbf8797</code></a> docs: add social icons (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2728">#2728</a>)</li> <li><a href="58f28be98e"><code>58f28be</code></a> Add section about event loop (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2725">#2725</a>)</li> <li><a href="93d9510749"><code>93d9510</code></a> Bump docs dependencies (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2724">#2724</a>)</li> <li><a href="9b1c6c45ed"><code>9b1c6c4</code></a> Move Marcelo Trylesinski to maintainers in <code>pyproject.toml</code> (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2719">#2719</a>)</li> <li><a href="57a61d86f2"><code>57a61d8</code></a> Add discord to README (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2718">#2718</a>)</li> <li><a href="7ef5f9f5e7"><code>7ef5f9f</code></a> chore(deps): bump astral-sh/setup-uv from 6.7.0 to 6.8.0 (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2717">#2717</a>)</li> <li><a href="6d26d88970"><code>6d26d88</code></a> Update pyproject.toml for PEP639 compliance (<a href="https://redirect.github.com/Kludex/uvicorn/issues/2713">#2713</a>)</li> <li>Additional commits viewable in <a href="https://github.com/Kludex/uvicorn/compare/0.35.0...0.38.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Erik Vroon <erik.vroon@channable.com>
123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
import asyncio
|
|
import socket
|
|
from collections.abc import AsyncIterator, Sequence
|
|
from contextlib import closing
|
|
from typing import Final
|
|
|
|
import aiohttp
|
|
import uvicorn
|
|
from fastapi import FastAPI
|
|
|
|
from bracket.app import app
|
|
from bracket.routes.models import SuccessResponse
|
|
from bracket.utils.http import HTTPMethod
|
|
from bracket.utils.types import JsonDict
|
|
from tests.integration_tests.models import AuthContext
|
|
|
|
SUCCESS_RESPONSE = SuccessResponse().model_dump()
|
|
|
|
|
|
def find_free_port() -> int:
|
|
"""
|
|
Ask the OS for an available port on localhost and then immediately give
|
|
it back so it can be used in our test. This way we don't have to hard code
|
|
a port to something and accidentally collide.
|
|
"""
|
|
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
|
|
s.bind(("", 0))
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
port: int = s.getsockname()[1]
|
|
return port
|
|
|
|
|
|
TEST_HOST: Final[str] = "127.0.0.1"
|
|
TEST_PORT: Final[int] = find_free_port()
|
|
|
|
|
|
def get_root_uvicorn_url() -> str:
|
|
return f"http://{TEST_HOST}:{TEST_PORT}/"
|
|
|
|
|
|
class UvicornTestServer(uvicorn.Server):
|
|
"""
|
|
Uvicorn test server. Used as a test fixture to do
|
|
integration tests against our FastAPI app.
|
|
"""
|
|
|
|
def __init__(self, _app: FastAPI = app, host: str = TEST_HOST, port: int = TEST_PORT):
|
|
self._startup_done = asyncio.Event()
|
|
self._serve_task: asyncio.Task[None] | None = None
|
|
self.should_exit: bool = False
|
|
super().__init__(config=uvicorn.Config(_app, host=host, port=port))
|
|
|
|
async def startup(self, sockets: Sequence[socket.socket] | None = None) -> None:
|
|
sockets_list = list(sockets) if sockets is not None else sockets
|
|
await super().startup(sockets=sockets_list)
|
|
self._startup_done.set()
|
|
|
|
async def up(self) -> None:
|
|
self._serve_task = asyncio.create_task(self.serve())
|
|
# If the startup takes longer than 5 seconds something is wrong and we can terminate it
|
|
await asyncio.wait_for(self._startup_done.wait(), 5)
|
|
|
|
async def down(self) -> None:
|
|
self.should_exit = True
|
|
assert self._serve_task is not None
|
|
await self._serve_task
|
|
|
|
|
|
async def send_request(
|
|
method: HTTPMethod,
|
|
endpoint: str,
|
|
body: JsonDict | AsyncIterator[bytes] | aiohttp.FormData | None = None,
|
|
json: JsonDict | None = None,
|
|
headers: JsonDict = {},
|
|
) -> JsonDict:
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.request(
|
|
method=method.value,
|
|
url=get_root_uvicorn_url() + endpoint,
|
|
data=body,
|
|
json=json,
|
|
headers=headers,
|
|
) as resp:
|
|
response: JsonDict = await resp.json()
|
|
return response
|
|
|
|
|
|
async def send_request_raw(method: HTTPMethod, endpoint: str) -> str:
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.request(
|
|
method=method.value,
|
|
url=get_root_uvicorn_url() + endpoint,
|
|
) as resp:
|
|
return await resp.text()
|
|
|
|
|
|
async def send_auth_request(
|
|
method: HTTPMethod,
|
|
endpoint: str,
|
|
auth_context: AuthContext,
|
|
body: JsonDict | None = None,
|
|
json: JsonDict | None = None,
|
|
) -> JsonDict:
|
|
return await send_request(
|
|
method=method, endpoint=endpoint, body=body, json=json, headers=auth_context.headers
|
|
)
|
|
|
|
|
|
async def send_tournament_request(
|
|
method: HTTPMethod,
|
|
endpoint: str,
|
|
auth_context: AuthContext,
|
|
body: JsonDict | AsyncIterator[bytes] | aiohttp.FormData | None = None,
|
|
json: JsonDict | None = None,
|
|
) -> JsonDict:
|
|
return await send_request(
|
|
method=method,
|
|
endpoint=f"tournaments/{auth_context.tournament.id}/{endpoint}",
|
|
body=body,
|
|
json=json,
|
|
headers=auth_context.headers,
|
|
)
|