omlish 0.0.0.dev217__py3-none-any.whl → 0.0.0.dev219__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- omlish/__about__.py +3 -3
- omlish/docker/oci/__init__.py +0 -0
- omlish/docker/oci/data.py +71 -0
- omlish/docker/oci/media.py +124 -0
- omlish/formats/json5/Json5.g4 +0 -3
- omlish/http/coro/server.py +45 -25
- omlish/http/handlers.py +18 -1
- omlish/http/sessions.py +1 -1
- omlish/http/simple.py +101 -0
- omlish/iterators/tools.py +1 -0
- omlish/logs/all.py +13 -0
- omlish/logs/callers.py +45 -0
- omlish/logs/protocol.py +176 -0
- omlish/secrets/__init__.py +0 -24
- omlish/secrets/all.py +16 -0
- omlish/secrets/secrets.py +6 -0
- omlish/sockets/addresses.py +33 -12
- omlish/sockets/bind.py +333 -0
- omlish/sockets/handlers.py +4 -15
- omlish/sockets/io.py +69 -0
- omlish/sockets/server/__init__.py +0 -0
- omlish/sockets/server/handlers.py +134 -0
- omlish/sockets/server/server.py +152 -0
- omlish/sockets/server/threading.py +123 -0
- omlish/sql/alchemy/secrets.py +1 -1
- omlish/sql/dbs.py +1 -1
- {omlish-0.0.0.dev217.dist-info → omlish-0.0.0.dev219.dist-info}/METADATA +3 -3
- {omlish-0.0.0.dev217.dist-info → omlish-0.0.0.dev219.dist-info}/RECORD +32 -21
- omlish/docker/oci.py +0 -81
- omlish/sockets/server.py +0 -66
- {omlish-0.0.0.dev217.dist-info → omlish-0.0.0.dev219.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev217.dist-info → omlish-0.0.0.dev219.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev217.dist-info → omlish-0.0.0.dev219.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev217.dist-info → omlish-0.0.0.dev219.dist-info}/top_level.txt +0 -0
omlish/sockets/io.py
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
# @omlish-lite
|
3
|
+
import io
|
4
|
+
import socket
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
|
8
|
+
##
|
9
|
+
|
10
|
+
|
11
|
+
class SocketWriter(io.BufferedIOBase):
|
12
|
+
"""
|
13
|
+
Simple writable BufferedIOBase implementation for a socket
|
14
|
+
|
15
|
+
Does not hold data in a buffer, avoiding any need to call flush().
|
16
|
+
"""
|
17
|
+
|
18
|
+
def __init__(self, sock):
|
19
|
+
super().__init__()
|
20
|
+
|
21
|
+
self._sock = sock
|
22
|
+
|
23
|
+
def writable(self):
|
24
|
+
return True
|
25
|
+
|
26
|
+
def write(self, b):
|
27
|
+
self._sock.sendall(b)
|
28
|
+
with memoryview(b) as view:
|
29
|
+
return view.nbytes
|
30
|
+
|
31
|
+
def fileno(self):
|
32
|
+
return self._sock.fileno()
|
33
|
+
|
34
|
+
|
35
|
+
class SocketIoPair(ta.NamedTuple):
|
36
|
+
r: ta.BinaryIO
|
37
|
+
w: ta.BinaryIO
|
38
|
+
|
39
|
+
@classmethod
|
40
|
+
def from_socket(
|
41
|
+
cls,
|
42
|
+
sock: socket.socket,
|
43
|
+
*,
|
44
|
+
r_buf_size: int = -1,
|
45
|
+
w_buf_size: int = 0,
|
46
|
+
) -> 'SocketIoPair':
|
47
|
+
rf: ta.Any = sock.makefile('rb', r_buf_size)
|
48
|
+
|
49
|
+
if w_buf_size:
|
50
|
+
wf: ta.Any = SocketWriter(sock)
|
51
|
+
else:
|
52
|
+
wf = sock.makefile('wb', w_buf_size)
|
53
|
+
|
54
|
+
return cls(rf, wf)
|
55
|
+
|
56
|
+
|
57
|
+
##
|
58
|
+
|
59
|
+
|
60
|
+
def close_socket_immediately(sock: socket.socket) -> None:
|
61
|
+
try:
|
62
|
+
# Explicitly shutdown. socket.close() merely releases the socket and waits for GC to perform the actual close.
|
63
|
+
sock.shutdown(socket.SHUT_WR)
|
64
|
+
|
65
|
+
except OSError:
|
66
|
+
# Some platforms may raise ENOTCONN here
|
67
|
+
pass
|
68
|
+
|
69
|
+
sock.close()
|
File without changes
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
# @omlish-lite
|
3
|
+
import abc
|
4
|
+
import concurrent.futures as cf
|
5
|
+
import dataclasses as dc
|
6
|
+
import socket
|
7
|
+
import typing as ta
|
8
|
+
|
9
|
+
from ..addresses import SocketAndAddress
|
10
|
+
from ..handlers import SocketHandler
|
11
|
+
from ..io import SocketIoPair
|
12
|
+
from ..io import close_socket_immediately
|
13
|
+
|
14
|
+
|
15
|
+
SocketServerHandler = ta.Callable[[SocketAndAddress], None] # ta.TypeAlias
|
16
|
+
|
17
|
+
|
18
|
+
##
|
19
|
+
|
20
|
+
|
21
|
+
class SocketServerHandler_(abc.ABC): # noqa
|
22
|
+
@abc.abstractmethod
|
23
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
24
|
+
raise NotImplementedError
|
25
|
+
|
26
|
+
|
27
|
+
##
|
28
|
+
|
29
|
+
|
30
|
+
@dc.dataclass(frozen=True)
|
31
|
+
class StandardSocketServerHandler(SocketServerHandler_):
|
32
|
+
handler: SocketServerHandler
|
33
|
+
|
34
|
+
timeout: ta.Optional[float] = None
|
35
|
+
|
36
|
+
# http://bugs.python.org/issue6192
|
37
|
+
# TODO: https://eklitzke.org/the-caveats-of-tcp-nodelay
|
38
|
+
disable_nagle_algorithm: bool = False
|
39
|
+
|
40
|
+
no_close: bool = False
|
41
|
+
|
42
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
43
|
+
try:
|
44
|
+
if self.timeout is not None:
|
45
|
+
conn.socket.settimeout(self.timeout)
|
46
|
+
|
47
|
+
if self.disable_nagle_algorithm:
|
48
|
+
conn.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
|
49
|
+
|
50
|
+
self.handler(conn)
|
51
|
+
|
52
|
+
finally:
|
53
|
+
close_socket_immediately(conn.socket)
|
54
|
+
|
55
|
+
|
56
|
+
#
|
57
|
+
|
58
|
+
|
59
|
+
@dc.dataclass(frozen=True)
|
60
|
+
class CallbackWrappedSocketServerHandler(SocketServerHandler_):
|
61
|
+
handler: SocketServerHandler
|
62
|
+
|
63
|
+
before_handle: ta.Optional[SocketServerHandler] = None
|
64
|
+
after_handle: ta.Optional[SocketServerHandler] = None
|
65
|
+
|
66
|
+
# Return True if suppress like __exit__
|
67
|
+
on_error: ta.Optional[ta.Callable[[SocketAndAddress, Exception], bool]] = None
|
68
|
+
|
69
|
+
finally_: ta.Optional[SocketServerHandler] = None
|
70
|
+
|
71
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
72
|
+
try:
|
73
|
+
if (before_handle := self.before_handle) is not None:
|
74
|
+
before_handle(conn)
|
75
|
+
|
76
|
+
self.handler(conn)
|
77
|
+
|
78
|
+
except Exception as e:
|
79
|
+
if (on_error := self.on_error) is not None and on_error(conn, e):
|
80
|
+
pass
|
81
|
+
else:
|
82
|
+
raise
|
83
|
+
|
84
|
+
else:
|
85
|
+
if (after_handle := self.after_handle) is not None:
|
86
|
+
after_handle(conn)
|
87
|
+
|
88
|
+
finally:
|
89
|
+
if (finally_ := self.finally_) is not None:
|
90
|
+
finally_(conn)
|
91
|
+
|
92
|
+
|
93
|
+
#
|
94
|
+
|
95
|
+
|
96
|
+
@dc.dataclass(frozen=True)
|
97
|
+
class SocketHandlerSocketServerHandler(SocketServerHandler_):
|
98
|
+
handler: SocketHandler
|
99
|
+
|
100
|
+
r_buf_size: int = -1
|
101
|
+
w_buf_size: int = 0
|
102
|
+
|
103
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
104
|
+
fp = SocketIoPair.from_socket(
|
105
|
+
conn.socket,
|
106
|
+
r_buf_size=self.r_buf_size,
|
107
|
+
w_buf_size=self.w_buf_size,
|
108
|
+
)
|
109
|
+
|
110
|
+
self.handler(conn.address, fp)
|
111
|
+
|
112
|
+
|
113
|
+
#
|
114
|
+
|
115
|
+
|
116
|
+
@dc.dataclass(frozen=True)
|
117
|
+
class SocketWrappingSocketServerHandler(SocketServerHandler_):
|
118
|
+
handler: SocketServerHandler
|
119
|
+
wrapper: ta.Callable[[SocketAndAddress], SocketAndAddress]
|
120
|
+
|
121
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
122
|
+
wrapped_conn = self.wrapper(conn)
|
123
|
+
self.handler(wrapped_conn)
|
124
|
+
|
125
|
+
|
126
|
+
#
|
127
|
+
|
128
|
+
@dc.dataclass(frozen=True)
|
129
|
+
class ExecutorSocketServerHandler(SocketServerHandler_):
|
130
|
+
handler: SocketServerHandler
|
131
|
+
executor: cf.Executor
|
132
|
+
|
133
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
134
|
+
self.executor.submit(self.handler, conn)
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# @omlish-lite
|
2
|
+
# ruff: noqa: UP006 UP007
|
3
|
+
import abc
|
4
|
+
import contextlib
|
5
|
+
import selectors
|
6
|
+
import threading
|
7
|
+
import typing as ta
|
8
|
+
|
9
|
+
from ..bind import SocketBinder
|
10
|
+
from ..io import close_socket_immediately
|
11
|
+
from .handlers import SocketServerHandler
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
|
16
|
+
|
17
|
+
class SocketServer(abc.ABC):
|
18
|
+
def __init__(
|
19
|
+
self,
|
20
|
+
binder: SocketBinder,
|
21
|
+
handler: SocketServerHandler,
|
22
|
+
*,
|
23
|
+
on_error: ta.Optional[ta.Callable[[BaseException], None]] = None,
|
24
|
+
poll_interval: float = .5,
|
25
|
+
shutdown_timeout: ta.Optional[float] = None,
|
26
|
+
) -> None:
|
27
|
+
super().__init__()
|
28
|
+
|
29
|
+
self._binder = binder
|
30
|
+
self._handler = handler
|
31
|
+
self._on_error = on_error
|
32
|
+
self._poll_interval = poll_interval
|
33
|
+
self._shutdown_timeout = shutdown_timeout
|
34
|
+
|
35
|
+
self._lock = threading.RLock()
|
36
|
+
self._is_shutdown = threading.Event()
|
37
|
+
self._should_shutdown = False
|
38
|
+
|
39
|
+
@property
|
40
|
+
def binder(self) -> SocketBinder:
|
41
|
+
return self._binder
|
42
|
+
|
43
|
+
@property
|
44
|
+
def handler(self) -> SocketServerHandler:
|
45
|
+
return self._handler
|
46
|
+
|
47
|
+
#
|
48
|
+
|
49
|
+
class SelectorProtocol(ta.Protocol):
|
50
|
+
def register(self, *args, **kwargs) -> None:
|
51
|
+
raise NotImplementedError
|
52
|
+
|
53
|
+
def select(self, *args, **kwargs) -> bool:
|
54
|
+
raise NotImplementedError
|
55
|
+
|
56
|
+
Selector: ta.ClassVar[ta.Any]
|
57
|
+
if hasattr(selectors, 'PollSelector'):
|
58
|
+
Selector = selectors.PollSelector
|
59
|
+
else:
|
60
|
+
Selector = selectors.SelectSelector
|
61
|
+
|
62
|
+
#
|
63
|
+
|
64
|
+
@contextlib.contextmanager
|
65
|
+
def _listen_context(self) -> ta.Iterator[SelectorProtocol]:
|
66
|
+
with contextlib.ExitStack() as es:
|
67
|
+
es.enter_context(self._lock)
|
68
|
+
es.enter_context(self._binder)
|
69
|
+
|
70
|
+
self._binder.listen()
|
71
|
+
|
72
|
+
self._is_shutdown.clear()
|
73
|
+
try:
|
74
|
+
# XXX: Consider using another file descriptor or connecting to the socket to wake this up instead of
|
75
|
+
# polling. Polling reduces our responsiveness to a shutdown request and wastes cpu at all other times.
|
76
|
+
with self.Selector() as selector:
|
77
|
+
selector.register(self._binder.fileno(), selectors.EVENT_READ)
|
78
|
+
|
79
|
+
yield selector
|
80
|
+
|
81
|
+
finally:
|
82
|
+
self._is_shutdown.set()
|
83
|
+
|
84
|
+
@contextlib.contextmanager
|
85
|
+
def loop_context(self, poll_interval: ta.Optional[float] = None) -> ta.Iterator[ta.Iterator[bool]]:
|
86
|
+
if poll_interval is None:
|
87
|
+
poll_interval = self._poll_interval
|
88
|
+
|
89
|
+
with self._listen_context() as selector:
|
90
|
+
def loop():
|
91
|
+
while not self._should_shutdown:
|
92
|
+
ready = selector.select(poll_interval)
|
93
|
+
|
94
|
+
# bpo-35017: shutdown() called during select(), exit immediately.
|
95
|
+
if self._should_shutdown:
|
96
|
+
break # type: ignore[unreachable]
|
97
|
+
|
98
|
+
if ready:
|
99
|
+
try:
|
100
|
+
conn = self._binder.accept()
|
101
|
+
|
102
|
+
except OSError as exc:
|
103
|
+
if (on_error := self._on_error) is not None:
|
104
|
+
on_error(exc)
|
105
|
+
|
106
|
+
return
|
107
|
+
|
108
|
+
try:
|
109
|
+
self._handler(conn)
|
110
|
+
|
111
|
+
except Exception as exc: # noqa
|
112
|
+
if (on_error := self._on_error) is not None:
|
113
|
+
on_error(exc)
|
114
|
+
|
115
|
+
close_socket_immediately(conn.socket)
|
116
|
+
|
117
|
+
yield bool(ready)
|
118
|
+
|
119
|
+
yield loop()
|
120
|
+
|
121
|
+
def run(self, poll_interval: ta.Optional[float] = None) -> None:
|
122
|
+
with self.loop_context(poll_interval=poll_interval) as loop:
|
123
|
+
for _ in loop:
|
124
|
+
pass
|
125
|
+
|
126
|
+
#
|
127
|
+
|
128
|
+
class _NOT_SET: # noqa
|
129
|
+
def __new__(cls, *args, **kwargs): # noqa
|
130
|
+
raise TypeError
|
131
|
+
|
132
|
+
def shutdown(
|
133
|
+
self,
|
134
|
+
block: bool = False,
|
135
|
+
timeout: ta.Union[float, None, ta.Type[_NOT_SET]] = _NOT_SET,
|
136
|
+
) -> None:
|
137
|
+
self._should_shutdown = True
|
138
|
+
|
139
|
+
if block:
|
140
|
+
if timeout is self._NOT_SET:
|
141
|
+
timeout = self._shutdown_timeout
|
142
|
+
|
143
|
+
if not self._is_shutdown.wait(timeout=timeout): # type: ignore
|
144
|
+
raise TimeoutError
|
145
|
+
|
146
|
+
#
|
147
|
+
|
148
|
+
def __enter__(self) -> 'SocketServer':
|
149
|
+
return self
|
150
|
+
|
151
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
152
|
+
self.shutdown()
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# @omlish-lite
|
2
|
+
# ruff: noqa: UP006 UP007
|
3
|
+
import threading
|
4
|
+
import time
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
from ...lite.check import check
|
8
|
+
from ..addresses import SocketAndAddress
|
9
|
+
from .handlers import SocketServerHandler
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
class ThreadingSocketServerHandler:
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
handler: SocketServerHandler,
|
19
|
+
*,
|
20
|
+
shutdown_timeout: ta.Optional[float] = None,
|
21
|
+
) -> None:
|
22
|
+
super().__init__()
|
23
|
+
|
24
|
+
self._handler = handler
|
25
|
+
self._shutdown_timeout = shutdown_timeout
|
26
|
+
|
27
|
+
self._lock = threading.RLock()
|
28
|
+
self._threads: ta.List[threading.Thread] = []
|
29
|
+
self._is_shutdown = False
|
30
|
+
|
31
|
+
@property
|
32
|
+
def handler(self) -> SocketServerHandler:
|
33
|
+
return self._handler
|
34
|
+
|
35
|
+
#
|
36
|
+
|
37
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
38
|
+
self.handle(conn)
|
39
|
+
|
40
|
+
def handle(self, conn: SocketAndAddress) -> None:
|
41
|
+
with self._lock:
|
42
|
+
check.state(not self._is_shutdown)
|
43
|
+
|
44
|
+
self._reap()
|
45
|
+
|
46
|
+
t = threading.Thread(
|
47
|
+
target=self._handler,
|
48
|
+
args=(conn,),
|
49
|
+
)
|
50
|
+
|
51
|
+
self._threads.append(t)
|
52
|
+
|
53
|
+
t.start()
|
54
|
+
|
55
|
+
#
|
56
|
+
|
57
|
+
def _reap(self) -> None:
|
58
|
+
with self._lock:
|
59
|
+
self._threads[:] = (thread for thread in self._threads if thread.is_alive())
|
60
|
+
|
61
|
+
def is_alive(self) -> bool:
|
62
|
+
with self._lock:
|
63
|
+
self._reap()
|
64
|
+
|
65
|
+
return bool(self._threads)
|
66
|
+
|
67
|
+
def join(self, timeout: ta.Optional[float] = None) -> None:
|
68
|
+
if timeout is not None:
|
69
|
+
deadline: ta.Optional[float] = time.time() + timeout
|
70
|
+
else:
|
71
|
+
deadline = None
|
72
|
+
|
73
|
+
def calc_timeout() -> ta.Optional[float]:
|
74
|
+
if deadline is None:
|
75
|
+
return None
|
76
|
+
|
77
|
+
tt = deadline - time.time()
|
78
|
+
if tt <= 0:
|
79
|
+
raise TimeoutError
|
80
|
+
|
81
|
+
return tt
|
82
|
+
|
83
|
+
if not (self._lock.acquire(timeout=calc_timeout() or -1)):
|
84
|
+
raise TimeoutError
|
85
|
+
|
86
|
+
try:
|
87
|
+
self._reap()
|
88
|
+
|
89
|
+
for t in self._threads:
|
90
|
+
t.join(timeout=calc_timeout())
|
91
|
+
|
92
|
+
if t.is_alive():
|
93
|
+
raise TimeoutError
|
94
|
+
|
95
|
+
finally:
|
96
|
+
self._lock.release()
|
97
|
+
|
98
|
+
#
|
99
|
+
|
100
|
+
class _NOT_SET: # noqa
|
101
|
+
def __new__(cls, *args, **kwargs): # noqa
|
102
|
+
raise TypeError
|
103
|
+
|
104
|
+
def shutdown(
|
105
|
+
self,
|
106
|
+
block: bool = False,
|
107
|
+
timeout: ta.Union[float, None, ta.Type[_NOT_SET]] = _NOT_SET,
|
108
|
+
) -> None:
|
109
|
+
self._is_shutdown = True
|
110
|
+
|
111
|
+
if block:
|
112
|
+
if timeout is self._NOT_SET:
|
113
|
+
timeout = self._shutdown_timeout
|
114
|
+
|
115
|
+
self.join(timeout=timeout) # type: ignore
|
116
|
+
|
117
|
+
#
|
118
|
+
|
119
|
+
def __enter__(self) -> 'ThreadingSocketServerHandler':
|
120
|
+
return self
|
121
|
+
|
122
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
123
|
+
self.shutdown()
|
omlish/sql/alchemy/secrets.py
CHANGED
omlish/sql/dbs.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: omlish
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev219
|
4
4
|
Summary: omlish
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -18,7 +18,7 @@ Requires-Dist: sniffio~=1.3; extra == "all"
|
|
18
18
|
Requires-Dist: greenlet~=3.1; extra == "all"
|
19
19
|
Requires-Dist: trio~=0.27; extra == "all"
|
20
20
|
Requires-Dist: trio-asyncio~=0.15; extra == "all"
|
21
|
-
Requires-Dist: lz4~=4.
|
21
|
+
Requires-Dist: lz4~=4.4; extra == "all"
|
22
22
|
Requires-Dist: python-snappy~=0.7; extra == "all"
|
23
23
|
Requires-Dist: zstandard~=0.23; extra == "all"
|
24
24
|
Requires-Dist: brotli~=1.1; extra == "all"
|
@@ -57,7 +57,7 @@ Requires-Dist: greenlet~=3.1; extra == "async"
|
|
57
57
|
Requires-Dist: trio~=0.27; extra == "async"
|
58
58
|
Requires-Dist: trio-asyncio~=0.15; extra == "async"
|
59
59
|
Provides-Extra: compress
|
60
|
-
Requires-Dist: lz4~=4.
|
60
|
+
Requires-Dist: lz4~=4.4; extra == "compress"
|
61
61
|
Requires-Dist: python-snappy~=0.7; extra == "compress"
|
62
62
|
Requires-Dist: zstandard~=0.23; extra == "compress"
|
63
63
|
Requires-Dist: brotli~=1.1; extra == "compress"
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=YGmAnUBszmosQQ_7Hh2wwtDiYdYZ4unNKYzOtALuels,7968
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=XK2FqqJrrqiv22AiJ0Zjsv-tVj5fAtCQ0g6QGY3-xtU,3380
|
3
3
|
omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
|
4
4
|
omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
|
5
5
|
omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
|
@@ -224,9 +224,11 @@ omlish/docker/consts.py,sha256=wvwfUtEFrEWZKfREWqSMrx8xjjl8P5MNUSF6qzzgJHY,70
|
|
224
224
|
omlish/docker/detect.py,sha256=Qrdbosm2wJkxKDuy8gaGmbQoxk4Wnp1HJjAEz58NA8Y,614
|
225
225
|
omlish/docker/hub.py,sha256=7LIuJGdA-N1Y1dmo50ynKM1KUTcnQM_5XbtPbdT_QLU,3940
|
226
226
|
omlish/docker/manifests.py,sha256=LR4FpOGNUT3bZQ-gTjB6r_-1C3YiG30QvevZjrsVUQM,7068
|
227
|
-
omlish/docker/oci.py,sha256=wbiOpZQWZtiCtyoDpZhYyHvwkZv5przil9DRLAvHrfs,2743
|
228
227
|
omlish/docker/portrelay.py,sha256=QlRoTnQXs5INguR7XOj1xH0gNdL9SUeZm5z45DUctXo,1222
|
229
228
|
omlish/docker/timebomb.py,sha256=A_pgIDaXKsQwPiikrCTgIJl91gwYqkPGFY6j-Naq07Q,342
|
229
|
+
omlish/docker/oci/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
230
|
+
omlish/docker/oci/data.py,sha256=4KtSxziT70BhF30ozQ1SCfX4y0LT_5x0CuOKC4zrEV4,2616
|
231
|
+
omlish/docker/oci/media.py,sha256=fJ8VcU-edDpg-FyJQamw-sUlhTghkC-WQ1TC4MiRpFU,4499
|
230
232
|
omlish/formats/__init__.py,sha256=T0AG1gFnqQ5JiHN0UPQjQ-7g5tnxMIG-mgOvMYExYAM,21
|
231
233
|
omlish/formats/cbor.py,sha256=o_Hbe4kthO9CeXK-FySrw0dHVlrdyTo2Y8PpGRDfZ3c,514
|
232
234
|
omlish/formats/cloudpickle.py,sha256=16si4yUp_pAdDWGECAWf6HLA2PwSANGGgDoMLGZUem8,579
|
@@ -262,7 +264,7 @@ omlish/formats/json/stream/errors.py,sha256=c8M8UAYmIZ-vWZLeKD2jMj4EDCJbr9QR8Jq_
|
|
262
264
|
omlish/formats/json/stream/lex.py,sha256=ItsWvtl5SZH-HwQtPy8Cpf4nszqDzvUTdIOEmSRiZ-E,6807
|
263
265
|
omlish/formats/json/stream/parse.py,sha256=JuYmXwtTHmQJTFKoJNoEHUpCPxXdl_gvKPykVXgED34,6208
|
264
266
|
omlish/formats/json/stream/render.py,sha256=NtmDsN92xZi5dkgSSuMeMXMAiJblmjz1arB4Ft7vBhc,3715
|
265
|
-
omlish/formats/json5/Json5.g4,sha256=
|
267
|
+
omlish/formats/json5/Json5.g4,sha256=ZUmgJPvj8lSMUD_v3wijp10ZQExYB5mu5Q089dYEJSU,2389
|
266
268
|
omlish/formats/json5/__init__.py,sha256=BsjPz5zJDji3GjQ8x8hWvcl1GYPV_ZIHnE3c2Sr8aTU,102
|
267
269
|
omlish/formats/json5/codec.py,sha256=ldnxCRo0JP1fkGLt0mMxJlLvNxqIF_1KUCcSp1HtI-M,452
|
268
270
|
omlish/formats/json5/errors.py,sha256=AHkR9ySjAoQdUrizpqgL8fg0M5oe5mHZkml3KZHEvC4,38
|
@@ -299,19 +301,20 @@ omlish/http/consts.py,sha256=7BJ4D1MdIvqBcepkgCfBFHolgTwbOlqsOEiee_IjxOA,2289
|
|
299
301
|
omlish/http/cookies.py,sha256=uuOYlHR6e2SC3GM41V0aozK10nef9tYg83Scqpn5-HM,6351
|
300
302
|
omlish/http/dates.py,sha256=Otgp8wRxPgNGyzx8LFowu1vC4EKJYARCiAwLFncpfHM,2875
|
301
303
|
omlish/http/encodings.py,sha256=w2WoKajpaZnQH8j-IBvk5ZFL2O2pAU_iBvZnkocaTlw,164
|
302
|
-
omlish/http/handlers.py,sha256=
|
304
|
+
omlish/http/handlers.py,sha256=_MdO62GGKqzCabSSmA9uCMTB41b6sSC0AFJCpPJ9vOU,1232
|
303
305
|
omlish/http/headers.py,sha256=ZMmjrEiYjzo0YTGyK0YsvjdwUazktGqzVVYorY4fd44,5081
|
304
306
|
omlish/http/json.py,sha256=9XwAsl4966Mxrv-1ytyCqhcE6lbBJw-0_tFZzGszgHE,7440
|
305
307
|
omlish/http/jwt.py,sha256=6Rigk1WrJ059DY4jDIKnxjnChWb7aFdermj2AI2DSvk,4346
|
306
308
|
omlish/http/multipart.py,sha256=R9ycpHsXRcmh0uoc43aYb7BdWL-8kSQHe7J-M81aQZM,2240
|
307
309
|
omlish/http/parsing.py,sha256=hxfd9nYaAAjYIivkTClFZXMRmiiCnxzeeEIGXw7-gt0,13992
|
308
|
-
omlish/http/sessions.py,sha256=
|
310
|
+
omlish/http/sessions.py,sha256=TfTJ_j-6c9PelG_RmijEwozfaVm3O7YzgtFvp8VzQqM,4799
|
311
|
+
omlish/http/simple.py,sha256=9WtpbQahiZE-UjRP3ZDni8DQTq_HkVSdwpui_y8mf1I,2867
|
309
312
|
omlish/http/sse.py,sha256=MDs9RvxQXoQliImcc6qK1ERajEYM7Q1l8xmr-9ceNBc,2315
|
310
313
|
omlish/http/versions.py,sha256=wSiOXPiClVjkVgSU_VmxkoD1SUYGaoPbP0U5Aw-Ufg8,409
|
311
314
|
omlish/http/wsgi.py,sha256=czZsVUX-l2YTlMrUjKN49wRoP4rVpS0qpeBn4O5BoMY,948
|
312
315
|
omlish/http/coro/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
313
316
|
omlish/http/coro/fdio.py,sha256=ajj_lekRockGwQEw8m_mi6RO9-o6hnC9ITiwtZe3y-s,4017
|
314
|
-
omlish/http/coro/server.py,sha256
|
317
|
+
omlish/http/coro/server.py,sha256=QujEUM2fhfy2GsoKhpHZvFv7SlGVwcU8kwUXEyUgwWk,18791
|
315
318
|
omlish/inject/__init__.py,sha256=n0RC9UDGsBQQ39cST39-XJqJPq2M0tnnh9yJubW9azo,1891
|
316
319
|
omlish/inject/binder.py,sha256=DAbc8TZi5w8Mna0TUtq0mT4jeDVA7i7SlBtOFrh2swc,4185
|
317
320
|
omlish/inject/bindings.py,sha256=pLXn2U3kvmAS-68IOG-tr77DbiI-wp9hGyy4lhG6_H8,525
|
@@ -373,7 +376,7 @@ omlish/io/fdio/pollers.py,sha256=yNadAt3W5wd90PFmd3vD77bq5QwoVb2A6SM2JjZpKRs,550
|
|
373
376
|
omlish/iterators/__init__.py,sha256=yMavf5FofiS1EU4UFuWPXiFZ03W0H-y7MuMxW8FUaEE,358
|
374
377
|
omlish/iterators/iterators.py,sha256=ghI4dO6WPyyFOLTIIMaHQ_IOy2xXaFpGPqveZ5YGIBU,3158
|
375
378
|
omlish/iterators/recipes.py,sha256=53mkexitMhkwXQZbL6DrhpT0WePQ_56uXd5Jaw3DfzI,467
|
376
|
-
omlish/iterators/tools.py,sha256=
|
379
|
+
omlish/iterators/tools.py,sha256=Pi4ybXytUXVZ3xwK89xpPImQfYYId9p1vIFQvVqVLqA,2551
|
377
380
|
omlish/iterators/unique.py,sha256=0jAX3kwzVfRNhe0Tmh7kVP_Q2WBIn8POo_O-rgFV0rQ,1390
|
378
381
|
omlish/lang/__init__.py,sha256=sY7YSgN772n48qWlR-mwuOOCOwRF5Fh421gZqZWxYlw,4042
|
379
382
|
omlish/lang/cached.py,sha256=92TvRZQ6sWlm7dNn4hgl7aWKbX0J1XUEo3DRjBpgVQk,7834
|
@@ -429,13 +432,15 @@ omlish/lite/types.py,sha256=fP5EMyBdEp2LmDxcHjUDtwAMdR06ISr9lKOL7smWfHM,140
|
|
429
432
|
omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
|
430
433
|
omlish/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
431
434
|
omlish/logs/abc.py,sha256=ho4ABKYMKX-V7g4sp1BByuOLzslYzLlQ0MESmjEpT-o,8005
|
432
|
-
omlish/logs/all.py,sha256=
|
435
|
+
omlish/logs/all.py,sha256=Er2NIcDvlMpuAcRr9b_uMHeoERU7I6lu5oLrDGRdV0U,728
|
436
|
+
omlish/logs/callers.py,sha256=W0BdEtuGkQ0JM-FCsXQIBQCsNUbIsbDrtCaJy9DStk4,1143
|
433
437
|
omlish/logs/color.py,sha256=CM-ceoPXs0j5_klnZDJkFCFRgHOToFzJyLjC6LsnPEk,665
|
434
438
|
omlish/logs/configs.py,sha256=XOc8rWxfPpPMxJESVD2mLCUoLtbQnGnZwvYhhqe7DD8,772
|
435
439
|
omlish/logs/filters.py,sha256=2noFRyBez3y519fpfsDSt1vo8wX-85b8sMXZi5o_xyE,208
|
436
440
|
omlish/logs/handlers.py,sha256=zgSnKQA5q9Fu7T0Nkd7twog9H1Wg9-bDCzz4_F1TOBo,319
|
437
441
|
omlish/logs/json.py,sha256=zyqMWpZY3lk4WRk4wgmataBomGX9S3iDsydiM1sS-lI,1366
|
438
442
|
omlish/logs/noisy.py,sha256=Ubc-eTH6ZbGYsLfUUi69JAotwuUwzb-SJBeGo_0dIZI,348
|
443
|
+
omlish/logs/protocol.py,sha256=NzyCeNBN-fyKpJinhECfjUQSd5MxZLiYbuLCTtW6QUU,4500
|
439
444
|
omlish/logs/proxy.py,sha256=A-ROPUUAlF397qTbEqhel6YhQMstNuXL3Xmts7w9dAo,2347
|
440
445
|
omlish/logs/standard.py,sha256=FbKdF2Z4Na5i2TNwKn0avLJXyICe2JKsPufjvKCHGn0,3162
|
441
446
|
omlish/logs/utils.py,sha256=mzHrZ9ji75p5A8qR29eUr05CBAHMb8J753MSkID_VaQ,393
|
@@ -496,18 +501,24 @@ omlish/reflect/inspect.py,sha256=veJ424-9oZrqyvhVpvxOi7hcKW-PDBkdYL2yjrFlk4o,495
|
|
496
501
|
omlish/reflect/ops.py,sha256=RJ6jzrM4ieFsXzWyNXWV43O_WgzEaUvlHSc5N2ezW2A,2044
|
497
502
|
omlish/reflect/subst.py,sha256=g3q7NmNWsmc67mcchmCE3WFPCMDSBq-FXn4ah-DWL_U,3622
|
498
503
|
omlish/reflect/types.py,sha256=lYxK_hlC4kVDMKeDYJp0mymSth21quwuFAMAEFBznyE,9151
|
499
|
-
omlish/secrets/__init__.py,sha256=
|
504
|
+
omlish/secrets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
505
|
+
omlish/secrets/all.py,sha256=zRp3bYkcVG4Aez4hBHKBxc07s6u74IrGQVUB8cfrGxY,281
|
500
506
|
omlish/secrets/crypto.py,sha256=6CsLy0UEqCrBK8Xx_3-iFF6SKtu2GlEqUQ8-MliY3tk,3709
|
501
507
|
omlish/secrets/marshal.py,sha256=U9uSRTWzZmumfNZeh_dROwVdGrARsp155TylRbjilP8,2048
|
502
508
|
omlish/secrets/openssl.py,sha256=wxA_wIlxtuOUy71ABxAJgavh-UI_taOfm-A0dVlmSwM,6219
|
503
509
|
omlish/secrets/pwgen.py,sha256=v-5ztnOTHTAWXLGR-3H6HkMj2nPIZBMbo5xWR3q0rDY,1707
|
504
510
|
omlish/secrets/pwhash.py,sha256=Goktn-swmC6PXqfRBnDrH_Lr42vjckT712UyErPjzkw,4102
|
505
|
-
omlish/secrets/secrets.py,sha256=
|
511
|
+
omlish/secrets/secrets.py,sha256=QNgOmRcIRK2fx49bIbBBM2rYbe6IhhLgk8fKvq8guoI,7963
|
506
512
|
omlish/secrets/subprocesses.py,sha256=ffjfbgPbEE_Pwb_87vG4yYR2CGZy3I31mHNCo_0JtHw,1212
|
507
513
|
omlish/sockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
508
|
-
omlish/sockets/addresses.py,sha256=
|
509
|
-
omlish/sockets/
|
510
|
-
omlish/sockets/
|
514
|
+
omlish/sockets/addresses.py,sha256=vbVeQBkzI513H4vRv-JS89QtRbr9U8v5zqkm3oODl_s,1869
|
515
|
+
omlish/sockets/bind.py,sha256=rNX-1VWYR0IlOLo4S0qqfm1PwqfjvSvHiFj7DE2_gIE,7914
|
516
|
+
omlish/sockets/handlers.py,sha256=ux2cPzAWV8b-mQ0K08-b7qjVeIT8Js5_-tyVZs0fbwg,406
|
517
|
+
omlish/sockets/io.py,sha256=lfhTkB7NnAIx9kuQhAkwgsEUXY78Mp1_WtYrIQNS_k8,1408
|
518
|
+
omlish/sockets/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
519
|
+
omlish/sockets/server/handlers.py,sha256=-5lH2Xg7gnZiPB4t2Asa_Vgblj1ZkHzLvyiC_K4XlNc,3295
|
520
|
+
omlish/sockets/server/server.py,sha256=kIQ8hHpc9GVefX7sGUrs6bhpJybaagYVwKq5QRT5B4s,4463
|
521
|
+
omlish/sockets/server/threading.py,sha256=YmW3Ym_p5j_F4SIH9BgRHIObywjq1HS39j9CGWIcMAY,2856
|
511
522
|
omlish/specs/__init__.py,sha256=zZwF8yXTEkSstYtORkDhVLK-_hWU8WOJCuBpognb_NY,118
|
512
523
|
omlish/specs/jmespath/LICENSE,sha256=IH-ZZlZkS8XMkf_ubNVD1aYHQ2l_wd0tmHtXrCcYpRU,1113
|
513
524
|
omlish/specs/jmespath/__init__.py,sha256=9tsrquw1kXe1KAhTP3WeL0GlGBiTguQVxsC-lUYTWP4,2087
|
@@ -552,14 +563,14 @@ omlish/specs/openapi/openapi.py,sha256=y4h04jeB7ORJSVrcy7apaBdpwLjIyscv1Ub5SderH
|
|
552
563
|
omlish/sql/__init__.py,sha256=TpZLsEJKJzvJ0eMzuV8hwOJJbkxBCV1RZPUMLAVB6io,173
|
553
564
|
omlish/sql/abc.py,sha256=NfbcIlEvdEu6vn0TolhfYb2SO5uzUmY0kARCbg6uVAU,1879
|
554
565
|
omlish/sql/dbapi.py,sha256=5ghJH-HexsmDlYdWlhf00nCGQX2IC98_gxIxMkucOas,3195
|
555
|
-
omlish/sql/dbs.py,sha256=
|
566
|
+
omlish/sql/dbs.py,sha256=65e388987upJpsFX8bNL7uhiYv2sCsmk9Y04V0MXdsI,1873
|
556
567
|
omlish/sql/params.py,sha256=Z4VPet6GhNqD1T_MXSWSHkdy3cpUEhST-OplC4B_fYI,4433
|
557
568
|
omlish/sql/qualifiedname.py,sha256=rlW3gVmyucJbqwcxj_7BfK4X2HoXrMroZT2H45zPgJQ,2264
|
558
569
|
omlish/sql/alchemy/__init__.py,sha256=1ruDMiviH5fjevn2xVki-QspcE9O3VPy4hxOqpHjI2s,224
|
559
570
|
omlish/sql/alchemy/asyncs.py,sha256=MwZwWIaZsUCQLcTA8mdHUPZmR-pXEVSAsvd15FCm3W4,3692
|
560
571
|
omlish/sql/alchemy/duckdb.py,sha256=kr7pIhiBLNAuZrcigHDtFg9zHkVcrRW3LfryO9VJ4mk,3749
|
561
572
|
omlish/sql/alchemy/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
|
562
|
-
omlish/sql/alchemy/secrets.py,sha256=
|
573
|
+
omlish/sql/alchemy/secrets.py,sha256=WEeaec1ejQcE3Yaa7p5BSP9AMGEzy1lwr7QMSRL0VBw,180
|
563
574
|
omlish/sql/alchemy/sqlean.py,sha256=RbkuOuFIfM4fowwKk8-sQ6Dxk-tTUwxS94nY5Kxt52s,403
|
564
575
|
omlish/sql/queries/__init__.py,sha256=8wdq6PBf5YzqQWFu-CE8om6BN38sDAD9UEz9VzkojzM,1337
|
565
576
|
omlish/sql/queries/base.py,sha256=_8O3MbH_OEjBnhp2oIJUZ3ClaQ8l4Sj9BdPdsP0Ie-g,224
|
@@ -628,9 +639,9 @@ omlish/text/indent.py,sha256=YjtJEBYWuk8--b9JU_T6q4yxV85_TR7VEVr5ViRCFwk,1336
|
|
628
639
|
omlish/text/minja.py,sha256=jZC-fp3Xuhx48ppqsf2Sf1pHbC0t8XBB7UpUUoOk2Qw,5751
|
629
640
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
630
641
|
omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
|
631
|
-
omlish-0.0.0.
|
632
|
-
omlish-0.0.0.
|
633
|
-
omlish-0.0.0.
|
634
|
-
omlish-0.0.0.
|
635
|
-
omlish-0.0.0.
|
636
|
-
omlish-0.0.0.
|
642
|
+
omlish-0.0.0.dev219.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
643
|
+
omlish-0.0.0.dev219.dist-info/METADATA,sha256=lh7Dpy8tG4NhG-VPo4QWw-EnYsyHj1OY8pnJOIEfQm8,4176
|
644
|
+
omlish-0.0.0.dev219.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
645
|
+
omlish-0.0.0.dev219.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
646
|
+
omlish-0.0.0.dev219.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
647
|
+
omlish-0.0.0.dev219.dist-info/RECORD,,
|