hypern 0.3.2__cp312-cp312-win32.whl → 0.3.4__cp312-cp312-win32.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/exceptions.py CHANGED
@@ -95,3 +95,13 @@ class Unauthorized(BaseException):
95
95
 
96
96
  class InvalidPortNumber(Exception):
97
97
  pass
98
+
99
+
100
+ class OutOfScopeApplicationException(Exception):
101
+ pass
102
+
103
+
104
+ class DBFieldValidationError(ValueError):
105
+ """Custom exception for field validation errors."""
106
+
107
+ pass
Binary file
hypern/hypern.pyi CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
4
  from typing import Any, Callable, Dict, List, Tuple
5
+ from enum import Enum
5
6
 
6
7
  @dataclass
7
8
  class BaseSchemaGenerator:
@@ -188,6 +189,8 @@ class Server:
188
189
  def set_startup_handler(self, on_startup: FunctionInfo) -> None: ...
189
190
  def set_shutdown_handler(self, on_shutdown: FunctionInfo) -> None: ...
190
191
  def set_auto_compression(self, enabled: bool) -> None: ...
192
+ def set_database_config(self, config: DatabaseConfig) -> None: ...
193
+ def set_mem_pool_capacity(self, min_capacity: int, max_capacity: int) -> None: ...
191
194
 
192
195
  class Route:
193
196
  path: str
@@ -303,3 +306,32 @@ class MiddlewareConfig:
303
306
 
304
307
  @staticmethod
305
308
  def default(self) -> MiddlewareConfig: ...
309
+
310
+ class DatabaseType(Enum):
311
+ Postgres: str
312
+ MySQL: str
313
+ SQLite: str
314
+
315
+ @dataclass
316
+ class DatabaseConfig:
317
+ driver: DatabaseType
318
+ url: str
319
+ max_connections: int = 10
320
+ min_connections: int = 1
321
+ idle_timeout: int = 30
322
+
323
+ options: Dict[str, Any] = {}
324
+
325
+ @dataclass
326
+ class DatabaseTransaction:
327
+ def execute(self, query: str, params: List[Any]) -> int: ...
328
+ def fetch_all(self, query: str, params: List[Any]) -> List[Dict[str, Any]]: ...
329
+ def stream_data(self, query: str, params: List[Any], chunk_size: int) -> Dict[str, Any]: ...
330
+ def bulk_change(self, query: str, params: List[List[Any]], batch_size: int) -> int | None: ...
331
+ def commit(self) -> None: ...
332
+ def rollback(self) -> None: ...
333
+ def __del__(self) -> None: ...
334
+ def __enter__(self) -> None: ...
335
+ def __exit__(self, _exc_type, _exc_value, _traceback) -> None: ...
336
+
337
+ def get_session_database(context_id: str) -> DatabaseTransaction: ...
hypern/processpool.py CHANGED
@@ -2,49 +2,33 @@ import asyncio
2
2
  import os
3
3
  import signal
4
4
  import sys
5
- from typing import Any, Dict, List
5
+ from typing import List
6
6
 
7
7
  from multiprocess import Process
8
8
  from watchdog.observers import Observer
9
9
 
10
- from .hypern import FunctionInfo, Router, Server, SocketHeld, WebsocketRouter
10
+ from .hypern import Server, SocketHeld
11
11
  from .logging import logger
12
12
  from .reload import EventHandler
13
13
 
14
14
 
15
15
  def run_processes(
16
+ server: Server,
16
17
  host: str,
17
18
  port: int,
18
19
  workers: int,
19
20
  processes: int,
20
21
  max_blocking_threads: int,
21
- router: Router,
22
- websocket_router: WebsocketRouter,
23
- injectables: Dict[str, Any],
24
- before_request: List[FunctionInfo],
25
- after_request: List[FunctionInfo],
26
- response_headers: Dict[str, str],
27
22
  reload: bool = True,
28
- on_startup: FunctionInfo | None = None,
29
- on_shutdown: FunctionInfo | None = None,
30
- auto_compression: bool = False,
31
23
  ) -> List[Process]:
32
24
  socket = SocketHeld(host, port)
33
25
 
34
26
  process_pool = init_processpool(
35
- router,
36
- websocket_router,
27
+ server,
37
28
  socket,
38
29
  workers,
39
30
  processes,
40
31
  max_blocking_threads,
41
- injectables,
42
- before_request,
43
- after_request,
44
- response_headers,
45
- on_startup,
46
- on_shutdown,
47
- auto_compression,
48
32
  )
49
33
 
50
34
  def terminating_signal_handler(_sig, _frame):
@@ -84,19 +68,11 @@ def run_processes(
84
68
 
85
69
 
86
70
  def init_processpool(
87
- router: Router,
88
- websocket_router: WebsocketRouter,
71
+ server: Server,
89
72
  socket: SocketHeld,
90
73
  workers: int,
91
74
  processes: int,
92
75
  max_blocking_threads: int,
93
- injectables: Dict[str, Any],
94
- before_request: List[FunctionInfo],
95
- after_request: List[FunctionInfo],
96
- response_headers: Dict[str, str],
97
- on_startup: FunctionInfo | None = None,
98
- on_shutdown: FunctionInfo | None = None,
99
- auto_compression: bool = False,
100
76
  ) -> List[Process]:
101
77
  process_pool = []
102
78
 
@@ -105,18 +81,10 @@ def init_processpool(
105
81
  process = Process(
106
82
  target=spawn_process,
107
83
  args=(
108
- router,
109
- websocket_router,
84
+ server,
110
85
  copied_socket,
111
86
  workers,
112
87
  max_blocking_threads,
113
- injectables,
114
- before_request,
115
- after_request,
116
- response_headers,
117
- on_startup,
118
- on_shutdown,
119
- auto_compression,
120
88
  ),
121
89
  )
122
90
  process.start()
@@ -140,37 +108,14 @@ def initialize_event_loop():
140
108
 
141
109
 
142
110
  def spawn_process(
143
- router: Router,
144
- websocket_router: WebsocketRouter,
111
+ server: Server,
145
112
  socket: SocketHeld,
146
113
  workers: int,
147
114
  max_blocking_threads: int,
148
- injectables: Dict[str, Any],
149
- before_request: List[FunctionInfo],
150
- after_request: List[FunctionInfo],
151
- response_headers: Dict[str, str],
152
- on_startup: FunctionInfo | None = None,
153
- on_shutdown: FunctionInfo | None = None,
154
- auto_compression: bool = False,
155
115
  ):
156
116
  loop = initialize_event_loop()
157
117
 
158
- server = Server()
159
- server.set_router(router=router)
160
- server.set_websocket_router(websocket_router=websocket_router)
161
- server.set_injected(injected=injectables)
162
- server.set_before_hooks(hooks=before_request)
163
- server.set_after_hooks(hooks=after_request)
164
- server.set_response_headers(headers=response_headers)
165
- server.set_auto_compression(enabled=auto_compression)
166
-
167
- if on_startup:
168
- server.set_startup_handler(on_startup)
169
- if on_shutdown:
170
- server.set_shutdown_handler(on_shutdown)
171
118
  try:
172
119
  server.start(socket, workers, max_blocking_threads)
173
- loop = asyncio.get_event_loop()
174
- loop.run_forever()
175
120
  except KeyboardInterrupt:
176
121
  loop.close()
@@ -15,6 +15,7 @@ from hypern.hypern import Request, Response
15
15
  from hypern.response import JSONResponse
16
16
 
17
17
  from .parser import InputHandler
18
+ from hypern.config import context_store
18
19
 
19
20
 
20
21
  def is_async_callable(obj: typing.Any) -> bool:
@@ -32,6 +33,9 @@ async def run_in_threadpool(func: typing.Callable, *args, **kwargs):
32
33
 
33
34
  async def dispatch(handler, request: Request, inject: typing.Dict[str, typing.Any]) -> Response:
34
35
  try:
36
+ # set context for global handler
37
+ context_store.set_context(request.context_id)
38
+
35
39
  is_async = is_async_callable(handler)
36
40
  signature = inspect.signature(handler)
37
41
  input_handler = InputHandler(request)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypern
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -23,6 +23,8 @@ Requires-Dist: multiprocess ==0.70.17
23
23
  Requires-Dist: uvloop ==0.21.0 ; sys_platform != 'win32' and platform_python_implementation == 'CPython' and platform_machine != 'armv7l'
24
24
  Requires-Dist: cryptography ==43.0.3
25
25
  Requires-Dist: watchdog ==6.0.0
26
+ Requires-Dist: jsonschema ==4.23.0
27
+ Requires-Dist: psutil ==6.1.0
26
28
  License-File: LICENSE
27
29
  Summary: A Fast Async Python backend with a Rust runtime.
28
30
  Author-email: Martin Dang <vannghiem848@gmail.com>
@@ -1,8 +1,8 @@
1
- hypern-0.3.2.dist-info/METADATA,sha256=xbMB8V67yK1aLvRGbYrsjqoScFdSOZXs97zXg0yVVQ4,3754
2
- hypern-0.3.2.dist-info/WHEEL,sha256=SK_cql1gpDHx6aBV-LOSvGbTt4TUC8AJJOzjOP2tdpI,92
3
- hypern-0.3.2.dist-info/licenses/LICENSE,sha256=qbYKAIJLS6jYg5hYncKE7OtWmqOtpVTvKNkwOa0Iwwg,1328
4
- hypern/application.py,sha256=yNlohWdSG0lpKfuTVX7N9gI3cmXl3IoEvP8WLH-yAiE,16251
5
- hypern/args_parser.py,sha256=diz3Oq1PDNMBlG7ElqK01iokY5w_X3U1Ky1jikPVXRg,2020
1
+ hypern-0.3.4.dist-info/METADATA,sha256=wJ9_iA8bw0-Sc-a3AtzB0aCWhN4iPavHZjQfZgEpats,3819
2
+ hypern-0.3.4.dist-info/WHEEL,sha256=SK_cql1gpDHx6aBV-LOSvGbTt4TUC8AJJOzjOP2tdpI,92
3
+ hypern-0.3.4.dist-info/licenses/LICENSE,sha256=qbYKAIJLS6jYg5hYncKE7OtWmqOtpVTvKNkwOa0Iwwg,1328
4
+ hypern/application.py,sha256=DCYFtU8e8NhQtmfaXbUfOxR2_Y3fEn-pzce9OOs6S4U,18396
5
+ hypern/args_parser.py,sha256=zTfLfBoKBvYWxdPjabTfZsCtYF3La3PT0TD8dfLMeM4,2815
6
6
  hypern/auth/authorization.py,sha256=-NprZsI0np889ZN1fp-MiVFrPoMNzUtatBJaCMtkllM,32
7
7
  hypern/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  hypern/background.py,sha256=xy38nQZSJsYFRXr3-uFJeNW9E1GiXXOC7lSe5pC0eyE,124
@@ -12,8 +12,19 @@ hypern/caching/strategies.py,sha256=qQjqgZLUX7KZjhwPD4SYUaMRewgCgsp6qa1FunK3Y0I,
12
12
  hypern/caching/__init__.py,sha256=ODO7zMm4iFG8wcvrhKmukryG5wOTW0DnzFvNMfF57Cc,352
13
13
  hypern/cli/commands.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  hypern/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- hypern/config.py,sha256=frZSdXBI8GaM0tkw1Rs-XydZ9-XjGLRPj6DL4d51-y4,4930
15
+ hypern/config.py,sha256=Jij9eGg5NgC8Un5Lw5i7ghuEMAfkVctdcoE4RaN5LTE,8157
16
16
  hypern/datastructures.py,sha256=zZGGSP07kPc9KJDf11hX5uYhAyRE-Ck5wezW5QtOVXw,897
17
+ hypern/db/addons/sqlalchemy/fields/color.py,sha256=Jj8q4lkT0ukKyjVyZjBx7fokGrX7AIJpKOGzwsBpfnU,480
18
+ hypern/db/addons/sqlalchemy/fields/daterange.py,sha256=qEfQN9c4jQdzeXNYKgQ4VIJ3Qc0HXHWRouzNF1se-RA,853
19
+ hypern/db/addons/sqlalchemy/fields/datetime.py,sha256=Bp2jMja2lb_b2WnzRnfbjXXTHBgBTyph1ECsItIwvvg,643
20
+ hypern/db/addons/sqlalchemy/fields/encrypted.py,sha256=pXsg4ImPpK-VkLDruKrv2gUtdp2kajQX7xDbRDxa-SI,1930
21
+ hypern/db/addons/sqlalchemy/fields/password.py,sha256=9pypORygWaINj3oiAOBRIOGgpuA0lcjPq4rh1pqJxq0,5789
22
+ hypern/db/addons/sqlalchemy/fields/ts_vector.py,sha256=bQyXYvQ1bAfFpYcS-sFwM7fU6L1lg9_7nGDRGp0CoUo,1361
23
+ hypern/db/addons/sqlalchemy/fields/unicode.py,sha256=rbqyHlsPUqRDWIjYQSRFF3zkHncnwxo0sdlzqUlcrUw,411
24
+ hypern/db/addons/sqlalchemy/fields/__init__.py,sha256=mLN_AvwgpSAbrWZvVHZuO7ff0gk1T_JbVwd5wug5nlw,359
25
+ hypern/db/addons/sqlalchemy/repository.py,sha256=ue6vWOTrnEPyDevlyh3v-7PU6GSfrZHYKrbXVuoS8UA,9516
26
+ hypern/db/addons/sqlalchemy/__init__.py,sha256=FuY78ubEwtifdQTVHhCrscYaAarlp2urgYBc_R77yt0,2766
27
+ hypern/db/addons/__init__.py,sha256=mdW0P0xvnK8htUk02ujvIaeHXl6w53JjrTS4ioNi1Bw,63
17
28
  hypern/db/nosql/addons/color.py,sha256=bAGRuARCAYwZ1nO4jK0lzGYKmavTDtS34BxvrsetF74,446
18
29
  hypern/db/nosql/addons/daterange.py,sha256=hGUSoVFqatNY-TB5wjZTq62iZpHpdsyRJIsHxsj1uDs,1192
19
30
  hypern/db/nosql/addons/encrypted.py,sha256=B0M-uDqvZHVmIZcFdwcuC2MGsv0pGJFQ1lrOg8klR9U,1741
@@ -21,25 +32,19 @@ hypern/db/nosql/addons/password.py,sha256=jfZxvWFm6nV9EWpXq5Mj-jpqnl9QbokZj9WT14
21
32
  hypern/db/nosql/addons/unicode.py,sha256=LaDpLfdoTcJuASPE-8fqOVD05H_uOx8gOdnyDn5Iu0c,268
22
33
  hypern/db/nosql/addons/__init__.py,sha256=WEtPM8sPHilvga7zxwqvINeTkF0hdcfgPcAnHc4MASE,125
23
34
  hypern/db/nosql/__init__.py,sha256=MH9YvlbRlbBCrQVNOdfTaK-hINwJxbJLmxwY9Mei7I8,644
24
- hypern/db/sql/addons/color.py,sha256=Jj8q4lkT0ukKyjVyZjBx7fokGrX7AIJpKOGzwsBpfnU,480
25
- hypern/db/sql/addons/daterange.py,sha256=qEfQN9c4jQdzeXNYKgQ4VIJ3Qc0HXHWRouzNF1se-RA,853
26
- hypern/db/sql/addons/datetime.py,sha256=Bp2jMja2lb_b2WnzRnfbjXXTHBgBTyph1ECsItIwvvg,643
27
- hypern/db/sql/addons/encrypted.py,sha256=pXsg4ImPpK-VkLDruKrv2gUtdp2kajQX7xDbRDxa-SI,1930
28
- hypern/db/sql/addons/password.py,sha256=9pypORygWaINj3oiAOBRIOGgpuA0lcjPq4rh1pqJxq0,5789
29
- hypern/db/sql/addons/ts_vector.py,sha256=bQyXYvQ1bAfFpYcS-sFwM7fU6L1lg9_7nGDRGp0CoUo,1361
30
- hypern/db/sql/addons/unicode.py,sha256=rbqyHlsPUqRDWIjYQSRFF3zkHncnwxo0sdlzqUlcrUw,411
31
- hypern/db/sql/addons/__init__.py,sha256=mLN_AvwgpSAbrWZvVHZuO7ff0gk1T_JbVwd5wug5nlw,359
32
- hypern/db/sql/repository.py,sha256=ue6vWOTrnEPyDevlyh3v-7PU6GSfrZHYKrbXVuoS8UA,9516
33
- hypern/db/sql/__init__.py,sha256=1UoWQi2CIcUAbQj3FadR-8V0o_b286nI2wYvOsvtbFc,6478
35
+ hypern/db/sql/field.py,sha256=tSs8iaYjy-K6nplJJ-1X4OQddzW76cfBlx9xTrG_NbQ,20073
36
+ hypern/db/sql/model.py,sha256=BLRmOlmfn6ibedR9Bv_rHErSruudJ24B9-nDbRHqWm4,3913
37
+ hypern/db/sql/query.py,sha256=MXiphm4pXBz6Axbdoc5rg11XEmw_UahTCdppowyXJxY,33329
38
+ hypern/db/sql/__init__.py,sha256=lCOGNTHaXNSJbuLLIOe2IWWNmX0MFQFPNCl2yytD2Xs,261
34
39
  hypern/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
40
  hypern/enum.py,sha256=KcVziJj7vWvyie0r2rtxhrLzdtkZAsf0DY58oJ4tQl4,360
36
- hypern/exceptions.py,sha256=nHTkF0YdNBMKfSiNtjRMHMNKoY3RMUm68YYluuW15us,2428
41
+ hypern/exceptions.py,sha256=rWQpWjnkLY51HBpKcWkFaVGCKoC_EiFUPrIBBfLh-eA,2608
37
42
  hypern/gateway/aggregator.py,sha256=N1onAp9gdzpCR-E5VubkVoUjjEmVNxG8gDZx9rhnbXc,1132
38
43
  hypern/gateway/gateway.py,sha256=26K2qvJUR-0JnN4IlhwvSSt7EYcpYrBVDuzZ1ivQQ34,1475
39
44
  hypern/gateway/proxy.py,sha256=w1wcTplDnVrfjn7hb0M0yBVth5TGl88irF-MUYHysQQ,2463
40
45
  hypern/gateway/service.py,sha256=PkRaM08olqM_j_4wRjEJCR8X8ZysAF2WOcfhWjaX2eo,1701
41
46
  hypern/gateway/__init__.py,sha256=TpFWtqnJerW1-jCWq5fjypJcw9Y6ytyrkvkzby1Eg0E,235
42
- hypern/hypern.pyi,sha256=GiUjtY6tbV8d6KI1PDTTZK5zWyOD4hooahALnFd7Fl4,8197
47
+ hypern/hypern.pyi,sha256=yXaWGPt598gwPN-CT1ARDdwOSqryZCBFuDLQC8gRd1U,9345
43
48
  hypern/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
49
  hypern/logging/logger.py,sha256=WACam_IJiCMXX0hGVKMGSxUQpY4DgAXy7M1dD3q-Z9s,3256
45
50
  hypern/logging/__init__.py,sha256=6eVriyncsJ4J73fGYhoejv9MX7aGTkRezTpPxO4DX1I,52
@@ -54,12 +59,12 @@ hypern/middleware/__init__.py,sha256=V-Gnv-Jf-14BVuA28z7PN7GBVQ9BBiBdab6-QnTPCfY
54
59
  hypern/openapi/schemas.py,sha256=YHfMlPUeP5DzDX5ao3YH8p_25Vvyaf616dh6XDCUZRc,1677
55
60
  hypern/openapi/swagger.py,sha256=naqUY3rFAEYA1ZLIlmDsMYaol0yIm6TVebdkFa5cMTc,64
56
61
  hypern/openapi/__init__.py,sha256=4rEVD8pa0kdSpsy7ZkJ5JY0Z2XF0NGSKDMwYAd7YZpE,141
57
- hypern/processpool.py,sha256=l6_PKRMFQ4GIMPLTMOEbIwWDsxER0NIj_wdxVWqA7zA,5042
62
+ hypern/processpool.py,sha256=RFV4turo1dBv40NlzzosjwaZLC24igdyq6twY2IXCUE,2968
58
63
  hypern/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
64
  hypern/reload.py,sha256=nfaZCoChrQetHNtIqN4Xzi-a0v-irxSCMhwCK3bCEq0,1569
60
65
  hypern/response/response.py,sha256=-dnboAraPic8asf503PxwmDuxhNllUO5h97_DGmbER4,4582
61
66
  hypern/response/__init__.py,sha256=_w3u3TDNuYx5ejnnN1unqnTY8NlBgUATQi6wepEB_FQ,226
62
- hypern/routing/dispatcher.py,sha256=i2wLAAW1ZXgpi5K2heGXhTODnP1WdQzaR5WlUjs1o9c,2368
67
+ hypern/routing/dispatcher.py,sha256=oQsbOTkjE5roFCl6k58oCW9lEGR_sY5tBoXSJIDgh0w,2508
63
68
  hypern/routing/endpoint.py,sha256=RKVhvqOEGL9IKBXQ3KJgPi9bgJj9gfWC5BdZc5U_atc,1026
64
69
  hypern/routing/parser.py,sha256=R-4lcN9Ha1iMeAjlqDe8HwkjjMVG-c-ubQLZyWKXj6M,3554
65
70
  hypern/routing/queue.py,sha256=NtFBbogU22ddyyX-CuQMip1XFDPZdMCVMIeUCQ-CR6Y,7176
@@ -75,5 +80,5 @@ hypern/ws/route.py,sha256=fGQ2RC708MPOiiIHPUo8aZ-oK379TTAyQYm4htNA5jM,803
75
80
  hypern/ws/__init__.py,sha256=dhRoRY683_rfPfSPM5qUczfTuyYDeuLOCFxY4hIdKt8,131
76
81
  hypern/ws.py,sha256=F6SA2Z1KVnqTEX8ssvOXqCtudUS4eo30JsiIsvfbHnE,394
77
82
  hypern/__init__.py,sha256=9Ww_aUQ0vJls0tOq7Yw1_TVOCRsa5bHJ-RtnSeComwk,119
78
- hypern/hypern.cp312-win32.pyd,sha256=JxNOpTLC3EaBfc6d3TLY05BbTHHx5ciyj3wSbOKbWIM,6539264
79
- hypern-0.3.2.dist-info/RECORD,,
83
+ hypern/hypern.cp312-win32.pyd,sha256=jJffm7oIt2JsiZrH3M4faieg-Ezb-WoWOH_4ZMt3sog,9813504
84
+ hypern-0.3.4.dist-info/RECORD,,
File without changes
File without changes