Pluralsight Logo
Author avatar

Chidiebere Nnadi

Author badge Author

Introduction and Setup to Building a Simple File Storage Service Using VueJS, Flask, and RethinkDB

Chidiebere Nnadi

Author BadgeAuthor
  • Aug 9, 2018
  • 5 Min read
  • 30,758 Views
  • Aug 9, 2018
  • 5 Min read
  • 30,758 Views
Python
Storage

Introduction

In this guide, I will be showing you how to build a simple file storage service. We shall be making use of VueJS to handle the front-end interactions, Flask for the back-end, and RethinkDB for database storage. I will be introducing a number of tools as we go, so stay tuned.

In the first part of this series of guides, I will be focusing on building out the back-end for the application. Later, I'll cover implementing some of the principles taught here in your current workflow either as a Python developer, Flask developer, or even as a programmer in general.

Building the API

Let's start by building out our API. Using this file storage service, as a user, we should be able to:

  1. Create an account
  2. Login
  3. Create and manage folders and subfolders
  4. Upload a file into a folder
  5. View file properties
  6. Edit and Delete files

For the API, we should have the following endpoints:

  • POST /api/v1/auth/login - This endpoint will be used to login users
  • POST /api/v1/auth/register - This endpoint will be used to register users
  • GET /api/v1/user/<user_id>/files/ - This endpoint will be used to list files for a user with user id user_id
  • POST /api/v1/user/<user_id>/files/ - This endpoint will be used for creating new files for the user with user id user_id
  • GET /api/v1/user/<user_id>/files/<file_id> - This endpoint will be used to get a single file with id file_id
  • PUT /api/v1/user/<user_id>/files/<file_id> - This endpoint will be used to edit a single file with id file_id
  • DELETE /api/v1/user/<user_id>/files/<file_id> - This endpoint will be used to delete a single file with id file_id

OK, we've figured out the API endpoints that we need to create this app. Now, we need to start the actual process of creating the endpoints. So let's get to it.

Setup

You should start by creating a project directory. This is the recommended structure for our application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- /api
  -- /controllers
  -- /utils
  -- models.py
  -- __init__.py
-- /templates
-- /static
  -- /lib
  -- https://www.pluralsight.com/js
  -- /css
  -- /img
-- index.html
-- config.py
-- run.py

The modules and packages for the API will be put into the /api directory with the models stored in the models.py module, and the controllers (mostly for routing purposes) stored as modules in the /controllers package.

We will add our routes and app creation function to /api/__init__.py. This way, we are able to use the create_app() function to create multiple app instances with different configurations. This is especially helpful when you are writing tests for your application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from flask import Flask, Blueprint
from flask_restful import Api

from config import config

def create_app(env):
  app = Flask(__name__)
  app.config.from_object(config[env])

  api_bp = Blueprint('api', __name__)
  api = Api(api_bp)

  # Code for adding Flask RESTful resources goes here

  app.register_blueprint(api_bp, url_prefix="/api/v1")

    return app

From what you can see here, we have created a function create_app() which takes an env parameter. Ideally, env should be one of development, production, and testing. Using the value supplied for env, we will be loading specific configurations. This configuration information is stored in config.py as a dictionary of classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
class Config(object):
  DEBUG = True
  TESTING = False
  DATABASE_NAME = "papers"

class DevelopmentConfig(Config):
  SECRET_KEY = "S0m3S3cr3tK3y"

config = {
  'development': DevelopmentConfig,
  'testing': DevelopmentConfig,
  'production': DevelopmentConfig
}

For now we've specified only a few configuration parameters like the DEBUG parameter which tells Flask whether or not to run in debug mode. We have also specified the DATABASE_NAME parameter, which we shall be referencing in our models and a SECRET_KEY parameter for JWT Token generation. We have used the same settings for all the environments so far.

As you can see, we are using Flask Blueprint to version our API, just in case we need to change implementation of core functionality without affecting the user. We have also initialized api, a Flask-RESTful API object. Later on, I will show you how to add new API endpoints to our app using this object.

Next, we put the code for running the server into run.py in the root directory. We will be using Flask-Script to create extra CLI commands for our application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask_script import Manager

from api import create_app

app = create_app('development')

manager = Manager(app)

@manager.command
def migrate():
  # Migration script
  pass

if __name__ == '__main__':
  manager.run()

Here, we have used the flask_script.Manager class to abstract out the running of the server and enable us to add new commands for the CLI. migrate() will be used to automatically create all the tables required by our models. This is a simplified solution for now. If all is well, you should not have any errors.

Now, we can go to the command line and run python run.py runserver to run the server on the default port 5000.

Next Steps

Continue on to the next guide in this series learn about User Model and Authentication Controller.

8