fully updated index routes ability to accept url path params, with 404 when needed

Commit 8af8853 · patx · 2025-01-25T16:32:21-05:00

Changeset
8af88539501cab05008560a424153907505c36e4
Parents
5019a5fb148663a0b81bc0cc2a3363ca91187258

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/MicroPie.py b/MicroPie.py
index c42faab..59d7e54 100644
--- a/MicroPie.py
+++ b/MicroPie.py
@@ -36,6 +36,8 @@ from wsgiref.simple_server import make_server
 import time
 import uuid
 import inspect
+import os
+import mimetypes
 from urllib.parse import parse_qs
 
 try:
@@ -210,6 +212,16 @@ class Server:
             return False
 
     def wsgi_app(self, environ, start_response):
+        """
+        A WSGI-compatible application method that processes incoming requests,
+        manages sessions, dispatches to the correct handler function,
+        and supports streaming/generator responses.
+        IMPORTANT:
+          - If your route returns (status, body, extra_headers), we handle them
+            in a single call to start_response.
+          - Do NOT call `start_response` in your handler.
+
+        """
         self.environ = environ
         self.start_response = start_response
 
@@ -221,10 +233,13 @@ class Server:
         func_name = path_parts[0] if path_parts else "index"
         self.path_params = path_parts[1:] if len(path_parts) > 1 else []
 
+        # Get the handler function
+        handler_function = getattr(self, func_name, None)
+
         # Special case: If the first segment doesn't match a function, assume index
-        if not hasattr(self, func_name):
+        if not handler_function:
             self.path_params = path_parts
-            func_name = "index"
+            handler_function = getattr(self, "index", None)
 
         # Parse query parameters
         self.query_params = parse_qs(environ["QUERY_STRING"])
@@ -285,12 +300,7 @@ class Server:
                 start_response("400 Bad Request", [("Content-Type", "text/html")])
                 return [f"400 Bad Request: {str(e)}".encode("utf-8")]
 
-        # Find the requested handler
-        handler_function = getattr(self, func_name, None)
-        if not handler_function:
-            start_response("404 Not Found", [("Content-Type", "text/html")])
-            return [b"404 Not Found"]
-
+        # Check if the handler function requires arguments
         sig = inspect.signature(handler_function)
         func_args = []
 
@@ -308,6 +318,11 @@ class Server:
                 start_response("400 Bad Request", [("Content-Type", "text/html")])
                 return [msg.encode("utf-8")]
 
+        # If the index method does not take any arguments and the path is not empty, return 404
+        if handler_function == getattr(self, "index", None) and not func_args and path:
+            start_response("404 Not Found", [("Content-Type", "text/html")])
+            return [b"404 Not Found"]
+
         try:
             response = handler_function(*func_args)
             status_code = 200
@@ -358,4 +373,3 @@ class Server:
             except:
                 pass
             return [b"500 Internal Server Error"]
-
diff --git a/README.md b/README.md
index 6ec1ae0..2d81252 100644
--- a/README.md
+++ b/README.md
@@ -115,33 +115,6 @@ class MyApp(Server):
 - [http://127.0.0.1:8080/profile/456](http://127.0.0.1:8080/profile/456)
   - Returns: `User ID: 456, Age: Unknown`
 
-#### **Other Considerations for GET requests**
-In **MicroPie**, the `index` method serves as the default route handler, which behaves differently compared to other route methods such as `greet` or any custom-defined handlers.
-
-##### Key Differences:
-
-1. **Default Handling:**  
-   - When the root URL (`/`) is accessed, the framework automatically maps the request to the `index` method.  
-   - Other methods (e.g., `greet`) must be explicitly accessed via their route, such as `/greet`.
-
-2. **URL Parameter Handling:**  
-   - The `index` method does **not** receive URL path parameters in the same way as other route methods.  
-   - Instead, it primarily relies on query parameters (e.g., `/index?name=John`).  
-   - Other methods can accept parameters directly from the URL path (e.g., `/greet/John`).
-
-##### Example Usage:
-
-| URL                  | Method Called             | Notes                                  |
-|--------------------- |--------------------------|----------------------------------------|
-| `/`                  | `index()`                 | Default route, no path parameters.    |
-| `/index?name=John`   | `index(name="John")`       | Query parameters work.                 |
-| `/greet/John`        | `greet("John")`            | Path parameters are passed correctly.  |
-| `/<dynamic_path>`    | **Not supported**          | Will result in a 404 error.            |
-
-**Note:** Dynamic paths such as `/<dynamic_path>` will not work with the `index` method. Instead, they should be explicitly handled using dedicated route methods.
-
-By understanding this distinction, you can structure your routes effectively when using MicroPie.
-
 ### **3. Handling POST Requests**
 
 MicroPie supports handling form data submitted via HTTP POST requests. Form data is automatically mapped to method arguments.
diff --git a/examples/streaming/text.py b/examples/streaming/text.py
index a020863..0fd7b66 100644
--- a/examples/streaming/text.py
+++ b/examples/streaming/text.py
@@ -2,6 +2,7 @@ import time
 from MicroPie import Server
 
 class Root(Server):
+
     def index(self):
         # Normal, immediate response (non-streaming)
         return "Hello from index!"
diff --git a/examples/streaming/video.mp4 b/examples/streaming/video.mp4
new file mode 100644
index 0000000..9b89f62
Binary files /dev/null and b/examples/streaming/video.mp4 differ
diff --git a/examples/streaming/video1.py b/examples/streaming/video1.py
index ede6965..efd0b72 100644
--- a/examples/streaming/video1.py
+++ b/examples/streaming/video1.py
@@ -81,7 +81,7 @@ class VideoStreamer(Server):
 app = VideoStreamer()
 
 # The WSGI entry point Gunicorn will look for
-wsgi_app = app.wsgi_apps
+wsgi_app = app.wsgi_app
 
 if __name__ == "__main__":
     app.run()