hypern 0.3.11__cp310-cp310-musllinux_1_2_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/__init__.py +24 -0
- hypern/application.py +495 -0
- hypern/args_parser.py +73 -0
- hypern/auth/__init__.py +0 -0
- hypern/auth/authorization.py +2 -0
- hypern/background.py +4 -0
- hypern/caching/__init__.py +6 -0
- hypern/caching/backend.py +31 -0
- hypern/caching/redis_backend.py +201 -0
- hypern/caching/strategies.py +208 -0
- hypern/cli/__init__.py +0 -0
- hypern/cli/commands.py +0 -0
- hypern/config.py +246 -0
- hypern/database/__init__.py +0 -0
- hypern/database/sqlalchemy/__init__.py +4 -0
- hypern/database/sqlalchemy/config.py +66 -0
- hypern/database/sqlalchemy/repository.py +290 -0
- hypern/database/sqlx/__init__.py +36 -0
- hypern/database/sqlx/field.py +246 -0
- hypern/database/sqlx/migrate.py +263 -0
- hypern/database/sqlx/model.py +117 -0
- hypern/database/sqlx/query.py +904 -0
- hypern/datastructures.py +40 -0
- hypern/enum.py +13 -0
- hypern/exceptions/__init__.py +34 -0
- hypern/exceptions/base.py +62 -0
- hypern/exceptions/common.py +12 -0
- hypern/exceptions/errors.py +15 -0
- hypern/exceptions/formatters.py +56 -0
- hypern/exceptions/http.py +76 -0
- hypern/gateway/__init__.py +6 -0
- hypern/gateway/aggregator.py +32 -0
- hypern/gateway/gateway.py +41 -0
- hypern/gateway/proxy.py +60 -0
- hypern/gateway/service.py +52 -0
- hypern/hypern.cpython-310-i386-linux-gnu.so +0 -0
- hypern/hypern.pyi +333 -0
- hypern/i18n/__init__.py +0 -0
- hypern/logging/__init__.py +3 -0
- hypern/logging/logger.py +82 -0
- hypern/middleware/__init__.py +17 -0
- hypern/middleware/base.py +13 -0
- hypern/middleware/cache.py +177 -0
- hypern/middleware/compress.py +78 -0
- hypern/middleware/cors.py +41 -0
- hypern/middleware/i18n.py +1 -0
- hypern/middleware/limit.py +177 -0
- hypern/middleware/security.py +184 -0
- hypern/openapi/__init__.py +5 -0
- hypern/openapi/schemas.py +51 -0
- hypern/openapi/swagger.py +3 -0
- hypern/processpool.py +139 -0
- hypern/py.typed +0 -0
- hypern/reload.py +46 -0
- hypern/response/__init__.py +3 -0
- hypern/response/response.py +142 -0
- hypern/routing/__init__.py +5 -0
- hypern/routing/dispatcher.py +70 -0
- hypern/routing/endpoint.py +30 -0
- hypern/routing/parser.py +98 -0
- hypern/routing/queue.py +175 -0
- hypern/routing/route.py +280 -0
- hypern/scheduler.py +5 -0
- hypern/worker.py +274 -0
- hypern/ws/__init__.py +4 -0
- hypern/ws/channel.py +80 -0
- hypern/ws/heartbeat.py +74 -0
- hypern/ws/room.py +76 -0
- hypern/ws/route.py +26 -0
- hypern-0.3.11.dist-info/METADATA +134 -0
- hypern-0.3.11.dist-info/RECORD +74 -0
- hypern-0.3.11.dist-info/WHEEL +4 -0
- hypern-0.3.11.dist-info/licenses/LICENSE +24 -0
- hypern.libs/libgcc_s-b5472b99.so.1 +0 -0
hypern/ws/heartbeat.py
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
import asyncio
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from time import time
|
4
|
+
from typing import Dict
|
5
|
+
|
6
|
+
from hypern.hypern import WebSocketSession
|
7
|
+
|
8
|
+
|
9
|
+
@dataclass
|
10
|
+
class HeartbeatConfig:
|
11
|
+
ping_interval: float = 30.0 # Send ping every 30 seconds
|
12
|
+
ping_timeout: float = 10.0 # Wait 10 seconds for pong response
|
13
|
+
max_missed_pings: int = 2 # Disconnect after 2 missed pings
|
14
|
+
|
15
|
+
|
16
|
+
class HeartbeatManager:
|
17
|
+
def __init__(self, config: HeartbeatConfig = None):
|
18
|
+
self.config = config or HeartbeatConfig()
|
19
|
+
self.active_sessions: Dict[WebSocketSession, float] = {}
|
20
|
+
self.ping_tasks: Dict[WebSocketSession, asyncio.Task] = {}
|
21
|
+
self.missed_pings: Dict[WebSocketSession, int] = {}
|
22
|
+
|
23
|
+
async def start_heartbeat(self, session: WebSocketSession):
|
24
|
+
"""Start heartbeat monitoring for a session"""
|
25
|
+
self.active_sessions[session] = time()
|
26
|
+
self.missed_pings[session] = 0
|
27
|
+
self.ping_tasks[session] = asyncio.create_task(self._heartbeat_loop(session))
|
28
|
+
|
29
|
+
async def stop_heartbeat(self, session: WebSocketSession):
|
30
|
+
"""Stop heartbeat monitoring for a session"""
|
31
|
+
if session in self.ping_tasks:
|
32
|
+
self.ping_tasks[session].cancel()
|
33
|
+
del self.ping_tasks[session]
|
34
|
+
self.active_sessions.pop(session, None)
|
35
|
+
self.missed_pings.pop(session, None)
|
36
|
+
|
37
|
+
async def handle_pong(self, session: WebSocketSession):
|
38
|
+
"""Handle pong response from client"""
|
39
|
+
if session in self.active_sessions:
|
40
|
+
self.active_sessions[session] = time()
|
41
|
+
self.missed_pings[session] = 0
|
42
|
+
|
43
|
+
async def _heartbeat_loop(self, session: WebSocketSession):
|
44
|
+
"""Main heartbeat loop for a session"""
|
45
|
+
try:
|
46
|
+
while True:
|
47
|
+
await asyncio.sleep(self.config.ping_interval)
|
48
|
+
|
49
|
+
if session not in self.active_sessions:
|
50
|
+
break
|
51
|
+
|
52
|
+
# Send ping frame
|
53
|
+
try:
|
54
|
+
await session.ping()
|
55
|
+
last_pong = self.active_sessions[session]
|
56
|
+
|
57
|
+
# Wait for pong timeout
|
58
|
+
await asyncio.sleep(self.config.ping_timeout)
|
59
|
+
|
60
|
+
# Check if we received a pong
|
61
|
+
if self.active_sessions[session] == last_pong:
|
62
|
+
self.missed_pings[session] += 1
|
63
|
+
|
64
|
+
# Check if we exceeded max missed pings
|
65
|
+
if self.missed_pings[session] >= self.config.max_missed_pings:
|
66
|
+
await session.close(1001, "Connection timeout")
|
67
|
+
break
|
68
|
+
|
69
|
+
except Exception as e:
|
70
|
+
await session.close(1001, f"Heartbeat failed: {str(e)}")
|
71
|
+
break
|
72
|
+
|
73
|
+
finally:
|
74
|
+
await self.stop_heartbeat(session)
|
hypern/ws/room.py
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from typing import Dict, Set
|
3
|
+
|
4
|
+
from hypern.hypern import WebSocketSession
|
5
|
+
|
6
|
+
|
7
|
+
@dataclass
|
8
|
+
class Room:
|
9
|
+
name: str
|
10
|
+
clients: Set[WebSocketSession] = field(default_factory=set)
|
11
|
+
|
12
|
+
def broadcast(self, message: str, exclude: WebSocketSession = None):
|
13
|
+
"""Broadcast message to all clients in the room except excluded one"""
|
14
|
+
for client in self.clients:
|
15
|
+
if client != exclude:
|
16
|
+
client.send(message)
|
17
|
+
|
18
|
+
def add_client(self, client: WebSocketSession):
|
19
|
+
"""Add a client to the room"""
|
20
|
+
self.clients.add(client)
|
21
|
+
|
22
|
+
def remove_client(self, client: WebSocketSession):
|
23
|
+
"""Remove a client from the room"""
|
24
|
+
self.clients.discard(client)
|
25
|
+
|
26
|
+
@property
|
27
|
+
def client_count(self) -> int:
|
28
|
+
return len(self.clients)
|
29
|
+
|
30
|
+
|
31
|
+
class RoomManager:
|
32
|
+
def __init__(self):
|
33
|
+
self.rooms: Dict[str, Room] = {}
|
34
|
+
self.client_rooms: Dict[WebSocketSession, Set[str]] = {}
|
35
|
+
|
36
|
+
def create_room(self, room_name: str) -> Room:
|
37
|
+
"""Create a new room if it doesn't exist"""
|
38
|
+
if room_name not in self.rooms:
|
39
|
+
self.rooms[room_name] = Room(room_name)
|
40
|
+
return self.rooms[room_name]
|
41
|
+
|
42
|
+
def get_room(self, room_name: str) -> Room:
|
43
|
+
"""Get a room by name"""
|
44
|
+
return self.rooms.get(room_name)
|
45
|
+
|
46
|
+
def join_room(self, client: WebSocketSession, room_name: str):
|
47
|
+
"""Add a client to a room"""
|
48
|
+
room = self.create_room(room_name)
|
49
|
+
room.add_client(client)
|
50
|
+
|
51
|
+
if client not in self.client_rooms:
|
52
|
+
self.client_rooms[client] = set()
|
53
|
+
self.client_rooms[client].add(room_name)
|
54
|
+
|
55
|
+
room.broadcast(f"Client joined room: {room_name}", exclude=client)
|
56
|
+
|
57
|
+
def leave_room(self, client: WebSocketSession, room_name: str):
|
58
|
+
"""Remove a client from a room"""
|
59
|
+
room = self.get_room(room_name)
|
60
|
+
if room:
|
61
|
+
room.remove_client(client)
|
62
|
+
if client in self.client_rooms:
|
63
|
+
self.client_rooms[client].discard(room_name)
|
64
|
+
|
65
|
+
room.broadcast(f"Client left room: {room_name}", exclude=client)
|
66
|
+
|
67
|
+
if room.client_count == 0:
|
68
|
+
del self.rooms[room_name]
|
69
|
+
|
70
|
+
def leave_all_rooms(self, client: WebSocketSession):
|
71
|
+
"""Remove a client from all rooms"""
|
72
|
+
if client in self.client_rooms:
|
73
|
+
rooms = self.client_rooms[client].copy()
|
74
|
+
for room_name in rooms:
|
75
|
+
self.leave_room(client, room_name)
|
76
|
+
del self.client_rooms[client]
|
hypern/ws/route.py
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
from typing import Callable, Optional
|
2
|
+
|
3
|
+
from hypern.hypern import WebsocketRoute as WebsocketRouteInternal, WebSocketSession
|
4
|
+
|
5
|
+
|
6
|
+
class WebsocketRoute:
|
7
|
+
def __init__(self) -> None:
|
8
|
+
self.routes = []
|
9
|
+
self._disconnect_handler: Optional[Callable] = None
|
10
|
+
|
11
|
+
def on(self, path):
|
12
|
+
def wrapper(func):
|
13
|
+
self.routes.append(WebsocketRouteInternal(path, func))
|
14
|
+
return func
|
15
|
+
|
16
|
+
return wrapper
|
17
|
+
|
18
|
+
def on_disconnect(self, func):
|
19
|
+
"""Register a disconnect handler"""
|
20
|
+
self._disconnect_handler = func
|
21
|
+
return func
|
22
|
+
|
23
|
+
def handle_disconnect(self, session: WebSocketSession):
|
24
|
+
"""Internal method to handle disconnection"""
|
25
|
+
if self._disconnect_handler:
|
26
|
+
return self._disconnect_handler(session)
|
@@ -0,0 +1,134 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: hypern
|
3
|
+
Version: 0.3.11
|
4
|
+
Classifier: Programming Language :: Rust
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
6
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
7
|
+
Requires-Dist: sqlalchemy[asyncio] ==2.0.31
|
8
|
+
Requires-Dist: pyjwt ==2.8.0
|
9
|
+
Requires-Dist: pydash ==8.0.3
|
10
|
+
Requires-Dist: sentry-sdk ==2.11.0
|
11
|
+
Requires-Dist: celery ==5.4.0
|
12
|
+
Requires-Dist: psycopg ==3.2.3
|
13
|
+
Requires-Dist: pyyaml ==6.0.2
|
14
|
+
Requires-Dist: orjson ==3.10.11
|
15
|
+
Requires-Dist: multiprocess ==0.70.17
|
16
|
+
Requires-Dist: uvloop ==0.21.0 ; sys_platform != 'win32' and platform_python_implementation == 'CPython' and platform_machine != 'armv7l'
|
17
|
+
Requires-Dist: watchdog ==6.0.0
|
18
|
+
Requires-Dist: psutil ==6.1.0
|
19
|
+
Requires-Dist: msgpack ==1.1.0
|
20
|
+
Requires-Dist: redis ==5.2.1
|
21
|
+
Requires-Dist: pydantic ==2.10.4
|
22
|
+
License-File: LICENSE
|
23
|
+
Summary: A Fast Async Python backend with a Rust runtime.
|
24
|
+
Author-email: Martin Dang <vannghiem848@gmail.com>
|
25
|
+
Requires-Python: >=3.10
|
26
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
27
|
+
|
28
|
+
|
29
|
+
# Hypern
|
30
|
+
|
31
|
+
Hypern: A Versatile Python and Rust Framework
|
32
|
+
|
33
|
+
Hypern is a flexible, open-source framework built on the [Rust](https://github.com/rust-lang/rust), designed to jumpstart your high-performance web development endeavors. By providing a pre-configured structure and essential components, Hypern empowers you to rapidly develop custom web applications that leverage the combined power of Python and Rust.
|
34
|
+
|
35
|
+
With Hypern, you can seamlessly integrate asynchronous features and build scalable solutions for RESTful APIs and dynamic web applications. Its intuitive design and robust tooling allow developers to focus on creating high-quality code while maximizing performance. Embrace the synergy of Python and Rust to elevate your web development experience.
|
36
|
+
|
37
|
+
|
38
|
+
### 🏁 Get started
|
39
|
+
|
40
|
+
### ⚙️ To Develop Locally
|
41
|
+
|
42
|
+
- Setup a virtual environment:
|
43
|
+
```
|
44
|
+
python3 -m venv venv
|
45
|
+
source venv/bin/activate
|
46
|
+
```
|
47
|
+
- Install required packages
|
48
|
+
|
49
|
+
```
|
50
|
+
pip install pre-commit poetry maturin
|
51
|
+
```
|
52
|
+
- Install development dependencies
|
53
|
+
```
|
54
|
+
poetry install --with dev --with test
|
55
|
+
```
|
56
|
+
- Install pre-commit git hooks
|
57
|
+
```
|
58
|
+
pre-commit install
|
59
|
+
```
|
60
|
+
- Build & install Rust package
|
61
|
+
```
|
62
|
+
maturin develop
|
63
|
+
```
|
64
|
+
|
65
|
+
## 🤔 Usage
|
66
|
+
|
67
|
+
### 🏃 Run your code
|
68
|
+
|
69
|
+
You will then have access to a server on the `localhost:5005`,
|
70
|
+
```python
|
71
|
+
# main.py
|
72
|
+
from hypern import Hypern
|
73
|
+
from hypern.routing import Route, HTTPEndpoint
|
74
|
+
|
75
|
+
class MyEndpoint(HTTPEndpoint):
|
76
|
+
|
77
|
+
async def get(self, request):
|
78
|
+
return {"data": "Hello World"}
|
79
|
+
|
80
|
+
routing = [
|
81
|
+
Route("/hello", MyEndpoint)
|
82
|
+
]
|
83
|
+
|
84
|
+
app = Hypern(routing)
|
85
|
+
|
86
|
+
if __name__ == "__main__":
|
87
|
+
app.start()
|
88
|
+
```
|
89
|
+
|
90
|
+
```
|
91
|
+
$ python3 main.py
|
92
|
+
```
|
93
|
+
You can open swagger UI at path `/docs`
|
94
|
+
|
95
|
+
## CLI
|
96
|
+
|
97
|
+
- host (str): The host address to bind to. Defaults to '127.0.0.1'.
|
98
|
+
- port (int): The port number to bind to. Defaults to 5000.
|
99
|
+
- processes (int): The number of processes to use. Defaults to 1.
|
100
|
+
- workers (int): The number of worker threads to use. Defaults to 1.
|
101
|
+
- max_blocking_threads (int): The maximum number of blocking threads. Defaults to 32.
|
102
|
+
- reload (bool): If True, the server will restart on file changes.
|
103
|
+
- auto_workers (bool): If True, sets the number of workers and max-blocking-threads automatically.
|
104
|
+
|
105
|
+
|
106
|
+
## 💡 Features
|
107
|
+
|
108
|
+
### ⚡ High Performance
|
109
|
+
- Rust-powered core with Python flexibility
|
110
|
+
- Multi-process architecture for optimal CPU utilization
|
111
|
+
- Async/await support for non-blocking operations
|
112
|
+
- Built on top of production-ready Rust language
|
113
|
+
|
114
|
+
### 🛠 Development Experience
|
115
|
+
- Type hints and IDE support
|
116
|
+
- Built-in Swagger/OpenAPI documentation
|
117
|
+
- Hot reload during development
|
118
|
+
- Comprehensive error handling and logging
|
119
|
+
|
120
|
+
### 🔌 Integration & Extensions
|
121
|
+
- Easy dependency injection
|
122
|
+
- Middleware support (before/after request hooks)
|
123
|
+
- WebSocket support
|
124
|
+
- Background task scheduling
|
125
|
+
- File upload handling
|
126
|
+
|
127
|
+
### 🔒 Security
|
128
|
+
- Built-in authentication/authorization (Comming soon)
|
129
|
+
- CORS configuration
|
130
|
+
- Rate limiting
|
131
|
+
- Request validation
|
132
|
+
|
133
|
+
|
134
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
hypern-0.3.11.dist-info/METADATA,sha256=ITw8gsjB2mG8_N0MV--ZF2Fi2pVeFCzAZBGCR0cK80o,4007
|
2
|
+
hypern-0.3.11.dist-info/WHEEL,sha256=USqslp_LkvPrjvikII3R4Uv8zm_gZxn3yIFSuCKczGI,105
|
3
|
+
hypern-0.3.11.dist-info/licenses/LICENSE,sha256=VdbaK2hSaaD-LUjtDIlEbeZVmvLGK7BEQvltP3mv-cY,1304
|
4
|
+
hypern.libs/libgcc_s-b5472b99.so.1,sha256=wh8CpjXz9IccAyeERcB7YDEx7NH2jF-PykwOyYNeRRI,453841
|
5
|
+
hypern/args_parser.py,sha256=hRlZe6VOZUutynVPXzCS8Mpn_Qp36MDDV0hFLNjM5YM,2149
|
6
|
+
hypern/gateway/aggregator.py,sha256=Z4LnsDlVDtlPlhsSKu8jCD0UsbztXOLu6UAVtkgJwQk,1100
|
7
|
+
hypern/gateway/gateway.py,sha256=rAZrS9db55tQGUfEfVNIKw6EetBdHAcSXyrC7rLfCZ8,1434
|
8
|
+
hypern/gateway/service.py,sha256=kxKTBZN0ZjuNEp8uwFldQWql-g1q1AECXUjKZsICdLg,1649
|
9
|
+
hypern/gateway/__init__.py,sha256=4wyCK49W_sTBCh0hkTdEli6kdRUFu9UBxncV6EXBxwA,229
|
10
|
+
hypern/gateway/proxy.py,sha256=cgMFJ6znUMWRDgPgnRz7HmPT6UUY6Z09-8HAxkCWGgk,2403
|
11
|
+
hypern/auth/authorization.py,sha256=b8N_MiBmSJBVR45SsOI2iMGmXYOlNKbsMsrMwXApxtk,30
|
12
|
+
hypern/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
hypern/middleware/limit.py,sha256=oWNt-XqYdORJuJMgg8pLYoEpHVm1cZBOPatxk8g7Nao,8075
|
14
|
+
hypern/middleware/__init__.py,sha256=sPmefKAy8-XeSg6BhkZBjqV8zgreeNLxikyyM6aDFT8,476
|
15
|
+
hypern/middleware/base.py,sha256=IXmEe7x_X5YykBsxTpko6ApsvNmVqfZ7IHBgJSSEWnY,356
|
16
|
+
hypern/middleware/compress.py,sha256=2eyxkYMgmsL6klbcTqr7WK0rFTo0grU0ZKQF15pVUBI,3041
|
17
|
+
hypern/middleware/cache.py,sha256=b4hRh1smFwhJE789hZ0p4TlkQ8ZjYR-7fXg9rI7uvbc,7406
|
18
|
+
hypern/middleware/i18n.py,sha256=s82nQo6kKClZ0s3G3jsy87VRfwxpBDbASB_ErjRL3O0,15
|
19
|
+
hypern/middleware/cors.py,sha256=q8Ts_znqApdUJYSJyLlRIbYKxxTQy6WNnJD6Kqbl32I,1759
|
20
|
+
hypern/middleware/security.py,sha256=hPYsilqhF9mRCX7DzOQw4AKh0y5k5FL0cM_zQdb9tiA,7491
|
21
|
+
hypern/openapi/schemas.py,sha256=Hg8G4aPZ1xXJTKFWhx8BgwRsDt2yw-v0N6LVjJ_qBHU,1547
|
22
|
+
hypern/openapi/__init__.py,sha256=oJ0HM9yAgSN00mBC_fRgV2irlGugrhvIpiveuDMv8PM,136
|
23
|
+
hypern/openapi/swagger.py,sha256=E5fHYUfFa77zQsCyQGf_vnqJVpl4_KI5qsKFHdgJEdw,61
|
24
|
+
hypern/hypern.pyi,sha256=GSVs2lNIlIU6k8KL2VNOBO8jafEEqzmsmJF6PHNtwAA,8718
|
25
|
+
hypern/routing/dispatcher.py,sha256=8_JuxyyOMiCqY3WsqcjSzUTpYjIGbvzGtI8j9T-fIkA,2391
|
26
|
+
hypern/routing/route.py,sha256=juK0eOjmTv1iYYhw3zyLt3uHCB3pT6au64tVcXqCEDc,9976
|
27
|
+
hypern/routing/parser.py,sha256=VYdQtf9TPe-NSx3J2wCfOZIh1S-iFLf0jdqrY9UPVMQ,3328
|
28
|
+
hypern/routing/__init__.py,sha256=FvmUQlSraZ91q9AFGkgj3ELIep1jiKZLBCDrXIVf5DI,157
|
29
|
+
hypern/routing/queue.py,sha256=Yus-49N4xc7O5S3YYxqL0muFLypu_Zgd0u2SADFh-Uk,7001
|
30
|
+
hypern/routing/endpoint.py,sha256=AWLHLQNlSGR8IGU6xM0RP-1kP06OJQzqpbXKSiZEzEo,996
|
31
|
+
hypern/response/response.py,sha256=_UbLlzEfDZvXKHDKOdXFdus-CJXgoNFPmV259cjQz2Q,4729
|
32
|
+
hypern/response/__init__.py,sha256=9z99BDgASpG404GK8LGkOsXgac0wFwH_cQOTI5Ju-1U,223
|
33
|
+
hypern/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
|
+
hypern/cli/commands.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
+
hypern/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
+
hypern/datastructures.py,sha256=SqqYX0iwA0U7R42bYerUjL-gjaA4mu-RwrvVT9biELg,842
|
37
|
+
hypern/worker.py,sha256=_m0NV-Srn4NGi65UciOOg3t4Bk6wGm0PMG4_1EYi6Zk,9487
|
38
|
+
hypern/__init__.py,sha256=IxXU3ev_2KFfceMvBlJBgHeF5_YGYoiDotWJOAiYjh4,615
|
39
|
+
hypern/reload.py,sha256=Y2pjHHh8Zv0z-pRkBPLezKiowRblb1ZJ7yI_oE55D4U,1523
|
40
|
+
hypern/background.py,sha256=fN38UlJG6wZf1gOGcvdY-INoD8zJKvGZZOdVYTMjDwg,120
|
41
|
+
hypern/processpool.py,sha256=7DSUMKy0IL6D3822W-XseH6oAU2MCmb-wKRt_80RuZE,3744
|
42
|
+
hypern/caching/__init__.py,sha256=I7X3bmdEHeHs80kjAI1s0mMlVD7RKmw9I-QupaTAIWo,346
|
43
|
+
hypern/caching/backend.py,sha256=Tj66YSepGUvpXrwC04gSdJzs45IepHA2hNlMtnRVB6c,798
|
44
|
+
hypern/caching/redis_backend.py,sha256=nRkAq07B248iFljn9TxE4tadYUeM8RqqERZWzEpfk7E,5767
|
45
|
+
hypern/caching/strategies.py,sha256=VU0FpYmIK6rEjjJSwRXPrprYdo0d2u1s9OxB3OAvs3g,7080
|
46
|
+
hypern/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
+
hypern/config.py,sha256=Ksn2LnHU0yhtGUjnac9bNjqtxl7IcPKmMdbDfZYm7Jo,7911
|
48
|
+
hypern/application.py,sha256=8dnaBB5zn5H-AccPHO38EWPMun1M3eRyxdF6zXFi1mg,17573
|
49
|
+
hypern/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
|
+
hypern/database/sqlx/field.py,sha256=C7vxo6VvCeOWxG3-GFrwe23xC4AiZ3fGqOzZTDbkC8c,8875
|
51
|
+
hypern/database/sqlx/model.py,sha256=5liN9IP6cKZhW2SZqQE5ynFNCPVkGL9_xoyPu5PAyjQ,3927
|
52
|
+
hypern/database/sqlx/__init__.py,sha256=1GJLdJfh1Dgy6o1tyl6Aus431rhrX4shhE53M9FLQl0,609
|
53
|
+
hypern/database/sqlx/query.py,sha256=_SRoXXXdVZ_kRLcvrYCtxmIbpb1GE3BpBg4rseHhctc,32442
|
54
|
+
hypern/database/sqlx/migrate.py,sha256=gHoZFUPop7OGp_cVic8pKiVnnV1-j2oUAJ9lXVfBBAA,9479
|
55
|
+
hypern/database/sqlalchemy/__init__.py,sha256=U_9q6L3V7VIRN-neeN5mVb1z6wKf7_GjWptgUl8-xxI,150
|
56
|
+
hypern/database/sqlalchemy/repository.py,sha256=YShEl1DqRXtYwNnn1F3YVfXX-TEdoNRjDEWIO_3Lu2s,9226
|
57
|
+
hypern/database/sqlalchemy/config.py,sha256=AyeDJnWtq42NFLX65T0w04yhX7l9x8t6lXFq8U4WgfE,2580
|
58
|
+
hypern/enum.py,sha256=-StRU0cWboP-y5fNuhB4Q7yMk8Zm_h1Eua9KzOtIyI8,347
|
59
|
+
hypern/exceptions/common.py,sha256=p9cx3PC6Azn0WAz7jCH02DEoLRLCCvKqNrL-dGhMGSQ,215
|
60
|
+
hypern/exceptions/formatters.py,sha256=51krRQIUq3uvwvcQm81mYPifdp2r2ckwC98pXI5v_P8,2330
|
61
|
+
hypern/exceptions/__init__.py,sha256=t4GhxGHjOPgPQ34f0MycMjoRGw5u3TRb3OcTDYc4Orw,936
|
62
|
+
hypern/exceptions/errors.py,sha256=mt6ZXUGHFZ_FfyP7sZFj4XT6amb5G-1Fa_26rH7BSWc,842
|
63
|
+
hypern/exceptions/http.py,sha256=N98kHaQtH4x9EW6Gavrcr-Ll_-HDvsDSaRAX1sNuN4A,3150
|
64
|
+
hypern/exceptions/base.py,sha256=_tt42Tuy_7oXR-THhJ00lZFsCJMKWbArJyTlF-kcgH4,1955
|
65
|
+
hypern/logging/__init__.py,sha256=lzYSz0382eIM3CvP0sZ6RbEEwYZwfeJEJh9cxQA6Rws,49
|
66
|
+
hypern/logging/logger.py,sha256=62Qg4YAi_JDGV72Rd6R58jixqZk7anRqHbtnuBlkrwA,3174
|
67
|
+
hypern/scheduler.py,sha256=nQoWIYMRmKd30g4XwdB072hWTNHvJlLd9S6rLlTFKS0,62
|
68
|
+
hypern/ws/channel.py,sha256=TWaqowshz3WZRdg7ApBdFtVAlZW0OsVqoOHoFtXaZrk,3103
|
69
|
+
hypern/ws/room.py,sha256=9u6gLq1WY4hn9_yEniavaY0yetFbQzgya_g6VPN-cgg,2522
|
70
|
+
hypern/ws/heartbeat.py,sha256=PIrYWnQn8VxQjfDXDmtMymMl-wN5MQ_Q6oHfAjPWznU,2787
|
71
|
+
hypern/ws/route.py,sha256=8YPTf1fsF46oCyqoXePC3mEbhjNVFDp8rqyWSsBHhBA,777
|
72
|
+
hypern/ws/__init__.py,sha256=iUYERiHxs7HCmHj7CS5iG2XewKAJgW7w8kqxSORu_N8,127
|
73
|
+
hypern/hypern.cpython-310-i386-linux-gnu.so,sha256=uJOMYLiAxodVa3HX_ypNEdB7ZYF6BNS2gI309lrYI88,9674717
|
74
|
+
hypern-0.3.11.dist-info/RECORD,,
|
@@ -0,0 +1,24 @@
|
|
1
|
+
BSD 2-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2024, Dang Van Nghiem
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Binary file
|