The provided content is a comprehensive tutorial on building a drag & drop file upload form using FastAPI, JavaScript, and Python.
Abstract
This article offers a step-by-step guide to creating a drag & drop file upload form, integrating backend Python code with FastAPI and frontend JavaScript. It covers setting up a FastAPI Web Starter project, installing necessary Python packages, structuring the application, and implementing both drag & drop and file selection upload methods. The tutorial also includes the creation of an upload area with custom styles, the use of JavaScript for handling drag & drop events, and Python functions for processing and saving uploaded files. Additionally, it demonstrates the upload process with visual examples and discusses future applications such as image analysis.
Opinions
The author emphasizes the versatility of FastAPI for building high-performance web frameworks, noting its modern features and reliance on standard Python type hints.
The use of HTML Drag and Drop interfaces is presented as a user-friendly feature that enhances the application's usability.
The article suggests that the code and techniques provided can be adapted for use with other Python frameworks, not just FastAPI.
The author provides links to additional resources for setting up a Python environment, creating a GitHub repository, and deploying a FastAPI app for free, indicating a commitment to comprehensive support for developers.
The inclusion of a Bootstrap 5 update reflects the author's attention to keeping the tutorial current with web development standards.
By offering the final code and a live demo, the author demonstrates a dedication to practical, hands-on learning and application.
How to Build a Drag & Drop Form with FastAPI & JavaScript
Step by Step Tutorial to Create Uploading File Form
Tableof Contents
· Introduction
· Set-Up
· Installing Python Packages Using requirements.txt
· Structure
· Creating the Upload Page
∘ ① How toadd a router in app/main.py
∘ ② Adding a link to the templates/include/topnav.html
∘ ③ Creating a controller app/routers/upload.py
∘ ④ Creating a view page, templates/upload.html
· Creating Upload Area
∘ Updating upload.html
· Plan ofProcedure
· Adding Drag & DropFunctions
· Python Codes
· Adding the upload/new Post Method
· Demo Using Drag andDrop
· Demo Using File Select
· Conclusion
· Updates
· References
Introduction
This article shows how to build a drag & drop form using Python and Javascript. Uploading files allows users to analyze their data or image on your app. We use FastAPI [1] for this tutorial but you can apply this to Flask or other Python frameworks. FastAPI is a modern, high-performance, web framework for building APIs with Python 3.6+ based on standard Python type hints. HTML Drag and Drop [2] interfaces enable applications to use drag-and-drop features in browsers.
Code along with the article or grab the final code.
<liclass="nav-item {{'active' if active_page == 'upload' }}"><aclass="nav-link"href="/upload">Upload</a></li>
We use Jinja’s if-statement to check that the active_page is upload. If it is so, it will add the active class.
③ Creating a controller app/routers/upload.py
Line 1: We import FastAPI’s APIRouter. We can include this file in the app/main.py.
Line 5: We create a APIRouter object, router.
Line 9-12: We use the get method with a URL of /upload. We use the HTMLResponse to return an HTML file called upload.html. For now, we return a variable result to the HTML file.
We are going to create a div upload-area in templates/upload.html.
Line 17: Since we will allow users to not only drag-and-drop but also select a file to upload, we add a submit button as well.
Line 37: Add the dragdrop.js. Please note type="module". This allows us to import another javascript file in the dragdrop.js.
Let’s add some styles for the upload page in the static/css/mystyle.css:
Now the page looks like this:
Upload area. Image by Author.
Plan of Procedure
The following flowchart is a summary process in sequential order for uploading a file. For this example, we are going to upload an image file and create a thumbnail.
Summary process in sequential order. Image by Author.
We handle most of the process with JavaScript and create a thumb image with Python. We go through the above process in the next section one by one.
Adding Drag & Drop Functions
There are two functions in static/js/imagehelpers.js.
The detect() function finds the image width and height. It takes an image URL and a callback. It creates a new Image object and assigns the Image src using the URL. We find the image width and height and use them in the callback. We are going to use the image width and height to determine the thumbnail width and height.
In the dragdrop() function, we use dragger, drop, and dragenter events to change the text when a user drags a file over the upload-area. We add preventDefault() and stopPropagation() to prevent the browser's default action.
In the last line, we export both functions so that we can import these in another javascript file.
In the static/js/dragdrop.js:
Line 1: Because we used type="module", we can import the detect() and dragdrop() functions from ./imghelper.js.
Line 4: Run the imported dragdrop() function.
Line 6–20: The preparedata() function creates an image URL blob using the file as the source. It uses the imported detect() function with the created image URL blob. The callback function uses the window.width(), imgWidth, and imgHeight - both are in the result returned from the detect() function. We store them in the data object and use the stringily() function to convert the JavaScript object to a JSON string. We append it and the dropped file. We then run the uploadData() function.
Line 23–36: This part controls actions when a user drops a file. First, it will change the text to “We are uploading your file”.
event.originalEvent.dataTransfer.files returns a list of files.
Returned value from e.originalEvent.dataTransfer.files
We use it to define the file variable, get the window width, winWidth and get the dropped file which is the first item on the list. If the dropped file matches the imageType, send it to the preparedata() function. Otherwise, change the text telling "Please use an image file. Try one more time.".
Line 39–41: This triggers the “select file” dialog box.
Line 44–54: This part is the same as line 28–36.
Line 57–69: This AJAX part posts data to the URL /upload/new. Once it is successful, it runs the updatatags() function.
Line 71–76: We set the HTML contents using an img tag, and change back the text to "Drag and Drop file here<br />Or<br />Click to Upload".
Python Codes
We add four more functions to the library/helpers.py.
setdimensions() calculates and returns dimensions for a thumbnail.
create_workspace() returns a directory path using uuid.uuid4() to create a unique directory name.
thumb() creates a thumbnail and saves it in a directory.
image_trannspose_exif() prevents a created image from rotation.
Adding the upload/new Post Method
Update app/routers/upload.py:
Line 1: Import File and UploadFile from fastapi.
Line 4: Import all functions from ../library/helpers.
Line 18: Add parameters, imgdata and file.
Line 19: The imgdata[0] contains winWidth, imgWidthand imgHeight. We convert the string to a Python dictionary using eval().
Line 22: Create the directory path and store it in the workspace variable.
Line 24: Store the dropped file name to file_name.
Line 26: Store the full path to img_full_path variable.
Line 27–29: Save the dropped file in the directory.
Line 31–35: Create a thumbnail and store the path to thumb_path variable.
Line 37–40: Return the img_full_path and thumb_path. These values will be used in dragdrop.js to insert the thumbnail on the page.
Demo Using Drag and Drop
Demo Using File Select
Conclusion
The uploaded image can be analyzed in your app. In a future article, we will cover how to find dominant colors in the image. Since we have the original and thumbnail in the directory we can use one of the images depending on the workload.