Create a login page in Python with flask and/or gunicorn   💻 🐍 
Tags: python, flask, gunicorn, login
Published: 2022-02-05 18:59:48

In this post I will show you how to create a simple login page in Python with the flask library and finally with gunicorn.

let's begin!

Create the virtual env:

in the project directory :

`python3 -m venv myenv`


Then the linux command to activate the new env:
`source /myenv/bin/activate`

Now we are in our dev env.

From here install the flask library :


`pip install flask`


Now we can start to develop our flask app.

Create a file that you can call `mylogin.py`

In this file :

```
#!/usr/bin/env python3

from flask import Flask, render_template, redirect, url_for, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] == 'Admin' and request.form['password'] == 'Admin1234$':
            return render_template("adminpage.html")
        elif request.form['username'] == 'User' and request.form['password'] == 'User1234$':
            return render_template("adminpage.html")
        else:
            return 'Invalid login or password, please try again'

    return render_template('login.html', error=error)


if __name__=='__main__':
    app.run(host='0.0.0.0')
```

We have created two users :

name: **Admin**
password : **Admin1234$'**
        
and 

name: **User**
password: **User1234$**



`mkdir templates`

in templates, we will create 3 files :

adminpage.html  login.html  userpage.html


`login.html `

```
<html>
<head>
<title>Login page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <div class="container">
        <h1>Please login</h1>
        <br>
        <form action="" method="post">
            <input type="text" placeholder="Username" name="username" value="{{  request.form.username }}">
            <input type="password" placeholder="Password" name="password" value="{{  request.form.password  }}">
            <input class="btn btn-default" type="submit" value="Login">
        </form>
        {% if error %}
            <p class="error"><strong>Error:</stong>  {{  error }}
        {% endif %}
    </div>
</body>
</html>

```

`adminpage.html`

```
<h1>This is the admin private page</h1>
```

`userpage.html`

```
<h1>>This is the user private page</h1>
```

Now you can test it with flask:

`python mylogin.py`


The app is running...


```
 * Serving Flask app 'mylogin' (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://YOUR.IP:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 521-493-757
```

Now open a web browser and connect to your ip : http://YOUR.IP:5000/

If you have a firewall installed, the port 5000 must be open.

You can now try to login with the admin the with the user account.

Now we can make it run for production with gunicorn :

install gunincorn:

`pip install gunicorn`

in the main directory, we need to create a file called :

`wsgi.py`

```
from mylogin import app

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

```

Here mylogin is our mylogin.py Python/Flask app.

Now we can run it with gunicorn :


`gunicorn --bind 0.0.0.0:5000 wsgi:app`

It's running well...

```
[2022-02-05 19:51:48 +0100] [6545] [INFO] Starting gunicorn 20.1.0
[2022-02-05 19:51:48 +0100] [6545] [INFO] Listening at: http://0.0.0.0:5000 (6545)
[2022-02-05 19:51:48 +0100] [6545] [INFO] Using worker: sync
[2022-02-05 19:51:48 +0100] [6546] [INFO] Booting worker with pid: 6546
```

Open again your web browser at the same address and it's running.

The project directory is like this :

`----Project-Directory->    
           |    
           |    
           --mylogin.py    
           --wsgi.py    
           |     
           |     
            ----Project-Directory->----templates->     
                 |     
                 |    
                 --login.html    
                 --userpage.html    
                 --adminpage.html`     


Finally the library requirements in this project :

requirements.txt

`click==8.0.3
Flask==2.0.2
gunicorn==20.1.0
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
Werkzeug==2.0.2`



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/he3ao48k5i52kkthozgk.jpg)