improve file upload example. made alot of comments to make it easy to follow

Commit 56a1523 · patx · 2025-06-10T17:37:51-04:00

Changeset
56a15238aa209e6f443dd9004207cd63af122981
Parents
291a0f159d9875e0aa98e4f0ea8bb3a3fa16e0c7

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/dist/micropie-0.11-py2.py3-none-any.whl b/dist/micropie-0.11-py2.py3-none-any.whl
new file mode 100644
index 0000000..d0f0887
Binary files /dev/null and b/dist/micropie-0.11-py2.py3-none-any.whl differ
diff --git a/dist/micropie-0.11.tar.gz b/dist/micropie-0.11.tar.gz
new file mode 100644
index 0000000..14082ac
Binary files /dev/null and b/dist/micropie-0.11.tar.gz differ
diff --git a/examples/file_uploads/app.py b/examples/file_uploads/app.py
index 98228a6..523f3d2 100644
--- a/examples/file_uploads/app.py
+++ b/examples/file_uploads/app.py
@@ -1,44 +1,52 @@
-import os
-import re
-import aiofiles
-from MicroPie import App
+import os          # Used for file path handling and directory creation
+import aiofiles    # Asynchronous file I/O operations
+from MicroPie import App  # Import the base App class from MicroPie
 
-UPLOAD_DIR = "uploads"
-os.makedirs(UPLOAD_DIR, exist_ok=True)  # Ensure directory exists
-MAX_UPLOAD_SIZE = 100 * 1024 * 1024  # 100MB
+# Ensure the "uploads" directory exists; create it if it doesn't
+os.makedirs("uploads", exist_ok=True)
 
 class Root(App):
+    """
+    This is the main application class that inherits from MicroPie's App.
+    It defines the HTTP routes and handles the logic for file uploading.
+    """
 
     async def index(self):
+        """
+        Serve a simple HTML form that lets the user choose a 
+        file and submit it via POST to /upload.
+        """
         return """<form action="/upload" method="post" enctype="multipart/form-data">
-            <label for="file">Choose a file:</label>
-            <input type="file" id="file" name="file" required>
+            <input type="file" name="file" required>
             <input type="submit" value="Upload">
-        </form>"""
+            </form>"""
 
     async def upload(self, file):
-        try:
-            filename = file["filename"]
-            # Sanitize filename
-            safe_filename = re.sub(r'[^\w\.-]', '_', os.path.basename(filename))
-            queue = file["content"]
-            total_bytes = 0
-            filepath = os.path.join(UPLOAD_DIR, safe_filename)
-
-            async with aiofiles.open(filepath, "wb") as f:
-                while True:
-                    chunk = await queue.get()
-                    if chunk is None:
-                        break
-                    if total_bytes + len(chunk) > MAX_UPLOAD_SIZE:
-                        await aiofiles.os.remove(filepath)  # Clean up partial file
-                        return 400, "File exceeds maximum size of 100MB"
-                    await f.write(chunk)
-                    total_bytes += len(chunk)
-
-            return 200, f"Uploaded {safe_filename} ({total_bytes} bytes) to {filepath}"
-        except Exception as e:
-            print(f"Upload error: {e}")
-            return 500, f"Failed to upload {filename}: {str(e)}"
+        """
+        Handle the uploaded file from the client:
+        - Saves the file to disk in the "uploads" directory.
+        - Uses aiofiles to write the file asynchronously, in chunks.
+        
+        `file` is a dictionary with:
+            'filename': The original filename of the uploaded file.
+            'content_type': The MIME type of the file (defaults 
+                to application/octet-stream).
+            'content': An asyncio.Queue containing chunks of file data as 
+                bytes, with a None sentinel signaling the end of the stream.
+        """
 
+        # Construct a safe path to save the uploaded file
+        filepath = os.path.join("uploads", file["filename"])
+        
+        # Open the destination file asynchronously for writing
+        async with aiofiles.open(filepath, "wb") as f:
+            # Read and write the file in chunks
+            while chunk := await file["content"].get():
+                await f.write(chunk)
+
+        # Return a confirmation response with the uploaded filename
+        return 200, f"Uploaded {file['filename']}"
+
+# Instantiate the app
 app = Root()
+