diff --git a/robyn/__init__.py b/robyn/__init__.py index b723bcdb0..37d45933b 100644 --- a/robyn/__init__.py +++ b/robyn/__init__.py @@ -1,6 +1,5 @@ import asyncio import inspect -import json import logging import os import socket @@ -30,6 +29,7 @@ config = Config() +openapi = OpenAPI() if (compile_path := config.compile_rust_path) is not None: compile_rust_files(compile_path) @@ -43,15 +43,16 @@ def __init__( self, file_object: str, config: Config = Config(), - openapi: OpenAPI = OpenAPI(), + openapi_instance: OpenAPI = OpenAPI(), dependencies: DependencyMap = DependencyMap(), ) -> None: + global openapi directory_path = os.path.dirname(os.path.abspath(file_object)) self.file_path = file_object self.directory_path = directory_path self.config = config - self.openapi = openapi self.dependencies = dependencies + openapi = openapi_instance load_vars(project_root=directory_path) logging.basicConfig(level=self.config.log_level) @@ -74,18 +75,6 @@ def __init__( self.exception_handler: Optional[Callable] = None self.authentication_handler: Optional[AuthenticationHandler] = None - def docs_handler(): - json_handler() - cwd = os.getcwd() - html_file = os.path.join(cwd, "testing_application/swagger.html") - return serve_html(html_file) - - def json_handler(): - return json.dumps(self.openapi.openapi_schema) - - self.add_route(route_type=HttpMethod.GET, endpoint="/openapi.json", handler=json_handler, is_const=False) - self.add_route(route_type=HttpMethod.GET, endpoint="/docs", handler=docs_handler, is_const=False) - def add_route( self, route_type: Union[HttpMethod, str], @@ -224,6 +213,9 @@ def start(self, host: str = "127.0.0.1", port: int = 8080, _check_port: bool = T :param _check_port bool: represents if the port should be checked if it is already in use """ + self.add_route(route_type=HttpMethod.GET, endpoint="/openapi.json", handler=openapi.json_handler, is_const=False) + self.add_route(route_type=HttpMethod.GET, endpoint="/docs", handler=openapi.docs_handler, is_const=False) + host = os.getenv("ROBYN_HOST", host) port = int(os.getenv("ROBYN_PORT", port)) open_browser = bool(os.getenv("ROBYN_BROWSER_OPEN", self.config.open_browser)) @@ -319,7 +311,8 @@ def get( """ def inner(handler): - self.openapi.add_openapi_path_obj("get", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("get", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.GET, endpoint, handler, const, auth_required) @@ -338,7 +331,8 @@ def post( """ def inner(handler): - self.openapi.add_openapi_path_obj("post", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("post", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.POST, endpoint, handler, auth_required=auth_required) @@ -357,7 +351,8 @@ def put( """ def inner(handler): - self.openapi.add_openapi_path_obj("put", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("put", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.PUT, endpoint, handler, auth_required=auth_required) @@ -376,7 +371,8 @@ def delete( """ def inner(handler): - self.openapi.add_openapi_path_obj("delete", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("delete", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.DELETE, endpoint, handler, auth_required=auth_required) @@ -395,7 +391,8 @@ def patch( """ def inner(handler): - self.openapi.add_openapi_path_obj("patch", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("patch", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.PATCH, endpoint, handler, auth_required=auth_required) @@ -414,7 +411,8 @@ def head( """ def inner(handler): - self.openapi.add_openapi_path_obj("head", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("head", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.HEAD, endpoint, handler, auth_required=auth_required) @@ -433,7 +431,8 @@ def options( """ def inner(handler): - self.openapi.add_openapi_path_obj("options", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("options", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.OPTIONS, endpoint, handler, auth_required=auth_required) @@ -452,7 +451,8 @@ def connect( """ def inner(handler): - self.openapi.add_openapi_path_obj("connect", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("connect", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.CONNECT, endpoint, handler, auth_required=auth_required) @@ -471,7 +471,8 @@ def trace( """ def inner(handler): - self.openapi.add_openapi_path_obj("trace", endpoint, inspect.getdoc(handler), openapi_tags) + global openapi + openapi.add_openapi_path_obj("trace", endpoint, inspect.getdoc(handler), openapi_tags) return self.add_route(HttpMethod.TRACE, endpoint, handler, auth_required=auth_required) @@ -507,7 +508,8 @@ def configure_authentication(self, authentication_handler: AuthenticationHandler class SubRouter(Robyn): def __init__(self, file_object: str, prefix: str = "", config: Config = Config()) -> None: - super().__init__(file_object, config) + global openapi + super().__init__(file_object, config, openapi) self.prefix = prefix def __add_prefix(self, endpoint: str): diff --git a/robyn/openapi.py b/robyn/openapi.py index 163a1103d..b27c76271 100644 --- a/robyn/openapi.py +++ b/robyn/openapi.py @@ -1,5 +1,9 @@ +import json +import os from typing import List, Dict, Union, Any +from robyn import serve_html + class OpenAPI: def __init__( @@ -153,6 +157,8 @@ def add_openapi_path_obj(self, route_type, endpoint, openapi_summary, openapi_ta self.openapi_schema["paths"][modified_endpoint] = {} self.openapi_schema["paths"][modified_endpoint][route_type] = path_obj + print(self.openapi_schema) + def get_path_obj(self, endpoint: str, summary: str, tags: list): modified_endpoint = endpoint @@ -187,3 +193,14 @@ def get_path_obj(self, endpoint: str, summary: str, tags: list): } }, } + + def docs_handler(self): + json.dumps(self.openapi_schema) + html_file = os.path.join(os.getcwd(), "robyn/swagger.html") + return serve_html(html_file) + + def json_handler(self): + return json.dumps(self.openapi_schema) + + +openapi = OpenAPI() diff --git a/testing_application/swagger.html b/robyn/swagger.html similarity index 100% rename from testing_application/swagger.html rename to robyn/swagger.html diff --git a/testing_application/app.py b/testing_application/app.py index 757107e5e..58bb5bb5f 100644 --- a/testing_application/app.py +++ b/testing_application/app.py @@ -1,8 +1,8 @@ -from robyn import Robyn, Request, jsonify, OpenAPI +from robyn import Robyn, Request, jsonify, OpenAPI, SubRouter app = Robyn( file_object=__file__, - openapi=OpenAPI( + openapi_instance=OpenAPI( openapi_title="Sample Pet Store App", openapi_summary=" A pet store manager.", openapi_description=" This is a sample server for a pet store.", @@ -43,6 +43,29 @@ async def delete_user(r: Request): return jsonify(r.path_params) +doctor_router = SubRouter(__name__, prefix="/doctor") + + +@doctor_router.get("/") +async def doctor_welcome(): + """hiiii""" + return "doctor_hiiiiii" + + +@doctor_router.get("/users/:name/:age") +async def doctor_get_user(r: Request): + """Get User by ID""" + return {"message": f"doctor_User {r.path_params['name']} : {r.path_params['age']}"} + + +@doctor_router.delete("/users/:name/:age") +async def doctor_delete_user(r: Request): + """Delete User by ID""" + return f"doctor_{jsonify(r.path_params)}" + + +app.include_router(doctor_router) + if __name__ == "__main__": app.start()