Repository: sparckles/Robyn (language: python)

Issue:
fix: allow generic parameter names in function callbacks
<!-- 
Thank you for considering improving Robyn!

Please describe your idea in depth. If you're not sure what to write, imagine the following:
  - How is this important to you? How would you use it?
  - Can you think of any alternatives?
  - Do you have any ideas about how it can be implemented? Are you willing/able to implement it? Do you need mentoring?
-->

e.g.

allow
```
@app.get('/')
def fx(r: Request):
  ...
```


Discussion / hints:

Fix patch:
diff --git a/docs_src/src/components/documentation/ApiDocs.jsx b/docs_src/src/components/documentation/ApiDocs.jsx
index d54f7f984..14864cc86 100644
--- a/docs_src/src/components/documentation/ApiDocs.jsx
+++ b/docs_src/src/components/documentation/ApiDocs.jsx
@@ -50,8 +50,7 @@ const guides = [
   {
     href: '/documentation/api_reference/redirection',
     name: 'Redirection',
-    description:
-      'Learn how to redirect requests to different endpoints.',
+    description: 'Learn how to redirect requests to different endpoints.',
   },
   {
     href: '/documentation/api_reference/file-uploads',
@@ -61,7 +60,7 @@ const guides = [
   },
   {
     href: '/documentation/api_reference/form_data',
-    name: 'Form Data',
+    name: 'Form Data and Multi Part Form Data',
     description: 'Learn how to handle form data.',
   },
   {
diff --git a/docs_src/src/components/documentation/Navigation.jsx b/docs_src/src/components/documentation/Navigation.jsx
index 5548d16c5..10859d8f6 100644
--- a/docs_src/src/components/documentation/Navigation.jsx
+++ b/docs_src/src/components/documentation/Navigation.jsx
@@ -256,7 +256,10 @@ export const navigation = [
         href: '/documentation/api_reference/templating',
         title: 'Templating',
       },
-      { title: 'Redirection', href: '/documentation/api_reference/redirection' },
+      {
+        title: 'Redirection',
+        href: '/documentation/api_reference/redirection',
+      },
       {
         href: '/documentation/api_reference/file-uploads',
         title: 'File Uploads',
diff --git a/docs_src/src/pages/documentation/api_reference/dependency_injection.mdx b/docs_src/src/pages/documentation/api_reference/dependency_injection.mdx
index 64f990637..b942f83f0 100644
--- a/docs_src/src/pages/documentation/api_reference/dependency_injection.mdx
+++ b/docs_src/src/pages/documentation/api_reference/dependency_injection.mdx
@@ -71,12 +71,12 @@ Router level dependency injection is used to inject dependencies into the router
       app.inject(ROUTER_DEPENDENCY=ROUTER_DEPENDENCY)
 
       @app.get("/sync/global_di")
-      def sync_global_di(request, router_dependencies):
+      def sync_global_di(r, router_dependencies): # r is the request object
         return router_dependencies["ROUTER_DEPENDENCY"]
     ```
 
     ```python {{ title: 'typed' }}
-      from robyn import Robyn, ALLOW_CORS
+      from robyn import Robyn, ALLOW_CORS, Request
 
       app = Robyn(__file__)
       ROUTER_DEPENDENCY = "ROUTER DEPENDENCY"
@@ -84,7 +84,7 @@ Router level dependency injection is used to inject dependencies into the router
       app.inject(ROUTER_DEPENDENCY=ROUTER_DEPENDENCY)
 
       @app.get("/sync/global_di")
-      def sync_global_di(request, router_dependencies):
+      def sync_global_di(r: Request, router_dependencies):
         return router_dependencies["ROUTER_DEPENDENCY"]
     ```
     </CodeGroup>
@@ -93,7 +93,7 @@ Router level dependency injection is used to inject dependencies into the router
 
 <Row>
 <Col>
-Note: `router_dependencies`, `global_dependencies` , `request` are named parameters and **must** be named as such. The order of the parameters does not matter.
+Note: `router_dependencies`, `global_dependencies` are reserved parameters and **must** be named as such. The order of the parameters does not matter among them. However, the `router_dependencies` and `global_dependencies` must only come after the `request` parameter. 
 </Col>
 </Row>
 
diff --git a/docs_src/src/pages/documentation/api_reference/file-uploads.mdx b/docs_src/src/pages/documentation/api_reference/file-uploads.mdx
index dec4aa926..10d0ece73 100644
--- a/docs_src/src/pages/documentation/api_reference/file-uploads.mdx
+++ b/docs_src/src/pages/documentation/api_reference/file-uploads.mdx
@@ -57,26 +57,20 @@ Batman scaled his application across multiple cores for better performance. He u
     <CodeGroup title="Request" tag="GET" label="/hello_world">
 
     ```python {{ title: 'untyped' }}
-    @app.post("/upload")
-    async def upload(request):
-      file = request.files['filename']
 
-      # write whatever filename
-      with open('filename', 'wb') as f:
-          f.write(file)
-
-      return {'message': 'success'}
+    @app.post("/sync/multipart-file")
+    def sync_multipart_file(request: Request):
+        files = request.files
+        file_names = files.keys()
+        return {"file_names": list(file_names)}
     ```
     ```python {{ title: 'typed' }}
-    @app.post("/upload")
-    async def upload(request: Request):
-      file = request.files['filename']
 
-      # write whatever filename
-      with open('filename', 'wb') as f:
-          f.write(file)
-
-      return {'message': 'success'}
+    @app.post("/sync/multipart-file")
+    def sync_multipart_file(request: Request):
+        files = request.files
+        file_names = files.keys()
+        return {"file_names": list(file_names)}
     ```
 
     </CodeGroup>
diff --git a/docs_src/src/pages/documentation/api_reference/form_data.mdx b/docs_src/src/pages/documentation/api_reference/form_data.mdx
index 11f528c14..b8021d9cc 100644
--- a/docs_src/src/pages/documentation/api_reference/form_data.mdx
+++ b/docs_src/src/pages/documentation/api_reference/form_data.mdx
@@ -1,12 +1,12 @@
 export const description =
   'On this page, we’ll dive into using the form data.'
 
-## Form Data
+## Form Data and Multi Part Form Data
 
 Batman learned how to handle file uploads using Robyn. Now, he wanted to handle the form data.
 
 
-## Handling Form Data
+## Handling Multi Part Form Data
 
 <Row>
 <Col>
diff --git a/docs_src/src/pages/documentation/api_reference/redirection.mdx b/docs_src/src/pages/documentation/api_reference/redirection.mdx
index d241fa546..b2427d15b 100644
--- a/docs_src/src/pages/documentation/api_reference/redirection.mdx
+++ b/docs_src/src/pages/documentation/api_reference/redirection.mdx
@@ -32,6 +32,6 @@ Batman wanted to redirect some endpoints to others. Robyn helped him do so by th
 
 ## What's next?
 
-Now, Batman wanted to have the ability to upload files to the server if any new villain appeared. Robyn introduced him to the file upload feature. 
+Now, Batman wanted to have the ability to upload files to the server if any new villain appeared. Robyn introduced him to the file upload and some of the form data features. 
 
-- [File Uploads](/documentation/api_reference/file-uploads)
\ No newline at end of file
+- [File Uploads](/documentation/api_reference/file-uploads)
diff --git a/src/executors/mod.rs b/src/executors/mod.rs
index 50da0f896..d47fa7da9 100644
--- a/src/executors/mod.rs
+++ b/src/executors/mod.rs
@@ -24,37 +24,23 @@ where
     T: ToPyObject,
 {
     let handler = function.handler.as_ref(py);
-    // kwargs are handled
     let kwargs = function.kwargs.as_ref(py);
-
     let function_args = function_args.to_object(py);
     debug!("Function args: {:?}", function_args);
 
     match function.number_of_params {
         0 => handler.call0(),
         1 => {
-            if function.args.as_ref(py).get_item("request").is_some()
-                || function.args.as_ref(py).get_item("response").is_some()
+            if kwargs.get_item("global_dependencies").is_some()
+                || kwargs.get_item("router_dependencies").is_some()
+            // these are reserved keywords
             {
-                // If 'request' is present, call handler with 'function_args'
-                handler.call1((function_args,))
-            } else {
-                // If neither 'request' nor 'response' is present
                 handler.call((), Some(kwargs))
-            }
-        }
-        2 => {
-            if function.args.as_ref(py).get_item("request").is_some()
-                || function.args.as_ref(py).get_item("response").is_some()
-            {
-                // If either 'request' or 'response' is present, call handler with 'function_args' and 'kwargs'
-                handler.call((function_args,), Some(kwargs))
             } else {
-                // If neither 'request' nor 'response' is present
-                handler.call((), Some(kwargs))
+                handler.call1((function_args,))
             }
         }
-        3..=u8::MAX => handler.call((function_args,), Some(kwargs)),
+        _ => handler.call((function_args,), Some(kwargs)),
     }
 }
 


Test patch:
diff --git a/integration_tests/base_routes.py b/integration_tests/base_routes.py
index d60e84527..7ebb87b64 100644
--- a/integration_tests/base_routes.py
+++ b/integration_tests/base_routes.py
@@ -218,7 +218,7 @@ def sync_middlewares_401():
 
 
 @app.get("/")
-async def hello_world(request):
+async def hello_world(r):
     return "Hello, world!"
 
 
diff --git a/integration_tests/subroutes/di_subrouter.py b/integration_tests/subroutes/di_subrouter.py
index f3e790c7c..53317be96 100644
--- a/integration_tests/subroutes/di_subrouter.py
+++ b/integration_tests/subroutes/di_subrouter.py
@@ -1,4 +1,4 @@
-from robyn import SubRouter
+from robyn import SubRouter, Request
 
 di_subrouter = SubRouter(__file__, "/di_subrouter")
 GLOBAL_DEPENDENCY = "GLOBAL DEPENDENCY OVERRIDE"
@@ -8,7 +8,7 @@
 
 
 @di_subrouter.get("/subrouter_router_di")
-def sync_subrouter_route_dependency(router_dependencies):
+def sync_subrouter_route_dependency(r: Request, router_dependencies, global_dependencies):
     return router_dependencies["ROUTER_DEPENDENCY"]