hypern 0.3.11__cp312-cp312-musllinux_1_2_armv7l.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.
Files changed (74) hide show
  1. hypern/__init__.py +24 -0
  2. hypern/application.py +495 -0
  3. hypern/args_parser.py +73 -0
  4. hypern/auth/__init__.py +0 -0
  5. hypern/auth/authorization.py +2 -0
  6. hypern/background.py +4 -0
  7. hypern/caching/__init__.py +6 -0
  8. hypern/caching/backend.py +31 -0
  9. hypern/caching/redis_backend.py +201 -0
  10. hypern/caching/strategies.py +208 -0
  11. hypern/cli/__init__.py +0 -0
  12. hypern/cli/commands.py +0 -0
  13. hypern/config.py +246 -0
  14. hypern/database/__init__.py +0 -0
  15. hypern/database/sqlalchemy/__init__.py +4 -0
  16. hypern/database/sqlalchemy/config.py +66 -0
  17. hypern/database/sqlalchemy/repository.py +290 -0
  18. hypern/database/sqlx/__init__.py +36 -0
  19. hypern/database/sqlx/field.py +246 -0
  20. hypern/database/sqlx/migrate.py +263 -0
  21. hypern/database/sqlx/model.py +117 -0
  22. hypern/database/sqlx/query.py +904 -0
  23. hypern/datastructures.py +40 -0
  24. hypern/enum.py +13 -0
  25. hypern/exceptions/__init__.py +34 -0
  26. hypern/exceptions/base.py +62 -0
  27. hypern/exceptions/common.py +12 -0
  28. hypern/exceptions/errors.py +15 -0
  29. hypern/exceptions/formatters.py +56 -0
  30. hypern/exceptions/http.py +76 -0
  31. hypern/gateway/__init__.py +6 -0
  32. hypern/gateway/aggregator.py +32 -0
  33. hypern/gateway/gateway.py +41 -0
  34. hypern/gateway/proxy.py +60 -0
  35. hypern/gateway/service.py +52 -0
  36. hypern/hypern.cpython-312-arm-linux-musleabihf.so +0 -0
  37. hypern/hypern.pyi +333 -0
  38. hypern/i18n/__init__.py +0 -0
  39. hypern/logging/__init__.py +3 -0
  40. hypern/logging/logger.py +82 -0
  41. hypern/middleware/__init__.py +17 -0
  42. hypern/middleware/base.py +13 -0
  43. hypern/middleware/cache.py +177 -0
  44. hypern/middleware/compress.py +78 -0
  45. hypern/middleware/cors.py +41 -0
  46. hypern/middleware/i18n.py +1 -0
  47. hypern/middleware/limit.py +177 -0
  48. hypern/middleware/security.py +184 -0
  49. hypern/openapi/__init__.py +5 -0
  50. hypern/openapi/schemas.py +51 -0
  51. hypern/openapi/swagger.py +3 -0
  52. hypern/processpool.py +139 -0
  53. hypern/py.typed +0 -0
  54. hypern/reload.py +46 -0
  55. hypern/response/__init__.py +3 -0
  56. hypern/response/response.py +142 -0
  57. hypern/routing/__init__.py +5 -0
  58. hypern/routing/dispatcher.py +70 -0
  59. hypern/routing/endpoint.py +30 -0
  60. hypern/routing/parser.py +98 -0
  61. hypern/routing/queue.py +175 -0
  62. hypern/routing/route.py +280 -0
  63. hypern/scheduler.py +5 -0
  64. hypern/worker.py +274 -0
  65. hypern/ws/__init__.py +4 -0
  66. hypern/ws/channel.py +80 -0
  67. hypern/ws/heartbeat.py +74 -0
  68. hypern/ws/room.py +76 -0
  69. hypern/ws/route.py +26 -0
  70. hypern-0.3.11.dist-info/METADATA +134 -0
  71. hypern-0.3.11.dist-info/RECORD +74 -0
  72. hypern-0.3.11.dist-info/WHEEL +4 -0
  73. hypern-0.3.11.dist-info/licenses/LICENSE +24 -0
  74. hypern.libs/libgcc_s-5b5488a6.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=ZpVFxu0p_HmuO1LnhwVR1IZeNyd7_l7MNT8RKZkkpkk,107
3
+ hypern-0.3.11.dist-info/licenses/LICENSE,sha256=VdbaK2hSaaD-LUjtDIlEbeZVmvLGK7BEQvltP3mv-cY,1304
4
+ hypern.libs/libgcc_s-5b5488a6.so.1,sha256=HGKUsVmTeNAxEdSy7Ua5Vh_I9FN3RCbPWzvZ7H_TrwE,2749061
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-312-arm-linux-musleabihf.so,sha256=bTB2Da5txb67o96fDDRdFgudGlyv-hyFGczu5d38TGw,9244653
74
+ hypern-0.3.11.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.8.1)
3
+ Root-Is-Purelib: false
4
+ Tag: cp312-cp312-musllinux_1_2_armv7l
@@ -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