[Memo for Flask] An amateur who does not understand HTML or Web construction tries to create a Web service with Python + Flask

This is a weekend engineer by an inexperienced throat amateur This is a memo article for creating a web application with Python and Flask.

Landing page [Flask] This page [Docker] Coming Soon… [Web development] http://qiita.com/yuusei/items/cf738b0849fc932a64e6

This page is the main page of Flask edition, The contents used for implementation, such as how to use modules and classes, are mainly based on Flask official Japanese site. This site has Github code "flaskr.py" that allows you to create one service just by copying and pasting. Then, especially in Tutorial, a microblog (a simple blog with only the title and body. Twitter Tweet) whose sample code is published. It's like reading the code (which has a title for each one) and organizing what you can understand.

Note that the smallest web app you can make with Flask has a “Hello World” app with only 9 lines. You can do it right away with a copy, so please give it a try.

Flask basic knowledge memo

・ What is Flask? A micro-framework for web development ・ A framework is like a "toy box" ・ "Toys" included in the consulting framework are strategic systems such as "SWOT analysis". -The "toys" included in the framework for web creators are libraries in which many people wrote code. ・ Web frameworks exist for each development language, just as consulting frameworks differ depending on the company or industry. -For Python, "Django" is the mainstream. It's an All in One framework that can handle medium-sized ones. -Even with the same Python web framework, "Flask" is "programming language-like" for "small-scale development purposes" compared to "Django".

List of minimum required modules in Flask

“Flask” module ・ No explanation required. A module that enables you to use Flask. -Strictly speaking, Flask can be used by importing the classes "Flask" and "request" of this "flask" module.

only this. It seems that you can make a minimum web application with just this "flask". Reference: The smallest web app you can make with Flask

But, well, there are two more modules needed to create a microblogging app at Tutorial. "Os" module -A module that reproduces the functions of a general OS. -You can use Unix-like commands that are typed into the command prompt for Windows OS and Terminal for Mac OS. ・ Although it may not be complete, the main ones are listed.

“Sqlite3” module -A module for connecting to and operating a DB. -When a web service is released, it will be necessary to register the user ID and attributes in RDB format. It. -As the name suggests, you can perform the same operations as using SQLlite. -It is not necessary to use this as a separate SQL or DB connection application. I just use this in the Tutorial.

(I don't care, but when I was writing this article, I heard a conversation saying "I thought I couldn't write SQL for this guy", and I was shocked for a moment.)

Then, make full use of the classes in these modules to create a microblogging application.

List of module class library objects other than Flask stored in the flask module (used in Tutorial)

“Flask” -A class for using Flask. -For making a declaration to create an application. ・ Used with app = Flask (name) etc.

“request” -Command library for handling HTML installed in Python ・ It seems that it was created because urllib is difficult to understand

“session” -It seems to be for managing log-in and log-out.

“g” -An object that stores Flask original DB connections -Once you save the connection format, you can use it from another function.

“redirect” -[HTTP redirect](http://e-words.jp/w/HTTP redirect.html) ・ Notice of URL change

“url_for” -For generating URLs. -It seems that it can also be used for Dynamic URL generation. It seems to be just right for creating my page for new users.

“abort” -Report an error to the client (?) -Used to display so-called client error

“render_template” -For calling the required template from Template and rendering = reading the program code as an image ・ I wondered if it would be fetched from Jinja2 here.

“flash” -How to display Flash and deliver characters / images to the client

Such a place. This completes flaskr.py for flaskr itself.

Directory structure

In the directory structure memo of the Web service of Web Development,

・ There is no optimal structure. There is only Root Directory (/)

I wrote that, but that alone is too wild, so Flask makes the directory structure like this.

-Folder storage "/ flaskr" folder for storing main module and database schema -Place CSS and JS directly under the "flask" folder, and have the user use the folder "/ static". -Similarly, a folder "/ templates" for searching Jinja2 templates directly under "flaskr"

There are three. In addition, including the necessary files The directory structure is as follows.

Flaskr_DirectryTree.png

About database design (schema)

Only one table is required for the microblogging app featured in Tutorial.

Comment inline in Tutorial Database Schema Creation Command.

drop table if exists entries;

If there is already a table named "entries", delete it

#Manners for creating a new table create table entries ( Declaration to create a table called "entries" with the contents written in # {}; id integer primary key autoincrement, #column ”id” Used as an integer type primary key (automatic numbering) title string not null, #define column "title" as a string. Null value is not possible text string not null # Define column "text" as a string. Null value is not possible );

Looking at the completed UI of this service first, it looks like the following.

flaskr_top_image.png

If you enter the title and text here, the id will be assigned by automatic numbering, and then You can see that the post is reflected.

For example, if you want to extend this screen to reflect the posting date, Put a sentence in the above schema in advance and prepare an autoincrement date field in the table.

This schema is stored as a "schema.sql" file directly under the flaskr directory.

Explanation for each part of the main body "flaskr.py"

The setting file of the application is put in the same hierarchy (directly under flaskr) as flaskr.py. In the same way, add comments inline.

App declaration and config

""" create our little application :)""" app = Flask(name) #Create an instance (WSGI this time) with the name "name" from the imported Flask class

When using as a single module, set it to "name" so as not to interfere with "main" of the import destination main unit.

# Load default config and override config from an environment variable app.config.update(dict( #Declare that the config of the application is defined by the dictionary method DATABASE = os.path.join (app.root_path,'flaskr.db'), #DB uses the root path "flaskr.db" DEBUG = True, # Debug SECRET_KEY ='development key', #Key to keep client-side sessions secure USERNAME ='admin', # Name to enter with administrator privileges PASSWORD ='default' #PW to enter with administrator privileges )) app.config.from_envvar('FLASKR_SETTINGS', silent=True) Code to refer to when #config is saved in a separate file Don't pass anything that isn't set with # silent = True to Flask.

This completes the settings. Next, the command to connect to the DB

DB connection and initialization

def connect_db(): Define the function to connect to #DB as "connect_db" #Connect, change the format with data to tuple-> dict, and return dict type row as rv """Connects to the specific database.""" rv = sqlite3.connect (app.config ['DATABASE']) Connect to the DB set in # app.config rv.row_factory = sqlite3.Row # row can be held in dict format instead of tuple return rv

Use this predefined "connect_db" function to define "init_db" which initializes the DB once before a new connection.

def init_db(): """Initializes the database.""" db = get_db () Store database as variable in #db with app.open_resource ('schema.sql', mode ='r') as f: # Store schema in "f" in read-only mode Use db.cursor (). executescript (f.read ()) # f.read () as sql and save as cursor commit to db.commit () #db-> initialized

Please refer to Click here for SQL cursor. The cursor seems to be a function that allows you to process data line by line on SQL. However, reading the explanation about cursor of spliete3 Simply cursor () instead of SQL Select statement. I feel like I'm using executescript. By the way, in order to use this init_db () function in CUI, the following device is required.

@ app.cli.command ('initdb') # Add new command "initdb" to command line interface def initdb_command (): Type # initdb to call the init_db () function and get "initialized" """Creates the database tables.""" init_db() print('Initialized the database.')

Now you have an environment to initialize the DB from CUI (is it convenient to have a test environment?). And, in the first place, I have not defined a function to connect to DB, so I will define it.

def get_db(): """Opens a new database connection if there is none yet for the current application context. """ if not hasattr(g, 'sqlite_db'): g.sqlite_db = connect_db() return g.sqlite_db

When this function connects to the DB for the first time, it saves the settings and performs the work of "connecting to the DB for each request". For example, I refer to this area. And we define disconnection below by saying that we have to disconnect once we connect.

@app.teardown_appcontext def close_db(error): """Closes the database again at the end of the request.""" if hasattr(g, 'sqlite_db'): g.sqlite_db.close()

It doesn't matter, but at first I didn't know what this hasattr was, but it looks like a python built in function.

The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.) from Python-Official

It is used by hasattr (object, name) and seems to return True if name is included in object. In this case, if sqlite_db is open (has been connected), it seems to be closed by g.sqlite_db.close (). Initdb for get_db () and close_db () is the end of db related processing.

View function / login / logout

Next, define four view functions to display the contents of the DB (posted contents) on the screen of the application. "View (all) entries", "Add new entry", "Login" and "Logout" respectively.

Then one by one ... I'll finish it quickly.

(All) Entry display

@app.route('/') def show_entries(): db = get_db() cur = db.execute('select title, text from entries order by id desc') entries = cur.fetchall() return render_template('show_entries.html', entries=entries)

What you want to see here is “cur = db.execute ('select title, text from entries order by id desc’)”. If you understand SQL, you can easily understand it, but this command () contains SQL. So I am executing sql to db with execute (“SQL statement”).

select title , text from entries order by id desc

Maybe it has something to do with the cursor statement I wrote a while ago (db.cursor (). executescript (f.read ())). In any case, this is rewritten and the element fetched by "fetchall ()" is rendered by "render_template". Rendering rules are defined in "show_entries.html". As an extended version, if you want to retrieve the date, you need to add "date" to the DB schema and the above SQL and rewrite "show_entries.html" to display the date.

Add new entry

@app.route('/add', methods=['POST']) def add_entry(): if not session.get('logged_in'): abort(401) db = get_db() db.execute('insert into entries (title, text) values (?, ?)', [request.form['title'], request.form['text']]) db.commit() flash('New entry was successfully posted') return redirect(url_for('show_entries'))

As a function, the following flow is defined as the add_entry () function.

"Return 401 if not logged in" -> "Connect to DB if logged in" -> "Execute the command to enter" title "and" text "as new entries in the connected DB" -> "Commit () to confirm processing" -> "Flash display that entry has been posted" -> "Reload the browser and call" show_entries "to redisplay everything"

is.

Login

@app.route('/login', methods=['GET', 'POST']) def login(): error = None if request.method == 'POST': if request.form['username'] != app.config['USERNAME']: error = 'Invalid username' elif request.form['password'] != app.config['PASSWORD']: error = 'Invalid password' else: session['logged_in'] = True flash('You were logged in') return redirect(url_for('show_entries')) return render_template('login.html', error=error)

As a function, the following flow is defined as a login () function.

"No error handling" -> "Check if POST is requested" -> "Check if user name is in existing user list (return error if not)" -> "Check if PW is in existing PW (return error if not)" -> "Set login session to True" -> "Flash login success" -> "Reload the browser and call" show_entries "to redisplay everything" (-> When error handling is not None, the screen at login error is rendered from the template)

is.

Log out

@app.route('/logout') def logout(): session.pop('logged_in', None) flash('You were logged out') return redirect(url_for('show_entries'))

As a function, the following flow is defined as a logout () function.

"Return logged_in to None" -> "Show" logged out "in flash" -> "Reload the browser and call" show_entries "to redisplay everything"

is. Surprisingly easy.

This covers the contents of flaskr.py. The rest is about HTML, so instead of writing it here I will put a link to the HTML and CSS frame in Web Development.

Continue···

Other web frameworks Simple notes ・ For Ruby, "Ruby on Rails". The speed of development is selling ・ For PHP, "CakePHP". Looking at the world, it seems that "the most web apps have been introduced" -For Java, "Spring" or "Play". It seems that it is a phase of selection from the group male division -For JavaScript, "AngularJS". It seems that it is suitable for application development that can be completed with one piece. Is it a slide story? -For CSS / JS, "Bootstrap". It seems that Twitter provides

Recommended Posts

[Memo for Flask] An amateur who does not understand HTML or Web construction tries to create a Web service with Python + Flask
Create a web service with Docker + Flask
I created an environment for Masonite, a Python web framework similar to Laravel, with Docker!
How to create a heatmap with an arbitrary domain in Python
Create a tool to automatically furigana with html using Mecab from Python3
[GCP] Procedure for creating a web application with Cloud Functions (Python + Flask)
An introduction to self-made Python web applications for a sluggish third-year web engineer
Memo to ask for KPI with python
Create a simple web app with flask
[Python] Quickly create an API with Flask
Let's make an A to B conversion web application with Flask! From scratch ...
[ES Lab] I tried to develop a WEB application with Python and Flask ②
Searching for an efficient way to write a Dockerfile in Python with poetry
[Python] How to create a local web server environment with SimpleHTTPServer and CGIHTTPServer
Create a LINE BOT with Minette for Python
Steps to create a Twitter bot with python
Launch a web server with Python and Flask
A python amateur tries to summarize the list ②
Environment construction for those who want to study python easily with VS Code (for Mac)
Create an animated GIF local server with Python + Flask
Memo to create your own Box with Pepper's Python
A memo connected to HiveServer2 of EMR with python
Why not create a stylish table easily with Python?
[Python] A memo to write CSV vertically with Pandas
Create a Layer for AWS Lambda Python with Docker
For those who want to write Python with vim
[Python] How to create a 2D histogram with Matplotlib
Environment construction procedure for those who are not familiar with the python version control system
Continued [Python] Let's automatically translate English PDF (but not limited to) with DeepL or Google Translate to make a text file, no HTML.