Python Website Full Tutorial — Flask, Authentication, Databases

As a beginner in web development, I knew that understanding databases and SQL would be crucial to building robust web applications. I started my journey by learning the basics of SQL and relational databases, practicing with various exercises and projects.

After gaining some experience, I decided to focus on MySQL. I was excited to apply my new skills to future projects.

At the end you will able to create it from sctrach.

A slight demo what you will learn to built.

Creating a basic Flask app

i. To get started with Flask, you first need to install it. You can do this using pip, the Python package installer, by running the following command in your terminal:

pip install flask

ii. Create a Flask app file Next, create a new Python file for your Flask app. This file will contain the code for your Flask app. You can name this file whatever you want, but for this example, we’ll name it app.py.

iii. Import Flask In your app.py file, import the Flask module using the following code:

from flask import Flask

iv. Create an instance of the Flask class Create an instance of the Flask class by calling the Flask constructor and passing in the name of your app. This code should be added to your app.py file:

app = Flask(__name__)

v. Create a route by defining a function and adding the @app.route() decorator above it. The decorator tells Flask what URL should trigger the func. For example, the following code defines a route for the root URL /:

@app.route('/')
def index():
return 'Hello, World!'

vi. Run the app Finally, run the app by calling the run() method on your app instance. This code should also be added to your app.py file:

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

And that’s it! You now have a basic Flask app up and running. Of course, we will customize app further by adding more routes, templates, and views.

Now we will start actual implementation of project.

It is important to use a different environment for Flask installation because it helps in keeping your system clean and organized. Flask, like any other application, has dependencies that need to be installed to make it run properly.

Overall, using a separate environment for Flask installation helps in making the development process smoother and more efficient by keeping the dependencies required by Flask isolated and easy to manage.

This is how our project structure will look create such

File descriptions:-
Flask web application is dir where our project is present

Website is name of application
— static (folder to save all static files)
— templates(will contains all html boiler plates)
— __init__.py(file where flask app is created and use as package)
— auth.py (file will have all authentication content)
— models.py (file will have database releated query and settings)
— views.py (file will generate webpage on searching url)

main.py (present outside this is starting point of our application which uses all content of __init__.py

Creating routes/views

In Flask, a route refers to a URL pattern that maps to a function in your Python code. When a user requests a URL, Flask uses the route to determine which function to call to handle the request and generate a response.

In above example we set http://localhost:5000/ in their browser, Flask will call the index() function and return the string "Hello, World!" as the response.

__init__.py
When http://127.0.0.1:5000/ url is searched in browser user will get Test as output.
route set for authentication file.
main.py file

Routes are a fundamental part of building Flask applications, as they allow you to define the URLs that your users will interact with and map them to the appropriate code to handle the requests. By understanding how routes work in Flask, you can build more complex and powerful web applications that respond to user input in a dynamic and flexible way.

Jinja templating language and HTML templates

When building a web application, it’s common to have a consistent layout for all pages. Rather than repeating the same HTML code for every page, we can use a templating engine to create a base template with reusable components. In Flask, the templating engine of choice is Jinja2.

Jinja2 is a modern and designer-friendly templating language for Python, modelled after Django’s templates. It is used to generate HTML or XML pages that can be served to clients. It is widely used in web frameworks such as Flask, Django.

In this template, we define a block named “title” that can be overridden by child templates. We also define a navigation bar with links to the Home, Login, and Sign Up pages. We then define another block named “content” that child templates can use to insert their specific content.

To create a child template that extends this base template, we use the
{% extends %} tag at the top of the file. We can then override the “title” and “content” blocks as needed.

This is base.html file which has navbar & basic structure for web app
login.html,home.html,sing_up.html are shown above are child templates inherenting parent base.html. auth.py,views.py are file serving the templates with help of route
Using Jinja this is how our pages are looking.

You should try to customize the template as per your choice. To get better understanding of them.

Handling HTTP requests (POST, GET)

The main difference between the GET and POST methods is that GET requests are used to retrieve data, while POST requests are used to send data. The data sent using the POST method is usually hidden from the user and is not visible in the URL.

In Flask, the request object is used to handle incoming HTTP requests from the client. It contains all the data that the client sends to the server, including form data, cookies, and headers.

It’s important to note that when using the request object, we should always check the method of the request using request.method to make sure we're handling the correct type of request. Additionally, we should always validate any user input and sanitize any data that will be stored in the database to prevent security vulnerabilities such as SQL injection.

sing_up.html, login.html, auth.py uses here http request method to give different output for different request

Implementing message flashing

In Flask, flash is a built-in function that allows you to display a message to the user when a certain event occurs, such as a successful login or an error in form submission. The flash function stores the message in a temporary session that is available to the next request. It is useful in situations where you want to provide feedback to the user after an action has been performed.

Demo of Flash message in flask.

In the case of the auth.py file, the flash function is being used to verify if the user has entered valid input for the email, first name, and passwords fields. If the input is invalid, an error message is flashed to the user. These messages are then displayed on the page using the get_flashed_messages function in the base.html template.

auth.py is verifying the user feedback on sing-up route. We are giving feedback to user i.e. frontend part should be present in template we used base.html means parent file

The get_flashed_messages function retrieves all the flashed messages, which are then looped over in the template using a for loop. The category of each message is checked (e.g. error or success) and a corresponding HTML element with the appropriate CSS classes is rendered. The message itself is then displayed within the element.

Overall, using flash messages in Flask is an effective way to provide feedback to the user and improve the user experience. It allows you to communicate important information to the user without cluttering the page or interrupting the user flow.

Setting up Flask SQLAlchemy

In a Flask web application, you can use SQLAlchemy to interact with databases. You can define a model class that represents a table in your database and use the Object-Relational Mapping (ORM) to insert, update, delete, and query the data in that table.

To use SQLAlchemy, you will first need to install it using pip. You can do this by running the following command in your terminal or command prompt:

pip install sqlalchemy

In this example, we define a User class that inherits from db.Model, which is a SQLAlchemy base class. We define several columns in the class, each of which maps to a column in the database table. The id column is a primary key, which is required for each table. The email column is unique and cannot be null, while the password, first_namecolumns are also required.

__init__.py define our SQLAlchemy instance and create our models. Finally, we create the database tables. models.py wedefine a User class that inherits from db.Model, which is a SQLAlchemy base class

To create the database, you will need to call the create_all() method on your SQLAlchemy instance and pass in your Flask app instance.

Creating database models and foreign key relationships

When designing a database in SQLAlchemy, it is important to create the appropriate models and establish relationships between them. In our case, we want to create a database for storing user details and user-generated notes. Here’s an example of how you might set up your database models:

modes.py is showing the relationship between tables . __init__.py is creating instance for tables.

The Note model has columns for id, userNote, date, and user_id. The id column is the primary key for the Note model, and is used to uniquely identify each note. The userNote column stores the actual text of the note. The date column is used to store the date and time when the note was created, and is set to the current time by default. The user_id column is the foreign key for the User model, and is used to establish many to one relationship between the Note and User models.

The User model has columns for id, email, password, and first_name. The id column is the primary key for the User model, and is used to uniquely identify each user. The email column stores the user's email address, and is set to be unique so that each user has a unique email. The password column stores the user's password. The first_name column stores the user's first name.

The notes attribute in the User model is used to create a one-to-many relationship between the User and Note models. This means that each user can have many notes. The notes attribute is created using the relationship function from SQLAlchemy. The first argument to relationship is the name of the related model (Note in this case).

Run this command python main.py and see an instance for database is created with name as database.db

Creating and logging in user accounts

Demo for authentication

In Flask, creating new user accounts and logging in users is an essential part of building web applications. The process involves capturing user information through a web form, validating the data, storing the data in a database, and providing access to protected content for authenticated users.

In auth.py Flask route at ‘/sign-up’ and accepts GET and POST requests. The ‘GET’ request displays a sign-up form, while the ‘POST’ request processes the form data and creates a new user account.

The login() function handles both GET and POST requests sent to the /login route. If the request method is POST, the email and password are extracted from the request's form data. The user's email is then used to search the database for a matching user record using the User.query.filter_by(email=email).first() method. If a user with the given email is found, the hashed password is checked against the provided password using the check_password_hash function. If the passwords match, a success message is flashed and the user is redirected to the home page using the redirect(url_for('views.home')) function. If the passwords do not match, an error message is flashed. If the email is not found in the database, an error message is flashed.

The sign_up() function also handles both GET and POST requests sent to the /sign-up route. If the request method is POST, the email, first name, and passwords are extracted from the request's form data. The email is used to search the database for a matching user record using the User.query.filter_by(email=email).first() method.

If a user with the given email already exists, an error message is flashed. Otherwise, a new user record is created with the email, first name, and hashed password using the generate_password_hash function. If all the checks pass, a new user is created with the User model and the generate_password_hash() function from Flask-Bcrypt to hash the password for secure storage. The new user is then added to the database using db.session.add() and committed using db.session.commit().

If the new user is successfully added to the database, a success message is flashed and the user is redirected to the homepage using the redirect() function from Flask.

Overall, the code provides a basic implementation of user authentication functionalities in Flask.

Adding and deleting user notes

So far we have created authentication system for user with valid email and password only can create notes. This is how home or index page looks for login in or singup users. Where he can create notes adding nodes in db is explained next.

home.html is jinja template, auth.py handles routing for url, views.py handles routing of index page

Adding notes in db is “post” method so we handling it in our home function that is mapped to the root URL path (‘/’). The function is decorated with @views.route”, which is a Flask decorator that maps the function to the specified URL path. Another decorator “@login_required” is used to ensure that only logged-in users can access the homepage; otherwise, they will be redirected to the login page

The function first checks the request method to see if it is a GET or POST request. If it is a POST request, the function gets the “note” from the form and checks if it is at least one character long. If it is not, it flashes an error message. If the note is valid, it creates a new note object and adds it to the database.

The function then returns the rendered “home.html” template and passes the current user as an argument. The template displays the user’s notes and provides a form for adding new notes. If the user is not logged in, they will be redirected to the login page.

Demo for adding and deleting

Now we will check how to display all notes made by user and how to code for delete operation.

views.py here we created route for delete, base.html added script for delete onclick opertaion, home.html here all notes are visible.

In ‘base.html’ JavaScript function deleteNote that is called when a user clicks a delete button to remove a note. When the function is called, it sends a POST request to the server with the noteId of the note to delete as the request body, using the fetch function. If the request is successful, it reloads the page to display the updated list of notes.

The flask decorator that handles the POST request from the deleteNote function. When a request is received, it loads the request data using the json.loads() function and extracts the noteId from the data. It then queries the database for the note with the matching noteId and checks if the current user is the owner of the note. If the note exists and belongs to the current user, it deletes the note from the database and commits the change. Finally, it returns a JSON response with an empty object to acknowledge the successful deletion.

As further learning you can add this flask application in your website to get better insights!..

You can also check my other’s blog below.

--

--

KunalD

A curious mind exploring the possibilities of machine learning & deep learning. Join me on a journey of discovery through beginner-friendly to advanced topics."