<jupyter_start><jupyter_text>Flask--- Flask is a web framework for python, also termed as "microframework" because it doesnot provide any extra modules other than required for handling http request/response.  Starting new project - Idea/Analysis/Design- Name of project- Create a project workspace- Start working on project  Idea/Analysis/Design*Shows visualisation of weather of Nepal in web application* **Mindmap about what are crude parts of our project**![](../../images/jalbayu/jalbayu_mindmap.png)  Name**jalbayu**  Create a project workspace *first create a project directory inside samples directory*    mkdir -p ../Samples/jalbayu *we have blank directory*    ls ../Samples/jalbayu/ *create a new file inside jalbayu named __environment.yml__ with following content*```yamlname: jalbayudependencies:    - python    - flask``` **Create new environment for project**```sh change into project directory$ cd jalbayu create a new environment using environment.yml file$ conda env create activate environment$ source activate jalbayu list all installed packages$ conda list``` **Start using git from start**```sh initialize git repository$ git init check status$ git status add environment.yml file to repository$ git add environment.yml commit the changes$ git commit -m "initial commit" make sure, what we want are committed properly$ git status$ git log``` **Create a new spyder project**![](../../images/jalbayu/spyder_project.png) **gitignore**```sh vim is commandline editor for linux you can use notepad/notepadd++ or spyder If using vim then      press "i" to start editing and press "colon" ie ":" and then "wq" and enter to save and exit$ vim .gitignore``` *content of __.gitignore__*```gitignore.spyderproject``` *Now*```sh add .gitignore file$ git add .gitignore commit the changes$ git commit -m "added gitignore file"``` **Create a simple hello world app** *create a file named __app.py__ with following contents*```python -*- coding: utf-8 -*- import Flask from module "flask"from flask import Flask create a new web application objectapplication = Flask(__name__) add a new route  http://localhost:5000/@application.route('/')def index():     we are returning a html string    return "Hello World"if __name__ == '__main__':     run the application    application.run()``` **Run the application**```sh$ python app.py* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)```*Open browser with http://localhost:5000* **Templates***using templates for html page instead of just passing them as html string*__app.py__```python -*- coding: utf-8 -*- import Flask from module "flask"from flask import Flask, render_template create a new web application objectapplication = Flask(__name__) add a new route  http://localhost:5000/@application.route('/')def index():     render templates searches given template file inside templates/ directory     and renders that template as html    return render_template('hello.html')if __name__ == '__main__':    application.run()``` **Create a templates directory**    $ mkdir -p templates*Create a file named __hello.html__ inside __templates__ with contents as*```html            Hello World                    Hello World    ``` **Restarting the server***Hit Ctrl+C on terminal/prompt where our application is running, and rerun the server as*```sh$ python app.py* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)``` **Reloading the server without restarting it manually***Enable debug mode, __app.py__*```python...if __name__ == '__main__':     enable debug mode     with this enabled we can view errors on browser      and server will automatically reload on every changes on python code    application.run(debug=True)``` *Restart the server again, this time it will be on debug mode* **templates/login.html**```html        Login              Email            Password        Login``` __app.py__```python... methods=['GET', 'POST'] means we are accepting both Request <EMAIL>('/login', methods=['GET', 'POST'])def login():    if request.method == 'POST':         if we get POST data, ie someone submitted the login form         just print what we obtained from browser        print("Posted data", request.form)     after everything is done show login form, or show form if this is GET request    return render_template('login.html')...``` ![](../../images/jalbayu/login_plain_html.png) **templates/login.html**```html                      JalBayu - Login Page                                                                                        Login              Email            Password        Login                                 -->      ``` *- Note that we have also used [bootstrap](http://getbootstrap.com), a css framework. Infact this whole base template is copied from bootstrap template example snippet.*  Jinja2Jinja2 is template language used with Flask and other python frameworks```html{{ some_variable }} prints the value of some_variable{{ 2 + 5 }} is evaluated and prints the result.{% block section %}{% endblock %}{% for i in some_list %}{{ i }}{% endfor %}{% if some_value %}This is inside if{% else %}This is inside else{% endif %}``` **Template Inheritence**We will create a single template for every repeated block of html code, for eg. headers, footers etc.__base.html__```html                      JalBayu - {% block title %}{% endblock %}                                                    {% block main %}{% endblock %}             -->      ``` *Lets update our __hello.html__ to use this base template, with contents as*```html{% extends 'base.html' %}{% block title %}Hello {{ name }}{% endblock %}{% block main %}Hello {{ name }}{% endblock %}```In Above- __extends__ means we are using __base.html__ template as our parent template- whatever we write inside __{% block title %}__ and __{% endblock %}__ in __hello.py__ template will be overwritten inside blocks of same name of parent ( in this case __base.html__ file).- i.e    - When we load __hello.html__ file from view, it will first load __base.html__, apply every block from __hello.html__ in this case, __{% block title %}__ and __{% block main %}__ and return whole result **Let's update login page** __templates/login.html__```html{% extends "base.html" %}{% block title %}Login Page{% endblock %}    {% block main %}                    Login                                            Email                                                        Password                                                  Login                    {% endblock %}``` *Restart the app, and visit http://localhost:5000/login in your browser*![login page](../../images/jalbayu/screenshot_login.png)  Authentication and Authorizationwe will use __flask_login__ module for authentication and basic authorization.- __Authentication__ means checking if user is known to us or not, unknown user are _guests_ who visits our public pages, while known users are those who are registered to our application and are logged in and may has profile page.- __Authorization__ means finding out if any user are allowed to do a certain task. For eg. _guest_ user are only allowed to view public pages, _authenticated_ ( logged in ) users are allowed to make some changes on their page and _admin_ user are allowed to do everything including deleting other users.  *change __environment.yml__ and update system*__environment.yml__```yamlname: jalbayudependencies:    - python    - flask    - pip:        - flask_login```*Note that we have put __flask_login__ inside __pip__, this means __pip__ ( the package manager that comes with python ) will be used to install the package since it is not available with __conda__*Now run following command```sh$ conda env update```*This will update current environment, ie looks into yaml file, install/update everything that was add/changed recently* __app.py__```python...from flask_login import LoginManager, login_user, login_required, logout_user...login_manager = LoginManager()login_manager.init_app(application)...class User:    """    This is main user class used by login manager to identify users    """         this will be list of all users who are allowed to login to our application    users = ({        'username': '<EMAIL>',        'password': '<PASSWORD>'              },)    authenticated = False         this attribute will be populated when user will be authenticated    user = {}        def is_authenticated(self):        """        if user is authenticated or not        """        return self.authenticated        def is_active(self):        """        if user is active or not        being active means, user has not be disabled/deactivated/blocked by us or by him/herself        """        return True        def is_anonymous(self):        return False        def get_id(self):        """        return identifier for the user, identifier should be unique to each user        here we are using username of user        """        if self.is_authenticated():            return self.user['username']        return None        @staticmethod    def user_exists(email, password):        """        check if user exists in our list of users with given username and password        """        user_dct = [dct for dct in User.users if dct['username'] == email                     and dct['password'] == password]        print("found user", user_dct)        if user_dct:            user.user = user_dct[0]            user.authenticated = True            return user        return None@login_manager.user_loaderdef load_user(user_id):    """    this is used by login manager object to load user object from user_id    user_id is obtained from session on consecutive requests    """    user_dct = [dct for dct in User.users if dct['username'] == user_id]    user.user = user_dct[0]    return user...@application.route('/login', methods=['GET', 'POST'])def login():    if request.method == 'POST':         save this data to db or do something        print("Posted data", request.form)         check if requested user is in our database         the email and password keys are values of "name" attributes in html form see: login.html         user = User.user_exists(request.form['email'], request.form['password'])        if user:             mark this user as loggedin            login_user(user)            print("logged in")        else:            print("Unable to login")    return render_template('login.html')@application.route('/logout')def logout():     unmark this user as loggedin    logout_user()     redirect to index page    return redirect('/') this page will be accessible as http://localhost:5000/data/add login_required makes sure that this page is accessible to those who have login credentials and logs in@application.route('/data/add', methods=['GET', 'POST'])@login_requireddef add_data():    if request.method == 'POST':         we wont do anything here now        pass            return render_template('data_add.html')...```__templates/data_add.html__```html{% extends 'base.html' %}{% block main %}We will show add form here{% endblock %}``` *Restart application**Visit http://localhost:5000/data/add, you should see something like this*![unauth](../../images/jalbayu/screenshot_unauth.png)This is because __@login_required__ part becomes active here for __/data/add__ route, we have not logged in yet so.- Visit http://localhost:5000/login and use __<EMAIL>__ as username and __<PASSWORD>__ as password and click login.- Now visit http://localhost:5000/data/add, you should see something like this![auth](../../images/jalbayu/screenshot_auth.png)*Note: If you are still getting unauthorized page, make sure you are logged in, see terminal/cmd prompt for login message*  DatabasesStoring user data inside python dictionary is not very nice, so we will use a database.- Database can be considered a type of datastructure/storage where we keep our data in a specific format.- Generally they can be viewed as tabular format **Lets create a database***we will be using sqlite, since we wont have to install anything to use it. Later this can be implemented using either MySQL or PostgreSQL as well with little changes.*<jupyter_code># import sqlite package
import sqlite3
# create a database, in case of sqlite it is a file
conn = sqlite3.connect('../Samples/jalbayu/data/db.sqlite3')
# create a cursor object
cur = conn.cursor()
# Now we will create required tables ie user table with columns id, username and password
cur.execute("""
CREATE TABLE user (
    id INTEGER NOT NULL,
    username VARCHAR(32),
    password VARCHAR(60),
    PRIMARY KEY (id),
    UNIQUE (username)
)
""")
# commit what we have done till now to disk
conn.commit()<jupyter_output><empty_output><jupyter_text>*Database is similar to Excel Document (if you have used one previously), Tables are as __Sheet__ of Excel and columns are well __Columns__ of a particular Sheet.*<jupyter_code># list out all the data from user table
cur.execute("SELECT * FROM user")
cur.fetchall()<jupyter_output><empty_output><jupyter_text>we dont have anything added to database yet<jupyter_code># now add two users to our user table
cur.execute("INSERT INTO user(id, username, password) VALUES(1, '<EMAIL>', '<PASSWORD>')")
cur.execute("INSERT INTO user(id, username, password) VALUES(2, '<EMAIL>', '<PASSWORD>')")
conn.commit()
# now check if our data have been actually inserted to db
cur.execute("SELECT * FROM user")
cur.fetchall()
# let's close connection to db
# we dont want it to be open all the time
conn.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09724485261442749, 'fraction_numerical': 0.005110354021626426, 'mean_word_length': 3.351595230422172, 'pattern_counts': {'":': 1, '<': 22, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '473004', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 3510, 'n_tokens_neox': 3300, 'n_words': 1522, 'path': 'Python/References/Flask.ipynb', 'repo_name': 'JahBirShakya/pysessions', 'size': '13535'}