How to Create a Simple Web App That Allows Users to Upload Files

Providing an easy method for collaborators to upload files to a filestore without the demand for them to understand whatsoever code whatsoever

Photo by Hello I'yard Nik 🎞 on Unsplash

When edifice a webserver we ofttimes wish to present an thought or topic. In the case of a static website, this tin can exist done by including the relevant information within the source files. In more than dynamic examples, an API (application programming interface) tin exist used to pre-process information before returning it to the user.

In this example, we design a unproblematic flask app which but requires a user fundamental and a web browser to work. The thought behind this is that anyone can use it, and information technology is a device (and operating system), contained.

Creating the flask app

As usual, nosotros starting time by installing the relevant libraries for the server. The simplest way to practice this is through the use of pip (pythons parcel manager).

            pip install flask, werkzeug          

The upload-page template

Next, create our HTML template for the login page. To exercise this we start in our application directory and make a new file named templates . Inside this, we create a file named upload.html and paste the following lawmaking inside it.

In essence, we have a form which contains our countersign input, a file upload input and a submit button. When working this will look equally follows

Output from upload_simple.html

Setting up the upload options

Next, nosotros define a config file for our upload options. To do this create a file named config.py in your main app folder. Within this, we tin specify a maximum accepted file size, the upload destination, and what file extensions nosotros can cull to accept. Copy the lawmaking below into config.py and adjust accordingly.

A note on file types: File extensions do non guarantee file type and we should avert executing any uploaded files. This is why nosotros later innovate a password — such that only approved users can upload.

A flask template

We brainstorm with a bones flask template, which imports our information and serves the upload.html page when navigating to http://127.0.0.i:4000/upload

Upload file checks

Now nosotros have our app, nosotros can add together a number of functions to ensure that we have the correct directory, and if not create information technology.

            if not os.path.isdir(upload_dest):
os.mkdir(upload_dest)

We can prepare the maximum file upload size (using the value from config.py)

            app.config['MAX_CONTENT_LENGTH'] = file_mb_max * 1024 * 1024          

and as well bank check the file extensions (once again divers in config.py)

            def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in extensions

Personally, I have added these between app.hole-and-corner and the @app.route sections inside the code.

What to exercise on upload

Finally, we have yet to tell the program what to do upon uploading. We practise and then this past parsing the post asking from the upload page. For information on what this means — take a read of:

Hither we check if the request.method is a POST, and if so handle any files attached. The first department deals with an empty asking, whilst the 2nd iterates through each file, checks that they have the correct file extension, and if then saves them to our desired location (upload_dest).

            @app.route('/upload', methods=['POST'])
def upload_file():
if asking.method == 'POST':
if 'files[]' non in request.files:
flash('No files found, endeavor again.')
return redirect(request.url)
files = asking.files.getlist('files[]') for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join( upload_dest, filename))
wink('File(due south) uploaded')
return redirect('/upload')

Testing the usage example

Finally, earlier continuing on to adding passwords, nosotros want to make sure that the upload functions as intended. To do this we run the python script, navigate to http://127.0.0.1:4000/upload, select a few files and click upload. If this has been successful, and yous are using the configuration above, your files should at present reside within an uploads_folder directory nested in the same binder every bit your app.

Calculation an encrypted database for user hallmark

Then far we have created a Flask app which we can use to upload files. Next, we want to add a layer of basic security, such that we can runway what files have been uploaded and by whom. In addition, this allows us to decline anyone not authorised to commit data to the directory.

Installing pysqlcipher3

Nosotros begin past installing our database tool. This tin can sometimes cause bug for people, so the installation instructions for Mac and Linux take been included beneath.

MAC

            brew install SQLCipher
pip install pysqlcipher3

LINUX

            sudo apt install sqlcipher libsqlcipher0 libsqlcipher-dev
sudo -H pip3 install pysqlcipher3
python3 -c 'import pysqlcipher3; print(pysqlcipher3.__path__)'

Connecting to the database

We showtime by connecting to the database. If y'all accept ever used databases earlier, the pysqlcipher syntax is pretty much the same as sqlite, or whatever postgresql libraries. We brainstorm by importing the libraries

            from pysqlcipher3 import dbapi2 every bit sqlite3
from config import app_key, db_loc

Then connecting to the database:

            conn = sqlite3.connect(db_loc)# where this is /path/test.db
cursor = conn.cursor()

Finally, we need to specify an encryption key for our database in order to be able to access the information.

            cursor.execute("PRAGMA key='%s'"%app_key)          

If you do non practise this, or utilize a different cardinal, you volition receive the post-obit error: DatabaseError: file is not a database when trying to read data from the database schema.

Creating the Database

Having opened our database, and entered our key, we can now create a table to shop our values. We do this by executing a create tabular array SQL command with the cursor execute function. The simplest usage case would require a proper name and an upload_key.

            cursor.execute(
'''
CREATE TABLE IF NOT EXISTS upload (
id INTEGER NOT NULL Chief Cardinal AUTOINCREMENT,
proper noun TEXT Non Zippo,
upload_key TEXT UNIQUE
);
'''
)

Additionally, I have set up a status that each central has to be unique, equally we are non using a user name to log on.

Finally, we have to commit our new table to the database and close it.

            conn.commit()
## conn.close()
## close only when we have finished everything, otherwise we have to reopen the database each fourth dimension

Adding a User

We demand users to exist able to use the upload tool, then we can add some using the insert command.

            cursor.execute(
'''
INSERT INTO upload (name, dir, uploadcode)
VALUES ("bob", "bobs top hole-and-corner upload key")
'''
conn.commit()

Reading the Database

As a check, we desire to run across if there is a name associated with the upload_key. This tin be done with the select function, coupled with a where provisional.

            user_code = 'bobs superlative secret upload key'            cursor.execute('select              * from upload              where              uploadcode="%southward"'%user_code)            result = cursor.fetchall() # go all the results east.g. [("bob",)]          

Stringing it all together

Now we have a database and an upload script, we can combine the two.

Opening the database

Firstly we add together the required library

            from pysqlcipher3 import dbapi2 as sqlite3
# from config import app_key, db_loc # already imported

under the from config_simple import *line.

Reading the password

If you are using the HTML lawmaking from before, we already accept a countersign input field :<p> upload_key: <input name="psw" type="password" /></p>

As this is inside the submission form we tin read it equally part of the POST request in the @app.route wrapper.

            user_code = str(request.class.get('psw'))          

Nosotros combine this with our database read to form a conditional checking if there is anyone with that access key /password.

            cursor.execute('select * from upload where uploadcode="%s"'%user_code)
result = cursor.fetchall()
if len(result)==0:
flash('Non a valid Code')
return redirect(request.url)

However, since the database can simply be opened and read from the same computational thread as the website we need to place

            conn = sqlite3.connect(db_loc)
cursor = conn.cursor()
cursor.execute("PRAGMA fundamental='%due south'"%app_key)

before the cursor.execute block, and a conn.shut() after the result = line. (run into app.py in the GitHub repo at the cease)

Conclusion

And there we have information technology — the about basic of submission boxes which allows for the uploading of files past pre-approved users. There are however a number of improvements that you may wish to make (these are all in the additional files shown in the GitHub repository below).

  • Checking the filename string for an extension tin can crusade issues. Files may be named incorrectly, or fifty-fifty not have an extension (equally was the case with many of my files). Instead, we can filter on the file.mimetype values. These are of the format prototype/png etc.
  • Drag and Drop uploading. It tin can ofttimes be cumbersome to manually select files, peculiarly if they are in different locations. Dragging them from a file browser makes life much simpler for the user.
  • Automatic uploads. Another mutual mistake is to select a file, but forget to click submit. Having a window that works immediately after you drop a file in information technology can help aid productivity and user satisfaction
  • File previews. If the user is uploading images, it tin always be helpful to take miniature previews available. This allows a last-minute check such that you are not repeatedly submitting the same file.
  • File failure indicators. Although there is a message informing us of the upload status, a visual cue (ie a lighter preview image) makes it much easier to see if something has not worked.
  • Unique download spaces — if you have many users, it tin become confusing which file belongs to who (not to mention the overwriting problem). Instead, we can add together a designated space for each user, and save the paths within the database.

Adding all the additional suggestions in a higher place and we the following output.

Here we come across, two files have failed, with one succeeding in the middle. In this example, information technology was due to invalid user credentials and an intentionally invalid filetype.

Disclaimer: this is not the about secure method of checking credentials, however for the purposes of many tasks it can be a perfectly adequate solution.

Codebase

All the case code for this tutorial has been dumped (quite literally) into a Github repository.

If you have any improvements, feel free to submit a pull asking.

bertrandtheiropeop.blogspot.com

Source: https://towardsdatascience.com/writing-a-multi-file-upload-python-web-app-with-user-authentication-8f75064b819a

0 Response to "How to Create a Simple Web App That Allows Users to Upload Files"

Publicar un comentario

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel