simbiot-harness/venv/lib/python3.12/site-packages/starlette/_utils.py
Simbiot Harness b60439152b Simbiot Harness v0.1: тактовая лестница на Strands + CQRS/ES-спина
- harness/es.py: append-only event store + проекции (образец — кооп-портал)
- harness/levels.py: уровни 1с/1м/1ч/1д, контекст ∝ масштабу
- harness/scheduler.py: уровневые потоки, идемпотентные тики, absorbed-стабы
- harness/isolated_runner.py + _llm_worker.py: LLM-тик в сабпроцессе
  (глобальный asyncio-рантайм Strands не переживает 2+ create_harness)
- cli.py: init/task/tasks/status/events + requeue (написан самим минутным агентом)
- 9router: отдельный ключ sk-simbiot, модель auto (glm-5.3 первым)
2026-09-29 15:28:50 +00:00

155 lines
4.1 KiB
Python

from __future__ import annotations
import functools
import re
import sys
from collections.abc import AsyncGenerator, Awaitable, Callable, Generator
from contextlib import AbstractAsyncContextManager, asynccontextmanager
from dataclasses import dataclass
from ipaddress import AddressValueError, IPv6Address
from typing import Any, Generic, Protocol, TypeVar, overload
import anyio.abc
from starlette.types import Scope
if sys.version_info >= (3, 13): # pragma: no cover
from inspect import iscoroutinefunction
from typing import TypeIs
else: # pragma: no cover
from asyncio import iscoroutinefunction
from typing_extensions import TypeIs
if sys.version_info < (3, 11): # pragma: no cover
from exceptiongroup import BaseExceptionGroup
T = TypeVar("T")
AwaitableCallable = Callable[..., Awaitable[T]]
# Reject characters that could make a Host header change the URL path or authority.
_HOST_RE = re.compile(
r"^(?P<host>[a-z0-9._~%!$&'()*+,;=-]+|\[(?:(?P<ipv6>[a-f0-9]*:[a-f0-9.:]+)|"
r"(?-i:v)[a-f0-9]+\.[a-z0-9._~!$&'()*+,;=:-]+)\])(?::(?P<port>[0-9]+))?$",
re.IGNORECASE,
)
@dataclass(frozen=True, slots=True)
class ParsedHost:
host: str
port: str | None
@property
def authority(self) -> str:
return self.host if self.port is None else f"{self.host}:{self.port}"
@property
def is_valid_port(self) -> bool:
if self.port is None:
return True
port = self.port.lstrip("0")
return len(port) <= 5 and int(port or "0") <= 65535
@overload
def is_async_callable(obj: AwaitableCallable[T]) -> TypeIs[AwaitableCallable[T]]: ...
@overload
def is_async_callable(obj: Any) -> TypeIs[AwaitableCallable[Any]]: ...
def is_async_callable(obj: Any) -> Any:
while isinstance(obj, functools.partial):
obj = obj.func
return iscoroutinefunction(obj) or (callable(obj) and iscoroutinefunction(obj.__call__))
T_co = TypeVar("T_co", covariant=True)
class AwaitableOrContextManager(
Awaitable[T_co], AbstractAsyncContextManager[T_co], Protocol[T_co]
): ... # pragma: no branch
class SupportsAsyncClose(Protocol):
async def close(self) -> None: ... # pragma: no cover
SupportsAsyncCloseType = TypeVar("SupportsAsyncCloseType", bound=SupportsAsyncClose, covariant=False)
class AwaitableOrContextManagerWrapper(Generic[SupportsAsyncCloseType]):
__slots__ = ("aw", "entered")
def __init__(self, aw: Awaitable[SupportsAsyncCloseType]) -> None:
self.aw = aw
def __await__(self) -> Generator[Any, None, SupportsAsyncCloseType]:
return self.aw.__await__()
async def __aenter__(self) -> SupportsAsyncCloseType:
self.entered = await self.aw
return self.entered
async def __aexit__(self, *args: Any) -> None | bool:
await self.entered.close()
return None
@asynccontextmanager
async def create_collapsing_task_group() -> AsyncGenerator[anyio.abc.TaskGroup, None]:
try:
async with anyio.create_task_group() as tg:
yield tg
except BaseExceptionGroup as excs:
if len(excs.exceptions) != 1:
raise
exc = excs.exceptions[0]
context = None if exc.__suppress_context__ else exc.__context__
raise exc from exc.__cause__ or context
def parse_host_header(host_header: str | None) -> ParsedHost | None:
"""Parse `host_header` into its host and port components.
The host preserves brackets around IP literals. Invalid headers produce `None`.
"""
if host_header is None:
return None
match = _HOST_RE.fullmatch(host_header)
if match is None:
return None
ipv6 = match["ipv6"]
if ipv6 is not None:
try:
IPv6Address(ipv6)
except AddressValueError:
return None
return ParsedHost(match["host"], match["port"])
def get_route_path(scope: Scope) -> str:
path: str = scope["path"]
root_path = scope.get("root_path", "")
if not root_path:
return path
if not path.startswith(root_path):
return path
if path == root_path:
return ""
if path[len(root_path)] == "/":
return path[len(root_path) :]
return path