fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099

Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-19 13:53:55 +09:00
parent dc08d29509
commit c2257d3a86
2709 changed files with 619549 additions and 10 deletions

View File

@@ -0,0 +1,10 @@
from __future__ import annotations
from ._base import AsyncBaseBackend, AsyncLowLevelResponse
from .hface import AsyncHfaceBackend
__all__ = (
"AsyncBaseBackend",
"AsyncLowLevelResponse",
"AsyncHfaceBackend",
)

View File

@@ -0,0 +1,330 @@
from __future__ import annotations
import typing
from ..._collections import HTTPHeaderDict
from ...contrib.ssa import AsyncSocket, SSLAsyncSocket
from .._base import BaseBackend, ResponsePromise
from ...util.response import BytesQueueBuffer
class AsyncDirectStreamAccess:
def __init__(
self,
stream_id: int,
read: typing.Callable[
[int | None, int | None, bool, bool],
typing.Awaitable[tuple[bytes, bool, HTTPHeaderDict | None]],
]
| None = None,
write: typing.Callable[[bytes, int, bool], typing.Awaitable[None]]
| None = None,
) -> None:
self._stream_id = stream_id
self._read = read
self._write = write
@property
def closed(self) -> bool:
return self._read is None and self._write is None
async def readinto(self, b: bytearray) -> int:
if self._read is None:
raise OSError("read operation on a closed stream")
temp = await self.recv(len(b))
if len(temp) == 0:
return 0
else:
b[: len(temp)] = temp
return len(temp)
def readable(self) -> bool:
return self._read is not None
def writable(self) -> bool:
return self._write is not None
def seekable(self) -> bool:
return False
def fileno(self) -> int:
return -1
def name(self) -> int:
return -1
async def recv(self, __bufsize: int, __flags: int = 0) -> bytes:
data, _, _ = await self.recv_extended(__bufsize)
return data
async def recv_extended(
self, __bufsize: int | None
) -> tuple[bytes, bool, HTTPHeaderDict | None]:
if self._read is None:
raise OSError("stream closed error")
data, eot, trailers = await self._read(
__bufsize,
self._stream_id,
__bufsize is not None,
False,
)
if eot:
self._read = None
return data, eot, trailers
async def sendall(self, __data: bytes, __flags: int = 0) -> None:
if self._write is None:
raise OSError("stream write not permitted")
await self._write(__data, self._stream_id, False)
async def write(self, __data: bytes) -> int:
if self._write is None:
raise OSError("stream write not permitted")
await self._write(__data, self._stream_id, False)
return len(__data)
async def sendall_extended(
self, __data: bytes, __close_stream: bool = False
) -> None:
if self._write is None:
raise OSError("stream write not permitted")
await self._write(__data, self._stream_id, __close_stream)
async def close(self) -> None:
if self._write is not None:
await self._write(b"", self._stream_id, True)
self._write = None
if self._read is not None:
await self._read(None, self._stream_id, False, True)
self._read = None
class AsyncLowLevelResponse:
"""Implemented for backward compatibility purposes. It is there to impose http.client like
basic response object. So that we don't have to change urllib3 tested behaviors."""
__internal_read_st: (
typing.Callable[
[int | None, int | None],
typing.Awaitable[tuple[bytes, bool, HTTPHeaderDict | None]],
]
| None
)
def __init__(
self,
method: str,
status: int,
version: int,
reason: str,
headers: HTTPHeaderDict,
body: typing.Callable[
[int | None, int | None],
typing.Awaitable[tuple[bytes, bool, HTTPHeaderDict | None]],
]
| None,
*,
authority: str | None = None,
port: int | None = None,
stream_id: int | None = None,
# this obj should not be always available[...]
dsa: AsyncDirectStreamAccess | None = None,
stream_abort: typing.Callable[[int], typing.Awaitable[None]] | None = None,
) -> None:
self.status = status
self.version = version
self.reason = reason
self.msg = headers
self._method = method
self.__internal_read_st = body
has_body = self.__internal_read_st is not None
self.closed = has_body is False
self._eot = self.closed
# is kept to determine if we can upgrade conn
self.authority = authority
self.port = port
# http.client compat layer
self.debuglevel: int = 0 # no-op flag, kept for strict backward compatibility!
self.chunked: bool = ( # is "chunked" being used? http1 only!
self.version == 11 and "chunked" == self.msg.get("transfer-encoding")
)
self.chunk_left: int | None = None # bytes left to read in current chunk
self.length: int | None = None # number of bytes left in response
self.will_close: bool = (
False # no-op flag, kept for strict backward compatibility!
)
if not self.chunked:
content_length = self.msg.get("content-length")
self.length = int(content_length) if content_length else None
#: not part of http.client but useful to track (raw) download speeds!
self.data_in_count = 0
self._stream_id = stream_id
self.__buffer_excess: BytesQueueBuffer = BytesQueueBuffer()
self.__promise: ResponsePromise | None = None
self._dsa = dsa
self._stream_abort = stream_abort
self.trailers: HTTPHeaderDict | None = None
@property
def fp(self) -> typing.NoReturn:
raise RuntimeError(
"urllib3-future no longer expose a filepointer-like in responses. It was a remnant from the http.client era. "
"We no longer support it."
)
@property
def from_promise(self) -> ResponsePromise | None:
return self.__promise
@from_promise.setter
def from_promise(self, value: ResponsePromise) -> None:
if value.stream_id != self._stream_id:
raise ValueError(
"Trying to assign a ResponsePromise to an unrelated LowLevelResponse"
)
self.__promise = value
@property
def method(self) -> str:
"""Original HTTP verb used in the request."""
return self._method
def isclosed(self) -> bool:
"""Here we do not create a fp sock like http.client Response."""
return self.closed
async def read(self, __size: int | None = None) -> bytes:
if self.closed is True or self.__internal_read_st is None:
# overly protective, just in case.
raise ValueError(
"I/O operation on closed file."
) # Defensive: Should not be reachable in normal condition
if __size == 0:
return b"" # Defensive: This is unreachable, this case is already covered higher in the stack.
buf_capacity = len(self.__buffer_excess)
data_ready_to_go = (
__size is not None and buf_capacity > 0 and buf_capacity >= __size
)
if self._eot is False and not data_ready_to_go:
data, self._eot, self.trailers = await self.__internal_read_st(
__size, self._stream_id
)
self.__buffer_excess.put(data)
buf_capacity = len(self.__buffer_excess)
data = self.__buffer_excess.get(
__size if __size is not None and __size > 0 else buf_capacity
)
size_in = len(data)
buf_capacity -= size_in
if self._eot and buf_capacity == 0:
self._stream_abort = None
self.closed = True
self._sock = None
if self.chunked:
self.chunk_left = buf_capacity if buf_capacity else None
elif self.length is not None:
self.length -= size_in
self.data_in_count += size_in
return data
async def abort(self) -> None:
if self._stream_abort is not None:
if self._eot is False:
if self._stream_id is not None:
await self._stream_abort(self._stream_id)
self._eot = True
self._stream_abort = None
self.closed = True
self._dsa = None
def close(self) -> None:
self.__internal_read_st = None
self.closed = True
self._dsa = None
class AsyncBaseBackend(BaseBackend):
sock: AsyncSocket | SSLAsyncSocket | None # type: ignore[assignment]
async def _upgrade(self) -> None: # type: ignore[override]
"""Upgrade conn from svn ver to max supported."""
raise NotImplementedError
async def _tunnel(self) -> None: # type: ignore[override]
"""Emit proper CONNECT request to the http (server) intermediary."""
raise NotImplementedError
async def _new_conn(self) -> AsyncSocket | None: # type: ignore[override]
"""Run protocol initialization from there. Return None to ensure that the child
class correctly create the socket / connection."""
raise NotImplementedError
async def _post_conn(self) -> None: # type: ignore[override]
"""Should be called after _new_conn proceed as expected.
Expect protocol handshake to be done here."""
raise NotImplementedError
async def endheaders( # type: ignore[override]
self,
message_body: bytes | None = None,
*,
encode_chunked: bool = False,
expect_body_afterward: bool = False,
) -> ResponsePromise | None:
"""This method conclude the request context construction."""
raise NotImplementedError
async def getresponse( # type: ignore[override]
self, *, promise: ResponsePromise | None = None
) -> AsyncLowLevelResponse:
"""Fetch the HTTP response. You SHOULD not retrieve the body in that method, it SHOULD be done
in the LowLevelResponse, so it enable stream capabilities and remain efficient.
"""
raise NotImplementedError
async def close(self) -> None: # type: ignore[override]
"""End the connection, do some reinit, closing of fd, etc..."""
raise NotImplementedError
async def send( # type: ignore[override]
self,
data: (bytes | typing.IO[typing.Any] | typing.Iterable[bytes] | str),
*,
eot: bool = False,
) -> ResponsePromise | None:
"""The send() method SHOULD be invoked after calling endheaders() if and only if the request
context specify explicitly that a body is going to be sent."""
raise NotImplementedError
async def ping(self) -> None: # type: ignore[override]
raise NotImplementedError

File diff suppressed because it is too large Load Diff