Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs_src/public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Main application class and sub-router for modular routes.
from robyn import Robyn, SubRouter

app = Robyn(__file__)
api = SubRouter(__file__, prefix="/api")
api = SubRouter(prefix="/api")

@api.get("/users")
def get_users(request):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ The parameter injection system works in two phases:
app = Robyn(__file__)

# API v1 routes
api_v1 = SubRouter(__file__, prefix="/api/v1")
api_v1 = SubRouter(prefix="/api/v1")

@api_v1.get("/users")
def list_users():
Expand All @@ -359,7 +359,7 @@ The parameter injection system works in two phases:
return {"created": True, "data": body}

# Admin routes
admin = SubRouter(__file__, prefix="/admin")
admin = SubRouter(prefix="/admin")

@admin.get("/dashboard")
def admin_dashboard():
Expand Down Expand Up @@ -393,7 +393,7 @@ The parameter injection system works in two phases:
from robyn.authentication import AuthenticationHandler

# Admin routes with authentication
admin = SubRouter(__file__, prefix="/admin")
admin = SubRouter(prefix="/admin")

class AdminAuth(AuthenticationHandler):
def authenticate(self, request):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ from robyn.robyn import QueryParams

from robyn import Request, SubRouter

subrouter: SubRouter = SubRouter(__name__, prefix="/sub")
subrouter: SubRouter = SubRouter(prefix="/sub")


@subrouter.get("/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ from robyn.robyn import QueryParams

from robyn import Request, SubRouter

subrouter: SubRouter = SubRouter(__name__, prefix="/sub")
subrouter: SubRouter = SubRouter(prefix="/sub")


@subrouter.get("/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ As the application grew, Batman needed a way to organize his routes better. He d
from robyn import SubRouter

# Create a subrouter for crime-related routes
crime_router = SubRouter(__file__, prefix="/crimes")
crime_router = SubRouter(prefix="/crimes")

@crime_router.get("/list")
def list_crimes():
Expand All @@ -21,7 +21,7 @@ def report_crime(request):
return {"id": create_crime_report(crime_data)}

# Create a subrouter for suspect-related routes
suspect_router = SubRouter(__file__, prefix="/suspects")
suspect_router = SubRouter(prefix="/suspects")

@suspect_router.get("/list")
def list_suspects():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const description =
from robyn import SubRouter

# 创建处理犯罪相关路由的子路由器
crime_router = SubRouter(__file__, prefix="/crimes")
crime_router = SubRouter(prefix="/crimes")

@crime_router.get("/list")
def list_crimes():
Expand All @@ -21,7 +21,7 @@ def report_crime(request):
return {"id": create_crime_report(crime_data)}

# 创建处理嫌疑人相关路由的子路由器
suspect_router = SubRouter(__file__, prefix="/suspects")
suspect_router = SubRouter(prefix="/suspects")

@suspect_router.get("/list")
def list_suspects():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ from robyn.robyn import QueryParams

from robyn import Request, SubRouter

subrouter: SubRouter = SubRouter(__name__, prefix="/sub")
subrouter: SubRouter = SubRouter(prefix="/sub")


@subrouter.get("/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ from robyn.robyn import QueryParams

from robyn import Request, SubRouter

subrouter: SubRouter = SubRouter(__name__, prefix="/sub")
subrouter: SubRouter = SubRouter(prefix="/sub")


@subrouter.get("/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ current_file_path = pathlib.Path(__file__).parent.resolve()
jinja_template = JinjaTemplate(os.path.join(current_file_path, "templates"))


frontend = SubRouter(__name__, prefix="/frontend")
frontend = SubRouter(prefix="/frontend")

@frontend.get("/")
async def get_frontend(request):
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/subroutes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .di_subrouter import di_subrouter
from .file_api import static_router

sub_router = SubRouter(__name__, prefix="/sub_router")
sub_router = SubRouter(prefix="/sub_router")

websocket = WebSocket(sub_router, "/ws")

Expand Down
2 changes: 1 addition & 1 deletion integration_tests/subroutes/di_subrouter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from robyn import Request, SubRouter

di_subrouter = SubRouter(__file__, "/di_subrouter")
di_subrouter = SubRouter(prefix="/di_subrouter")
GLOBAL_DEPENDENCY = "GLOBAL DEPENDENCY OVERRIDE"
ROUTER_DEPENDENCY = "ROUTER DEPENDENCY"
di_subrouter.inject_global(GLOBAL_DEPENDENCY=GLOBAL_DEPENDENCY)
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/subroutes/file_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from robyn import Request, SubRouter

static_router = SubRouter(__name__, "/static")
static_router = SubRouter(prefix="/static")


@static_router.get("/build")
Expand Down
2 changes: 1 addition & 1 deletion llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Main application class and sub-router for modular routes.
from robyn import Robyn, SubRouter

app = Robyn(__file__)
api = SubRouter(__file__, prefix="/api")
api = SubRouter(prefix="/api")

@api.get("/users")
def get_users(request):
Expand Down
166 changes: 86 additions & 80 deletions robyn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,35 +78,9 @@ class BaseRobyn(ABC):

def __init__(
self,
file_object: str,
config: Config = Config(),
openapi_file_path: Optional[str] = None,
openapi: Optional[OpenAPI] = None,
dependencies: DependencyMap = DependencyMap(),
) -> None:
directory_path = os.path.dirname(os.path.abspath(file_object))
self.file_path = file_object
self.directory_path = directory_path
self.config = config
self.dependencies = dependencies
self.openapi = openapi

self.init_openapi(openapi_file_path)

if not bool(os.environ.get("ROBYN_CLI", False)):
# the env variables are already set when are running through the cli
load_vars(project_root=directory_path)

self._handle_dev_mode()

logging.basicConfig(level=self.config.log_level)

if self.config.log_level.lower() != "warn":
logger.info(
"SERVER IS RUNNING IN VERBOSE/DEBUG MODE. Set --log-level to WARN to run in production mode.",
color=Colors.BLUE,
)

self.router = Router()
self.middleware_router = MiddlewareRouter()
self.web_socket_router = WebSocketRouter()
Expand All @@ -120,32 +94,6 @@ def __init__(
self.included_routers: List[Router] = []
self._mcp_app: Optional[MCPApp] = None

def init_openapi(self, openapi_file_path: Optional[str]) -> None:
if self.config.disable_openapi:
return

if self.openapi is None:
self.openapi = OpenAPI()

if openapi_file_path:
self.openapi.override_openapi(Path(self.directory_path).joinpath(openapi_file_path))
elif Path(self.directory_path).joinpath("openapi.json").exists():
self.openapi.override_openapi(Path(self.directory_path).joinpath("openapi.json"))
else:
logger.debug("No OpenAPI spec file found; using auto-generated documentation only.", color=Colors.YELLOW)

def _handle_dev_mode(self):
cli_dev_mode = self.config.dev # --dev
env_dev_mode = os.getenv("ROBYN_DEV_MODE", "False").lower() == "true" # ROBYN_DEV_MODE=True
is_robyn = os.getenv("ROBYN_CLI", False)

if cli_dev_mode and not is_robyn:
raise SystemExit("Dev mode is not supported in the python wrapper. Please use the Robyn CLI. e.g. python3 -m robyn app.py --dev")

if env_dev_mode and not is_robyn:
logger.error("Ignoring ROBYN_DEV_MODE environment variable. Dev mode is not supported in the python wrapper.")
raise SystemExit("Dev mode is not supported in the python wrapper. Please use the Robyn CLI. e.g. python3 -m robyn app.py")

def add_route(
self,
route_type: Union[HttpMethod, str],
Expand Down Expand Up @@ -335,32 +283,6 @@ def is_port_in_use(self, port: int) -> bool:
except Exception:
raise Exception(f"Invalid port number: {port}")

def _add_openapi_routes(self, auth_required: bool = False):
if self.config.disable_openapi:
return

if self.openapi is None:
logger.error("No openAPI")
return

self.router.prepare_routes_openapi(self.openapi, self.included_routers)

self.add_route(
route_type=HttpMethod.GET,
endpoint="/openapi.json",
handler=self.openapi.get_openapi_config,
is_const=True,
auth_required=auth_required,
)
self.add_route(
route_type=HttpMethod.GET,
endpoint="/docs",
handler=self.openapi.get_openapi_docs_page,
is_const=True,
auth_required=auth_required,
)
self.exclude_response_headers_for(["/docs", "/openapi.json"])

def exception(self, exception_handler: Callable):
self.exception_handler = exception_handler

Expand Down Expand Up @@ -626,6 +548,90 @@ def calculate_tool(args):


class Robyn(BaseRobyn):
def __init__(
self,
file_object: str,
config: Config = Config(),
openapi_file_path: Optional[str] = None,
openapi: Optional[OpenAPI] = None,
dependencies: DependencyMap = DependencyMap(),
) -> None:
super().__init__(dependencies=dependencies)

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._init_openapi(openapi_file_path)

if not bool(os.environ.get("ROBYN_CLI", False)):
# the env variables are already set when are running through the cli
load_vars(project_root=directory_path)

self._handle_dev_mode()

logging.basicConfig(level=self.config.log_level)

if self.config.log_level.lower() != "warn":
logger.info(
"SERVER IS RUNNING IN VERBOSE/DEBUG MODE. Set --log-level to WARN to run in production mode.",
color=Colors.BLUE,
)

def _init_openapi(self, openapi_file_path: Optional[str]) -> None:
if self.config.disable_openapi:
return

if self.openapi is None:
self.openapi = OpenAPI()

if openapi_file_path:
self.openapi.override_openapi(Path(self.directory_path).joinpath(openapi_file_path))
elif Path(self.directory_path).joinpath("openapi.json").exists():
self.openapi.override_openapi(Path(self.directory_path).joinpath("openapi.json"))
else:
logger.debug("No OpenAPI spec file found; using auto-generated documentation only.", color=Colors.YELLOW)

def _handle_dev_mode(self):
cli_dev_mode = self.config.dev # --dev
env_dev_mode = os.getenv("ROBYN_DEV_MODE", "False").lower() == "true" # ROBYN_DEV_MODE=True
is_robyn = os.getenv("ROBYN_CLI", False)

if cli_dev_mode and not is_robyn:
raise SystemExit("Dev mode is not supported in the python wrapper. Please use the Robyn CLI. e.g. python3 -m robyn app.py --dev")

if env_dev_mode and not is_robyn:
logger.error("Ignoring ROBYN_DEV_MODE environment variable. Dev mode is not supported in the python wrapper.")
raise SystemExit("Dev mode is not supported in the python wrapper. Please use the Robyn CLI. e.g. python3 -m robyn app.py")

def _add_openapi_routes(self, auth_required: bool = False):
if self.config.disable_openapi:
return

if self.openapi is None:
logger.error("No openAPI")
return

self.router.prepare_routes_openapi(self.openapi, self.included_routers)

self.add_route(
route_type=HttpMethod.GET,
endpoint="/openapi.json",
handler=self.openapi.get_openapi_config,
is_const=True,
auth_required=auth_required,
)
self.add_route(
route_type=HttpMethod.GET,
endpoint="/docs",
handler=self.openapi.get_openapi_docs_page,
is_const=True,
auth_required=auth_required,
)
self.exclude_response_headers_for(["/docs", "/openapi.json"])

def start(self, host: str = "127.0.0.1", port: int = 8080, _check_port: bool = True, client_timeout: int = 30, keep_alive_timeout: int = 20):
"""
Starts the server
Expand Down Expand Up @@ -682,8 +688,8 @@ def start(self, host: str = "127.0.0.1", port: int = 8080, _check_port: bool = T


class SubRouter(BaseRobyn):
def __init__(self, file_object: str, prefix: str = "", config: Config = Config(), openapi: OpenAPI = OpenAPI()) -> None:
super().__init__(file_object=file_object, config=config, openapi=openapi)
def __init__(self, prefix: str = "", dependencies: DependencyMap = DependencyMap()) -> None:
super().__init__(dependencies=dependencies)
self.prefix = prefix

def __add_prefix(self, endpoint: str):
Expand Down
Loading