robyn 0.76.0__cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- robyn/__init__.py +782 -0
- robyn/__main__.py +4 -0
- robyn/ai.py +308 -0
- robyn/argument_parser.py +129 -0
- robyn/authentication.py +96 -0
- robyn/cli.py +136 -0
- robyn/dependency_injection.py +71 -0
- robyn/env_populator.py +35 -0
- robyn/events.py +6 -0
- robyn/exceptions.py +32 -0
- robyn/jsonify.py +13 -0
- robyn/logger.py +80 -0
- robyn/mcp.py +461 -0
- robyn/openapi.py +448 -0
- robyn/processpool.py +226 -0
- robyn/py.typed +0 -0
- robyn/reloader.py +164 -0
- robyn/responses.py +208 -0
- robyn/robyn.cpython-314-x86_64-linux-gnu.so +0 -0
- robyn/robyn.pyi +562 -0
- robyn/router.py +426 -0
- robyn/scaffold/mongo/Dockerfile +12 -0
- robyn/scaffold/mongo/app.py +43 -0
- robyn/scaffold/mongo/requirements.txt +2 -0
- robyn/scaffold/no-db/Dockerfile +12 -0
- robyn/scaffold/no-db/app.py +12 -0
- robyn/scaffold/no-db/requirements.txt +1 -0
- robyn/scaffold/postgres/Dockerfile +32 -0
- robyn/scaffold/postgres/app.py +31 -0
- robyn/scaffold/postgres/requirements.txt +3 -0
- robyn/scaffold/postgres/supervisord.conf +14 -0
- robyn/scaffold/prisma/Dockerfile +15 -0
- robyn/scaffold/prisma/app.py +32 -0
- robyn/scaffold/prisma/requirements.txt +2 -0
- robyn/scaffold/prisma/schema.prisma +13 -0
- robyn/scaffold/sqlalchemy/Dockerfile +12 -0
- robyn/scaffold/sqlalchemy/__init__.py +0 -0
- robyn/scaffold/sqlalchemy/app.py +13 -0
- robyn/scaffold/sqlalchemy/models.py +21 -0
- robyn/scaffold/sqlalchemy/requirements.txt +2 -0
- robyn/scaffold/sqlite/Dockerfile +12 -0
- robyn/scaffold/sqlite/app.py +22 -0
- robyn/scaffold/sqlite/requirements.txt +1 -0
- robyn/scaffold/sqlmodel/Dockerfile +11 -0
- robyn/scaffold/sqlmodel/app.py +46 -0
- robyn/scaffold/sqlmodel/models.py +10 -0
- robyn/scaffold/sqlmodel/requirements.txt +2 -0
- robyn/status_codes.py +137 -0
- robyn/swagger.html +32 -0
- robyn/templating.py +30 -0
- robyn/types.py +44 -0
- robyn/ws.py +67 -0
- robyn-0.76.0.dist-info/METADATA +303 -0
- robyn-0.76.0.dist-info/RECORD +57 -0
- robyn-0.76.0.dist-info/WHEEL +5 -0
- robyn-0.76.0.dist-info/entry_points.txt +3 -0
- robyn-0.76.0.dist-info/licenses/LICENSE +25 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from sqlalchemy import Boolean, Column, Integer, String, create_engine
|
|
2
|
+
from sqlalchemy.orm import declarative_base, sessionmaker
|
|
3
|
+
|
|
4
|
+
Base = declarative_base()
|
|
5
|
+
|
|
6
|
+
engine = create_engine("sqlite+pysqlite:///:memory:", echo=True)
|
|
7
|
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class User(Base):
|
|
11
|
+
__tablename__ = "users"
|
|
12
|
+
|
|
13
|
+
id = Column(Integer, primary_key=True, index=True)
|
|
14
|
+
username = Column(String, unique=True, index=True)
|
|
15
|
+
hashed_password = Column(String)
|
|
16
|
+
is_active = Column(Boolean, default=True)
|
|
17
|
+
is_superuser = Column(Boolean, default=False)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if __name__ == "__main__":
|
|
21
|
+
Base.metadata.create_all(bind=engine)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import sqlite3
|
|
2
|
+
|
|
3
|
+
from robyn import Robyn
|
|
4
|
+
|
|
5
|
+
app = Robyn(__file__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@app.get("/")
|
|
9
|
+
def index():
|
|
10
|
+
# your db name
|
|
11
|
+
conn = sqlite3.connect("example.db")
|
|
12
|
+
cur = conn.cursor()
|
|
13
|
+
cur.execute("DROP TABLE IF EXISTS test")
|
|
14
|
+
cur.execute("CREATE TABLE test(column_1, column_2)")
|
|
15
|
+
res = cur.execute("SELECT name FROM sqlite_master")
|
|
16
|
+
th = res.fetchone()
|
|
17
|
+
table_name = th[0]
|
|
18
|
+
return f"Hello World! {table_name}"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
app.start(host="0.0.0.0", port=8080)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
robyn
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from models import Hero
|
|
2
|
+
from sqlmodel import Session, SQLModel, create_engine, select
|
|
3
|
+
|
|
4
|
+
from robyn import Robyn
|
|
5
|
+
|
|
6
|
+
app = Robyn(__file__)
|
|
7
|
+
|
|
8
|
+
engine = create_engine("sqlite:///database.db", echo=True)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.get("/")
|
|
12
|
+
def index():
|
|
13
|
+
return "Hello World"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.get("/create")
|
|
17
|
+
def create():
|
|
18
|
+
SQLModel.metadata.create_all(bind=engine)
|
|
19
|
+
return "created tables"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@app.get("/insert")
|
|
23
|
+
def insert():
|
|
24
|
+
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
|
|
25
|
+
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
|
|
26
|
+
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
|
|
27
|
+
|
|
28
|
+
with Session(engine) as session:
|
|
29
|
+
session.add(hero_1)
|
|
30
|
+
session.add(hero_2)
|
|
31
|
+
session.add(hero_3)
|
|
32
|
+
session.commit()
|
|
33
|
+
return "inserted"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@app.get("/select")
|
|
37
|
+
def get_data():
|
|
38
|
+
with Session(engine) as session:
|
|
39
|
+
statement = select(Hero).where(Hero.name == "Spider-Boy")
|
|
40
|
+
hero = session.exec(statement).first()
|
|
41
|
+
return hero
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
# create a configured "Session" class
|
|
46
|
+
app.start(host="0.0.0.0", port=8080)
|
robyn/status_codes.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""
|
|
2
|
+
HTTP codes
|
|
3
|
+
See HTTP Status Code Registry:
|
|
4
|
+
https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
|
5
|
+
|
|
6
|
+
And RFC 2324 - https://tools.ietf.org/html/rfc2324
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__all__ = (
|
|
10
|
+
"HTTP_100_CONTINUE",
|
|
11
|
+
"HTTP_101_SWITCHING_PROTOCOLS",
|
|
12
|
+
"HTTP_102_PROCESSING",
|
|
13
|
+
"HTTP_103_EARLY_HINTS",
|
|
14
|
+
"HTTP_200_OK",
|
|
15
|
+
"HTTP_201_CREATED",
|
|
16
|
+
"HTTP_202_ACCEPTED",
|
|
17
|
+
"HTTP_203_NON_AUTHORITATIVE_INFORMATION",
|
|
18
|
+
"HTTP_204_NO_CONTENT",
|
|
19
|
+
"HTTP_205_RESET_CONTENT",
|
|
20
|
+
"HTTP_206_PARTIAL_CONTENT",
|
|
21
|
+
"HTTP_207_MULTI_STATUS",
|
|
22
|
+
"HTTP_208_ALREADY_REPORTED",
|
|
23
|
+
"HTTP_226_IM_USED",
|
|
24
|
+
"HTTP_300_MULTIPLE_CHOICES",
|
|
25
|
+
"HTTP_301_MOVED_PERMANENTLY",
|
|
26
|
+
"HTTP_302_FOUND",
|
|
27
|
+
"HTTP_303_SEE_OTHER",
|
|
28
|
+
"HTTP_304_NOT_MODIFIED",
|
|
29
|
+
"HTTP_305_USE_PROXY",
|
|
30
|
+
"HTTP_306_RESERVED",
|
|
31
|
+
"HTTP_307_TEMPORARY_REDIRECT",
|
|
32
|
+
"HTTP_308_PERMANENT_REDIRECT",
|
|
33
|
+
"HTTP_400_BAD_REQUEST",
|
|
34
|
+
"HTTP_401_UNAUTHORIZED",
|
|
35
|
+
"HTTP_402_PAYMENT_REQUIRED",
|
|
36
|
+
"HTTP_403_FORBIDDEN",
|
|
37
|
+
"HTTP_404_NOT_FOUND",
|
|
38
|
+
"HTTP_405_METHOD_NOT_ALLOWED",
|
|
39
|
+
"HTTP_406_NOT_ACCEPTABLE",
|
|
40
|
+
"HTTP_407_PROXY_AUTHENTICATION_REQUIRED",
|
|
41
|
+
"HTTP_408_REQUEST_TIMEOUT",
|
|
42
|
+
"HTTP_409_CONFLICT",
|
|
43
|
+
"HTTP_410_GONE",
|
|
44
|
+
"HTTP_411_LENGTH_REQUIRED",
|
|
45
|
+
"HTTP_412_PRECONDITION_FAILED",
|
|
46
|
+
"HTTP_413_REQUEST_ENTITY_TOO_LARGE",
|
|
47
|
+
"HTTP_414_REQUEST_URI_TOO_LONG",
|
|
48
|
+
"HTTP_415_UNSUPPORTED_MEDIA_TYPE",
|
|
49
|
+
"HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE",
|
|
50
|
+
"HTTP_417_EXPECTATION_FAILED",
|
|
51
|
+
"HTTP_418_IM_A_TEAPOT",
|
|
52
|
+
"HTTP_421_MISDIRECTED_REQUEST",
|
|
53
|
+
"HTTP_422_UNPROCESSABLE_ENTITY",
|
|
54
|
+
"HTTP_423_LOCKED",
|
|
55
|
+
"HTTP_424_FAILED_DEPENDENCY",
|
|
56
|
+
"HTTP_425_TOO_EARLY",
|
|
57
|
+
"HTTP_426_UPGRADE_REQUIRED",
|
|
58
|
+
"HTTP_428_PRECONDITION_REQUIRED",
|
|
59
|
+
"HTTP_429_TOO_MANY_REQUESTS",
|
|
60
|
+
"HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE",
|
|
61
|
+
"HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS",
|
|
62
|
+
"HTTP_500_INTERNAL_SERVER_ERROR",
|
|
63
|
+
"HTTP_501_NOT_IMPLEMENTED",
|
|
64
|
+
"HTTP_502_BAD_GATEWAY",
|
|
65
|
+
"HTTP_503_SERVICE_UNAVAILABLE",
|
|
66
|
+
"HTTP_504_GATEWAY_TIMEOUT",
|
|
67
|
+
"HTTP_505_HTTP_VERSION_NOT_SUPPORTED",
|
|
68
|
+
"HTTP_506_VARIANT_ALSO_NEGOTIATES",
|
|
69
|
+
"HTTP_507_INSUFFICIENT_STORAGE",
|
|
70
|
+
"HTTP_508_LOOP_DETECTED",
|
|
71
|
+
"HTTP_510_NOT_EXTENDED",
|
|
72
|
+
"HTTP_511_NETWORK_AUTHENTICATION_REQUIRED",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
HTTP_100_CONTINUE = 100
|
|
76
|
+
HTTP_101_SWITCHING_PROTOCOLS = 101
|
|
77
|
+
HTTP_102_PROCESSING = 102
|
|
78
|
+
HTTP_103_EARLY_HINTS = 103
|
|
79
|
+
HTTP_200_OK = 200
|
|
80
|
+
HTTP_201_CREATED = 201
|
|
81
|
+
HTTP_202_ACCEPTED = 202
|
|
82
|
+
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
|
|
83
|
+
HTTP_204_NO_CONTENT = 204
|
|
84
|
+
HTTP_205_RESET_CONTENT = 205
|
|
85
|
+
HTTP_206_PARTIAL_CONTENT = 206
|
|
86
|
+
HTTP_207_MULTI_STATUS = 207
|
|
87
|
+
HTTP_208_ALREADY_REPORTED = 208
|
|
88
|
+
HTTP_226_IM_USED = 226
|
|
89
|
+
HTTP_300_MULTIPLE_CHOICES = 300
|
|
90
|
+
HTTP_301_MOVED_PERMANENTLY = 301
|
|
91
|
+
HTTP_302_FOUND = 302
|
|
92
|
+
HTTP_303_SEE_OTHER = 303
|
|
93
|
+
HTTP_304_NOT_MODIFIED = 304
|
|
94
|
+
HTTP_305_USE_PROXY = 305
|
|
95
|
+
HTTP_306_RESERVED = 306
|
|
96
|
+
HTTP_307_TEMPORARY_REDIRECT = 307
|
|
97
|
+
HTTP_308_PERMANENT_REDIRECT = 308
|
|
98
|
+
HTTP_400_BAD_REQUEST = 400
|
|
99
|
+
HTTP_401_UNAUTHORIZED = 401
|
|
100
|
+
HTTP_402_PAYMENT_REQUIRED = 402
|
|
101
|
+
HTTP_403_FORBIDDEN = 403
|
|
102
|
+
HTTP_404_NOT_FOUND = 404
|
|
103
|
+
HTTP_405_METHOD_NOT_ALLOWED = 405
|
|
104
|
+
HTTP_406_NOT_ACCEPTABLE = 406
|
|
105
|
+
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
|
|
106
|
+
HTTP_408_REQUEST_TIMEOUT = 408
|
|
107
|
+
HTTP_409_CONFLICT = 409
|
|
108
|
+
HTTP_410_GONE = 410
|
|
109
|
+
HTTP_411_LENGTH_REQUIRED = 411
|
|
110
|
+
HTTP_412_PRECONDITION_FAILED = 412
|
|
111
|
+
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
|
|
112
|
+
HTTP_414_REQUEST_URI_TOO_LONG = 414
|
|
113
|
+
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
|
|
114
|
+
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
|
|
115
|
+
HTTP_417_EXPECTATION_FAILED = 417
|
|
116
|
+
HTTP_418_IM_A_TEAPOT = 418
|
|
117
|
+
HTTP_421_MISDIRECTED_REQUEST = 421
|
|
118
|
+
HTTP_422_UNPROCESSABLE_ENTITY = 422
|
|
119
|
+
HTTP_423_LOCKED = 423
|
|
120
|
+
HTTP_424_FAILED_DEPENDENCY = 424
|
|
121
|
+
HTTP_425_TOO_EARLY = 425
|
|
122
|
+
HTTP_426_UPGRADE_REQUIRED = 426
|
|
123
|
+
HTTP_428_PRECONDITION_REQUIRED = 428
|
|
124
|
+
HTTP_429_TOO_MANY_REQUESTS = 429
|
|
125
|
+
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
|
|
126
|
+
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
|
|
127
|
+
HTTP_500_INTERNAL_SERVER_ERROR = 500
|
|
128
|
+
HTTP_501_NOT_IMPLEMENTED = 501
|
|
129
|
+
HTTP_502_BAD_GATEWAY = 502
|
|
130
|
+
HTTP_503_SERVICE_UNAVAILABLE = 503
|
|
131
|
+
HTTP_504_GATEWAY_TIMEOUT = 504
|
|
132
|
+
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
|
|
133
|
+
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
|
|
134
|
+
HTTP_507_INSUFFICIENT_STORAGE = 507
|
|
135
|
+
HTTP_508_LOOP_DETECTED = 508
|
|
136
|
+
HTTP_510_NOT_EXTENDED = 510
|
|
137
|
+
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511
|
robyn/swagger.html
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Robyn OpenAPI Docs</title>
|
|
5
|
+
<link
|
|
6
|
+
rel="stylesheet"
|
|
7
|
+
type="text/css"
|
|
8
|
+
href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css"
|
|
9
|
+
/>
|
|
10
|
+
<link
|
|
11
|
+
rel="icon"
|
|
12
|
+
type="image/png"
|
|
13
|
+
href="https://user-images.githubusercontent.com/29942790/140995889-5d91dcff-3aa7-4cfb-8a90-2cddf1337dca.png"
|
|
14
|
+
/>
|
|
15
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
16
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-standalone-preset.js"></script>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<div id="swagger-ui"></div>
|
|
20
|
+
<script>
|
|
21
|
+
window.onload = function () {
|
|
22
|
+
SwaggerUIBundle({
|
|
23
|
+
url: "/openapi.json",
|
|
24
|
+
dom_id: "#swagger-ui",
|
|
25
|
+
deepLinking: true,
|
|
26
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
|
|
27
|
+
layout: "StandaloneLayout",
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
</script>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
robyn/templating.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
from jinja2 import Environment, FileSystemLoader
|
|
4
|
+
|
|
5
|
+
from robyn import status_codes
|
|
6
|
+
|
|
7
|
+
from .robyn import Headers, Response
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TemplateInterface(ABC):
|
|
11
|
+
def __init__(self): ...
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
def render_template(self, *args, **kwargs) -> Response: ...
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class JinjaTemplate(TemplateInterface):
|
|
18
|
+
def __init__(self, directory, encoding="utf-8", followlinks=False):
|
|
19
|
+
self.env = Environment(loader=FileSystemLoader(searchpath=directory, encoding=encoding, followlinks=followlinks))
|
|
20
|
+
|
|
21
|
+
def render_template(self, template_name, **kwargs) -> Response:
|
|
22
|
+
rendered_template = self.env.get_template(template_name).render(**kwargs)
|
|
23
|
+
return Response(
|
|
24
|
+
status_code=status_codes.HTTP_200_OK,
|
|
25
|
+
description=rendered_template,
|
|
26
|
+
headers=Headers({"Content-Type": "text/html; charset=utf-8"}),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
__all__ = ["TemplateInterface", "JinjaTemplate"]
|
robyn/types.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Dict, NewType, Optional, TypedDict
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Directory:
|
|
7
|
+
route: str
|
|
8
|
+
directory_path: str
|
|
9
|
+
show_files_listing: bool
|
|
10
|
+
index_file: Optional[str]
|
|
11
|
+
|
|
12
|
+
def as_list(self):
|
|
13
|
+
return [
|
|
14
|
+
self.route,
|
|
15
|
+
self.directory_path,
|
|
16
|
+
self.show_files_listing,
|
|
17
|
+
self.index_file,
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
PathParams = NewType("PathParams", Dict[str, str])
|
|
22
|
+
Method = NewType("Method", str)
|
|
23
|
+
FormData = NewType("FormData", Dict[str, str])
|
|
24
|
+
Files = NewType("Files", Dict[str, bytes])
|
|
25
|
+
IPAddress = NewType("IPAddress", Optional[str])
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class JSONResponse(TypedDict):
|
|
29
|
+
"""
|
|
30
|
+
A type alias for openapi response bodies. This class should be inherited by the response class type definition.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Body:
|
|
37
|
+
"""
|
|
38
|
+
A type alias for openapi request bodies. This class should be inherited by the request body class annotation.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__all__ = ["JSONResponse", "Body"]
|
robyn/ws.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
from typing import TYPE_CHECKING, Callable
|
|
5
|
+
|
|
6
|
+
from robyn.argument_parser import Config
|
|
7
|
+
from robyn.dependency_injection import DependencyMap
|
|
8
|
+
from robyn.robyn import FunctionInfo
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from robyn import Robyn
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
|
|
15
|
+
_logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class WebSocket:
|
|
19
|
+
# should this be websocket router?
|
|
20
|
+
"""This is the python wrapper for the web socket that will be used here."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, robyn_object: "Robyn", endpoint: str, config: Config = Config(), dependencies: DependencyMap = DependencyMap()) -> None:
|
|
23
|
+
self.robyn_object = robyn_object
|
|
24
|
+
self.endpoint = endpoint
|
|
25
|
+
self.methods: dict = {}
|
|
26
|
+
self.config = config
|
|
27
|
+
self.dependencies = dependencies
|
|
28
|
+
|
|
29
|
+
def on(self, type: str) -> Callable[..., None]:
|
|
30
|
+
def inner(handler):
|
|
31
|
+
if type not in ["connect", "close", "message"]:
|
|
32
|
+
raise Exception(f"Socket method {type} does not exist")
|
|
33
|
+
|
|
34
|
+
params = dict(inspect.signature(handler).parameters)
|
|
35
|
+
num_params = len(params)
|
|
36
|
+
is_async = inspect.iscoroutinefunction(handler)
|
|
37
|
+
|
|
38
|
+
injected_dependencies = self.dependencies.get_dependency_map(self)
|
|
39
|
+
|
|
40
|
+
new_injected_dependencies = {}
|
|
41
|
+
for dependency in injected_dependencies:
|
|
42
|
+
if dependency in params:
|
|
43
|
+
new_injected_dependencies[dependency] = injected_dependencies[dependency]
|
|
44
|
+
else:
|
|
45
|
+
_logger.debug(f"Dependency {dependency} is not used in the handler {handler.__name__}")
|
|
46
|
+
|
|
47
|
+
self.methods[type] = FunctionInfo(handler, is_async, num_params, params, kwargs=new_injected_dependencies)
|
|
48
|
+
self.robyn_object.add_web_socket(self.endpoint, self)
|
|
49
|
+
|
|
50
|
+
return inner
|
|
51
|
+
|
|
52
|
+
def inject(self, **kwargs):
|
|
53
|
+
"""
|
|
54
|
+
Injects the dependencies for the route
|
|
55
|
+
|
|
56
|
+
:param kwargs dict: the dependencies to be injected
|
|
57
|
+
"""
|
|
58
|
+
self.dependencies.add_router_dependency(self, **kwargs)
|
|
59
|
+
|
|
60
|
+
def inject_global(self, **kwargs):
|
|
61
|
+
"""
|
|
62
|
+
Injects the dependencies for the global routes
|
|
63
|
+
Ideally, this function should be a global function
|
|
64
|
+
|
|
65
|
+
:param kwargs dict: the dependencies to be injected
|
|
66
|
+
"""
|
|
67
|
+
self.dependencies.add_global_dependency(**kwargs)
|