hypern 0.2.1__cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl → 0.3.0__cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hypern/application.py +27 -3
- hypern/hypern.cpython-310-i386-linux-gnu.so +0 -0
- hypern/hypern.pyi +32 -3
- hypern/middleware/limit.py +1 -1
- hypern/processpool.py +9 -3
- hypern/routing/route.py +1 -1
- hypern/ws.py +16 -0
- {hypern-0.2.1.dist-info → hypern-0.3.0.dist-info}/METADATA +2 -2
- {hypern-0.2.1.dist-info → hypern-0.3.0.dist-info}/RECORD +11 -10
- {hypern-0.2.1.dist-info → hypern-0.3.0.dist-info}/WHEEL +1 -1
- {hypern-0.2.1.dist-info → hypern-0.3.0.dist-info}/licenses/LICENSE +0 -0
hypern/application.py
CHANGED
|
@@ -8,8 +8,7 @@ import orjson
|
|
|
8
8
|
from typing_extensions import Annotated, Doc
|
|
9
9
|
|
|
10
10
|
from hypern.datastructures import Contact, HTTPMethod, Info, License
|
|
11
|
-
from hypern.hypern import FunctionInfo, Router
|
|
12
|
-
from hypern.hypern import Route as InternalRoute
|
|
11
|
+
from hypern.hypern import FunctionInfo, Router, Route as InternalRoute, WebsocketRouter
|
|
13
12
|
from hypern.openapi import SchemaGenerator, SwaggerUI
|
|
14
13
|
from hypern.processpool import run_processes
|
|
15
14
|
from hypern.response import HTMLResponse, JSONResponse
|
|
@@ -17,6 +16,7 @@ from hypern.routing import Route
|
|
|
17
16
|
from hypern.scheduler import Scheduler
|
|
18
17
|
from hypern.middleware import Middleware
|
|
19
18
|
from hypern.args_parser import ArgsConfig
|
|
19
|
+
from hypern.ws import WebsocketRoute
|
|
20
20
|
|
|
21
21
|
AppType = TypeVar("AppType", bound="Hypern")
|
|
22
22
|
|
|
@@ -47,6 +47,15 @@ class Hypern:
|
|
|
47
47
|
"""
|
|
48
48
|
),
|
|
49
49
|
] = None,
|
|
50
|
+
websockets: Annotated[
|
|
51
|
+
List[WebsocketRoute] | None,
|
|
52
|
+
Doc(
|
|
53
|
+
"""
|
|
54
|
+
A list of routes to serve incoming WebSocket requests.
|
|
55
|
+
You can define routes using the `WebsocketRoute` class from `Hypern
|
|
56
|
+
"""
|
|
57
|
+
),
|
|
58
|
+
] = None,
|
|
50
59
|
title: Annotated[
|
|
51
60
|
str,
|
|
52
61
|
Doc(
|
|
@@ -186,6 +195,7 @@ class Hypern:
|
|
|
186
195
|
) -> None:
|
|
187
196
|
super().__init__(*args, **kwargs)
|
|
188
197
|
self.router = Router(path="/")
|
|
198
|
+
self.websocket_router = WebsocketRouter(path="/")
|
|
189
199
|
self.scheduler = scheduler
|
|
190
200
|
self.injectables = default_injectables or {}
|
|
191
201
|
self.middleware_before_request = []
|
|
@@ -193,9 +203,12 @@ class Hypern:
|
|
|
193
203
|
self.response_headers = {}
|
|
194
204
|
self.args = ArgsConfig()
|
|
195
205
|
|
|
196
|
-
for route in routes:
|
|
206
|
+
for route in routes or []:
|
|
197
207
|
self.router.extend_route(route(app=self).routes)
|
|
198
208
|
|
|
209
|
+
for websocket_route in websockets or []:
|
|
210
|
+
self.websocket_router.add_route(websocket_route)
|
|
211
|
+
|
|
199
212
|
if openapi_url and docs_url:
|
|
200
213
|
self.__add_openapi(
|
|
201
214
|
info=Info(
|
|
@@ -358,6 +371,7 @@ class Hypern:
|
|
|
358
371
|
processes=self.args.processes,
|
|
359
372
|
max_blocking_threads=self.args.max_blocking_threads,
|
|
360
373
|
router=self.router,
|
|
374
|
+
websocket_router=self.websocket_router,
|
|
361
375
|
injectables=self.injectables,
|
|
362
376
|
before_request=self.middleware_before_request,
|
|
363
377
|
after_request=self.middleware_after_request,
|
|
@@ -379,3 +393,13 @@ class Hypern:
|
|
|
379
393
|
func_info = FunctionInfo(handler=handler, is_async=is_async)
|
|
380
394
|
route = InternalRoute(path=endpoint, function=func_info, method=method.name)
|
|
381
395
|
self.router.add_route(route=route)
|
|
396
|
+
|
|
397
|
+
def add_websocket(self, ws_route: WebsocketRoute):
|
|
398
|
+
"""
|
|
399
|
+
Adds a WebSocket route to the WebSocket router.
|
|
400
|
+
|
|
401
|
+
Args:
|
|
402
|
+
ws_route (WebsocketRoute): The WebSocket route to be added to the router.
|
|
403
|
+
"""
|
|
404
|
+
for route in ws_route.routes:
|
|
405
|
+
self.websocket_router.add_route(route=route)
|
|
Binary file
|
hypern/hypern.pyi
CHANGED
|
@@ -183,9 +183,6 @@ class FunctionInfo:
|
|
|
183
183
|
handler: Callable
|
|
184
184
|
is_async: bool
|
|
185
185
|
|
|
186
|
-
class SocketHeld:
|
|
187
|
-
socket: Any
|
|
188
|
-
|
|
189
186
|
@dataclass
|
|
190
187
|
class Server:
|
|
191
188
|
router: Router
|
|
@@ -195,6 +192,7 @@ class Server:
|
|
|
195
192
|
|
|
196
193
|
def add_route(self, route: Route) -> None: ...
|
|
197
194
|
def set_router(self, router: Router) -> None: ...
|
|
195
|
+
def set_websocket_router(self, websocket_router: WebsocketRouter) -> None: ...
|
|
198
196
|
def start(self, socket: SocketHeld, worker: int, max_blocking_threads: int) -> None: ...
|
|
199
197
|
def inject(self, key: str, value: Any) -> None: ...
|
|
200
198
|
def set_injected(self, injected: Dict[str, Any]) -> None: ...
|
|
@@ -227,6 +225,34 @@ class Router:
|
|
|
227
225
|
def get_routes_by_method(self, method: str) -> List[Route]: ...
|
|
228
226
|
def extend_route(self, routes: List[Route]) -> None: ...
|
|
229
227
|
|
|
228
|
+
@dataclass
|
|
229
|
+
class SocketHeld:
|
|
230
|
+
socket: Any
|
|
231
|
+
|
|
232
|
+
@dataclass
|
|
233
|
+
class WebSocketSession:
|
|
234
|
+
sender: Callable[[str], None]
|
|
235
|
+
receiver: Callable[[], str]
|
|
236
|
+
is_closed: bool
|
|
237
|
+
|
|
238
|
+
def send(self, message: str) -> None: ...
|
|
239
|
+
|
|
240
|
+
@dataclass
|
|
241
|
+
class WebsocketRoute:
|
|
242
|
+
path: str
|
|
243
|
+
handler: Callable[[WebSocketSession], None]
|
|
244
|
+
|
|
245
|
+
@dataclass
|
|
246
|
+
class WebsocketRouter:
|
|
247
|
+
path: str
|
|
248
|
+
routes: List[WebsocketRoute]
|
|
249
|
+
|
|
250
|
+
def add_route(self, route: WebsocketRoute) -> None: ...
|
|
251
|
+
def remove_route(self, path: str) -> None: ...
|
|
252
|
+
def extend_route(self, route: WebsocketRoute) -> None: ...
|
|
253
|
+
def clear_routes(self) -> None: ...
|
|
254
|
+
def route_count(self) -> int: ...
|
|
255
|
+
|
|
230
256
|
@dataclass
|
|
231
257
|
class Header:
|
|
232
258
|
headers: Dict[str, str]
|
|
@@ -264,3 +290,6 @@ class Request:
|
|
|
264
290
|
path_params: Dict[str, str]
|
|
265
291
|
body: BodyData
|
|
266
292
|
method: str
|
|
293
|
+
remote_addr: str
|
|
294
|
+
timestamp: float
|
|
295
|
+
context_id: str
|
hypern/middleware/limit.py
CHANGED
hypern/processpool.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import Any, Dict, List
|
|
|
7
7
|
from multiprocess import Process
|
|
8
8
|
from watchdog.observers import Observer
|
|
9
9
|
|
|
10
|
-
from .hypern import FunctionInfo, Router, Server, SocketHeld
|
|
10
|
+
from .hypern import FunctionInfo, Router, Server, SocketHeld, WebsocketRouter
|
|
11
11
|
from .logging import logger
|
|
12
12
|
from .reload import EventHandler
|
|
13
13
|
|
|
@@ -19,6 +19,7 @@ def run_processes(
|
|
|
19
19
|
processes: int,
|
|
20
20
|
max_blocking_threads: int,
|
|
21
21
|
router: Router,
|
|
22
|
+
websocket_router: WebsocketRouter,
|
|
22
23
|
injectables: Dict[str, Any],
|
|
23
24
|
before_request: List[FunctionInfo],
|
|
24
25
|
after_request: List[FunctionInfo],
|
|
@@ -27,7 +28,9 @@ def run_processes(
|
|
|
27
28
|
) -> List[Process]:
|
|
28
29
|
socket = SocketHeld(host, port)
|
|
29
30
|
|
|
30
|
-
process_pool = init_processpool(
|
|
31
|
+
process_pool = init_processpool(
|
|
32
|
+
router, websocket_router, socket, workers, processes, max_blocking_threads, injectables, before_request, after_request, response_headers
|
|
33
|
+
)
|
|
31
34
|
|
|
32
35
|
def terminating_signal_handler(_sig, _frame):
|
|
33
36
|
logger.info("Terminating server!!")
|
|
@@ -67,6 +70,7 @@ def run_processes(
|
|
|
67
70
|
|
|
68
71
|
def init_processpool(
|
|
69
72
|
router: Router,
|
|
73
|
+
websocket_router: WebsocketRouter,
|
|
70
74
|
socket: SocketHeld,
|
|
71
75
|
workers: int,
|
|
72
76
|
processes: int,
|
|
@@ -82,7 +86,7 @@ def init_processpool(
|
|
|
82
86
|
copied_socket = socket.try_clone()
|
|
83
87
|
process = Process(
|
|
84
88
|
target=spawn_process,
|
|
85
|
-
args=(router, copied_socket, workers, max_blocking_threads, injectables, before_request, after_request, response_headers),
|
|
89
|
+
args=(router, websocket_router, copied_socket, workers, max_blocking_threads, injectables, before_request, after_request, response_headers),
|
|
86
90
|
)
|
|
87
91
|
process.start()
|
|
88
92
|
process_pool.append(process)
|
|
@@ -106,6 +110,7 @@ def initialize_event_loop():
|
|
|
106
110
|
|
|
107
111
|
def spawn_process(
|
|
108
112
|
router: Router,
|
|
113
|
+
websocket_router: WebsocketRouter,
|
|
109
114
|
socket: SocketHeld,
|
|
110
115
|
workers: int,
|
|
111
116
|
max_blocking_threads: int,
|
|
@@ -118,6 +123,7 @@ def spawn_process(
|
|
|
118
123
|
|
|
119
124
|
server = Server()
|
|
120
125
|
server.set_router(router=router)
|
|
126
|
+
server.set_websocket_router(websocket_router=websocket_router)
|
|
121
127
|
server.set_injected(injected=injectables)
|
|
122
128
|
server.set_before_hooks(hooks=before_request)
|
|
123
129
|
server.set_after_hooks(hooks=after_request)
|
hypern/routing/route.py
CHANGED
|
@@ -188,7 +188,7 @@ class Route:
|
|
|
188
188
|
docs["responses"] = {
|
|
189
189
|
"200": {
|
|
190
190
|
"description": "Successful response",
|
|
191
|
-
"content": {"application/json": {"schema": response_type.
|
|
191
|
+
"content": {"application/json": {"schema": pydantic_to_swagger(response_type).get(response_type.__name__)}},
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
|
hypern/ws.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .hypern import WebsocketRoute as WebsocketRouteInternal, WebSocketSession
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class WebsocketRoute:
|
|
5
|
+
def __init__(self) -> None:
|
|
6
|
+
self.routes = []
|
|
7
|
+
|
|
8
|
+
def on(self, path):
|
|
9
|
+
def wrapper(func):
|
|
10
|
+
self.routes.append(WebsocketRouteInternal(path, func))
|
|
11
|
+
return func
|
|
12
|
+
|
|
13
|
+
return wrapper
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ["WebsocketRoute", "WebSocketSession"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: hypern
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
hypern-0.
|
|
2
|
-
hypern-0.
|
|
3
|
-
hypern-0.
|
|
4
|
-
hypern/application.py,sha256=
|
|
1
|
+
hypern-0.3.0.dist-info/METADATA,sha256=SINnZRpXUXjLnonzyUZ-STXzjY1JRGPl_nu0vqF0Qkg,3658
|
|
2
|
+
hypern-0.3.0.dist-info/WHEEL,sha256=FoUXvRjrx9srB--PKQ_WTjugQ9iTCsmmZ8FeY4NnMw8,125
|
|
3
|
+
hypern-0.3.0.dist-info/licenses/LICENSE,sha256=VdbaK2hSaaD-LUjtDIlEbeZVmvLGK7BEQvltP3mv-cY,1304
|
|
4
|
+
hypern/application.py,sha256=yXrKhVKwCQDweHoZPFyWr0ws7nmCOPp6H3aLZLbD7sw,13923
|
|
5
5
|
hypern/middleware/__init__.py,sha256=YpgxL7GQkzZM91VCNxHT2xmTa1R1b_BUS8n3tZ2b1Ys,268
|
|
6
6
|
hypern/middleware/cors.py,sha256=SfG-3vAS-4MPXqsIsegNwDx9mqC9lvgUc3RuYzN6HNg,1643
|
|
7
7
|
hypern/middleware/base.py,sha256=Llcg9wglcumvY4BqaTfrX1OOZDqns4wb34wGF55EXcI,523
|
|
8
|
-
hypern/middleware/limit.py,sha256=
|
|
8
|
+
hypern/middleware/limit.py,sha256=9EA79q2GgyZkRynMJj8rfgumEhJKbAvyi3jII6A_BX8,7976
|
|
9
9
|
hypern/middleware/i18n.py,sha256=s82nQo6kKClZ0s3G3jsy87VRfwxpBDbASB_ErjRL3O0,15
|
|
10
10
|
hypern/routing/dispatcher.py,sha256=aujogCVTz2mYtZRkEtmpdlxXA9l6X4D072qOiIg-a_Q,2301
|
|
11
11
|
hypern/routing/__init__.py,sha256=MtyPYRHYMWIiCReZsUjJH93PvluotCbPU3RnWFQQmrA,97
|
|
12
|
-
hypern/routing/route.py,sha256=
|
|
12
|
+
hypern/routing/route.py,sha256=AZc4Qo5iy74q0_U8E5X6RIsudznHZYEZR8MdHRoCmB4,10119
|
|
13
13
|
hypern/routing/endpoint.py,sha256=AWLHLQNlSGR8IGU6xM0RP-1kP06OJQzqpbXKSiZEzEo,996
|
|
14
14
|
hypern/routing/parser.py,sha256=4BFn8MAmSX1QplwBXEEgbabYiNUAllYf2svPZoPPD5k,3454
|
|
15
15
|
hypern/response/__init__.py,sha256=9z99BDgASpG404GK8LGkOsXgac0wFwH_cQOTI5Ju-1U,223
|
|
16
16
|
hypern/response/response.py,sha256=s6KqscjA7jl8RaZh5gZQgVksPtHKzsRrQywDcEjVSR4,4448
|
|
17
17
|
hypern/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
hypern/
|
|
18
|
+
hypern/ws.py,sha256=XImBSYW2SM9s8wprnis8c2uRPhYxIXuDhwgRLLLDU38,378
|
|
19
|
+
hypern/processpool.py,sha256=mtP6qYSKTUgHOQEqtw6yhBvZ4JMAPw6uLxuyd-96CYI,3908
|
|
19
20
|
hypern/security.py,sha256=dOWdNHA8SoUhlbu6Z2MapOwT9tAhlsierrTBBiEV5-A,1729
|
|
20
|
-
hypern/hypern.pyi,sha256=
|
|
21
|
+
hypern/hypern.pyi,sha256=WlE2tNIY3FnJaUorHKfJ7tY-DZf83XK7bRvzrxauyr4,7405
|
|
21
22
|
hypern/logging/logger.py,sha256=62Qg4YAi_JDGV72Rd6R58jixqZk7anRqHbtnuBlkrwA,3174
|
|
22
23
|
hypern/logging/__init__.py,sha256=lzYSz0382eIM3CvP0sZ6RbEEwYZwfeJEJh9cxQA6Rws,49
|
|
23
24
|
hypern/reload.py,sha256=oRwDyxze69ERiVT41eJI_qpg6eJFDbIszGPVAoS5DHs,2233
|
|
@@ -64,5 +65,5 @@ hypern/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
64
65
|
hypern/datastructures.py,sha256=7Nb_fOxmfO8CT7_v_-RhmXg54IhioXGZSp405IzJLh4,857
|
|
65
66
|
hypern/config.py,sha256=v9KLL6snReAETKiVb8x3KOFrXpYd8-Io5tM7eruR85U,4781
|
|
66
67
|
hypern/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
|
-
hypern/hypern.cpython-310-i386-linux-gnu.so,sha256=
|
|
68
|
-
hypern-0.
|
|
68
|
+
hypern/hypern.cpython-310-i386-linux-gnu.so,sha256=ldctvI0tUTpF_rGKBuEjMrsMNg-6yWwiz0xEQ05WD-M,6496404
|
|
69
|
+
hypern-0.3.0.dist-info/RECORD,,
|
|
File without changes
|