Using Flask - A step by step...

Preview:

Citation preview

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Using FlaskA step by step demonstration

Devert Alexandre

January 5, 2013 — Slide 1/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Table of Contents

1 Introduction

2 Starting minimal

3 Database integration

4 User’s links

5 Posting links

6 Ordering the links

Devert Alexandre — Using Flask — Slide 2/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Objective

• Using Flask on a real application

• Showing how SQLAlchemy and Flask works together

• Demonstrating the power of a modern web applicationframework

Devert Alexandre — Using Flask — Slide 3/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Study case : LINKY

We will build LINKY, a social website

• Users can post links about they read on the web

• Users can see what are the lastest posted links

• Can see links of their friends, per category, etc.

Don’t laught : 10 years ago, it was the future . . .

Devert Alexandre — Using Flask — Slide 4/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Table of Contents

1 Introduction

2 Starting minimal

3 Database integration

4 User’s links

5 Posting links

6 Ordering the links

Devert Alexandre — Using Flask — Slide 5/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Objective

Objective of this step

Starting with a minimal but working and extensible code base

Devert Alexandre — Using Flask — Slide 6/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The file hiearchy

The file hierarchy

|− run . py||− s t a t i c| || |− base . c s s||− t emp l a t e s

||− base . html|− i n d e x . html

Devert Alexandre — Using Flask — Slide 7/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

run.py

run.py is the script to use for starting our wep application

from f l a s k impor t F lask , r e n d e r t emp l a t eapp = F l a s k ( name )

@app . r ou t e ( ’ / ’ )d e f i nd e x ( ) :

r e t u r n r e n d e r t emp l a t e ( ’ i nd e x . html ’ )

i f name == ’ ma i n ’ :app . run ( debug = True )

• Instanciate the Flask application object

• The root URL serves a single page, index.html

• We run in debug mode

Devert Alexandre — Using Flask — Slide 8/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

index.html

index.html is the welcome page for our website

{% extend s ” base . html ” %}

{% block con t en t %}<d i v c l a s s = ” s e c t i o n ”>

<h2>What i s i t ?</h2><p>L inky i s a web s i t e to sha r e l i n k s between f r i e n d s . Funny , amazing ,r e v o l t i n g , o r i n s p i r i n g , s ha r e them a l l ! Ju s t copy−pa s t e a l i n k , put acomment , and t h e r e you go , a l l your f r i e n d s w i l l s e e i t .</p>

</ d i v>

<d i v c l a s s = ” s e c t i o n ”><h2>How i t works ?</h2><p>Reg i s t e r , f o r f r e e , to ge t an account . Once l ogged in , you w i l l s e e themost popu l a r l i n k s . Add f r i e n d s , and you w i l l s e e t h e i r l i n k s too .</p>

</ d i v>{% endb lock %}

Devert Alexandre — Using Flask — Slide 9/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

base.htmlAt this step, we already define a common template for all theviews : base.html

<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4.01//EN”><html l ang=”en”>

<head>< t i t l e>LINKY</ t i t l e>< l i n k r e l=” s t y l e s h e e t ” type=” t e x t / c s s ” media=” s c r e e n ”

h r e f=”{{ u r l f o r ( ’ s t a t i c ’ , f i l e n ame=’ base . cs s ’ ) }}”></head><body>

<d i v i d=” c o n t a i n e r ”><d i v i d=” heade r ”>

<h1>LINKY</h1></ d i v>

<d i v i d=” con ten t ”>{% block con t en t %}{% endb lock %}

</ d i v></ d i v>

<d i v i d=” f o o t e r ”><h1>LINKY</h1><p>Des ign &amp ; c o p y r i g h t &copy ; A l exand re Dever t</p>

</ d i v></body>

</html>

Devert Alexandre — Using Flask — Slide 10/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

base.css

base.css is the CSS style used for our website

html , body , d iv , span , h1 , h2 , h3 , h4 , h5 , h6 , p {margin : 0 ;padd ing : 0 ;bo rde r : 0 ;font−s i z e : 100%;f o n t : i n h e r i t ;v e r t i c a l−a l i g n : b a s e l i n e ;

}

body {f o n t : h e l v e t i c a , a r i a l , sans−s e r i f ;c o l o r : DarkS la teGray ;background−c o l o r : Co r nS i l k ;l i n e−h e i g h t : 1 ;

}

. . .

Getting the CSS to look right takes a LOT of time . . .

Devert Alexandre — Using Flask — Slide 11/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The main pageWhat we have done so far, from user point of view

The minimal style is deliberate : at first, don’t waste time onwhat will change a lot

Devert Alexandre — Using Flask — Slide 12/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Conclusion

• Minimal code

• Define the common template for all views ⇒ coherentstyle for all our views, no code duplication

• Heavy use of the div tag ⇒ full control on the graphicstyle

• Minimal graphic style, just keep it open and easy tochange

Devert Alexandre — Using Flask — Slide 13/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Table of Contents

1 Introduction

2 Starting minimal

3 Database integration

4 User’s links

5 Posting links

6 Ordering the links

Devert Alexandre — Using Flask — Slide 14/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Objective

Objective of this step

• Putting together Flask and SQLAlchemy

• Setting the User table

• Allowing users to login and logout

Devert Alexandre — Using Flask — Slide 15/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The file hiearchy

The file hierarchy

|− db−i n i t . py||− l i n k y| |− database . py| |− i n i t . py| |− model . py||− run . py||− s t a t i c| |− base . c s s| |− form . c s s| |− pane l . c s s||− t emp l a t e s| |− base . html| |− home . html| |− i n d e x . html| |− l o g i n . html| |− u i . html||− u s e r s . t x t

Devert Alexandre — Using Flask — Slide 16/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The file hiearchy

Note that we define a linky Python module

|− l i n k y| |− database . py| |− i n i t . py| |− model . py

• init .py is just to tell Python that linky is a module.

• model.py will contain all the objects of the Linky datamodel

• database.py Contains the declaration and definitions forSQLAlchemy

Devert Alexandre — Using Flask — Slide 17/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

database.py

database.py is exactly as we had it in the ORM mappingtutorial

from sq l a l ch emy impor t c r e a t e e n g i n efrom sq l a l ch emy . orm impor t s e s s i onmake r , s c o p e d s e s s i o nfrom sq l a l ch emy . e x t . d e c l a r a t i v e impor t d e c l a r a t i v e b a s e

Base = d e c l a r a t i v e b a s e ( )

d b f i l e n ame = ’ l i n k y . db ’eng i n e = c r e a t e e n g i n e ( ’ s q l i t e :///% s ’ % db f i l e n ame , echo = Fa l s e )d b s e s s i o n = s c o p e d s e s s i o n ( s e s s i onmake r ( b ind = eng i n e ) )

de f d b i n i t ( ) :from . impor t modelBase . metadata . c r e a t e a l l ( b ind = eng in e )

Devert Alexandre — Using Flask — Slide 18/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The User object

The user table

name SQL type

id INTEGER

name VARCHAR(256)

email VARCHAR(256)

pwd hash VARCHAR(128)

pwd salt VARCHAR(48)

We do not store passwords in clean, we store hashed andsalted passwords. It’s basic security standard.

Devert Alexandre — Using Flask — Slide 19/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The User object

We use SQLAlchemy to have an object User mapped to theuser table

c l a s s User ( Base ) :t a b l e n ame = ’ u s e r ’

i d = Column ( I n t e g e r , p r ima r y k e y = True )name = Column ( S t r i n g (256 ) )ema i l = Column ( S t r i n g (256 ) )pwd hash = Column ( S t r i n g (128 ) )pwd sa l t = Column ( S t r i n g (48 ) )

User is part of the our model for Linky, so it goes in model.py

Devert Alexandre — Using Flask — Slide 20/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The User object

A few useful methods for our User object

de f i n i t ( s e l f , name , ema i l ) :s e l f . name = names e l f . ema i l = ema i l

d e f hash pas sword ( s e l f , password , s a l t ) :r e t u r n h a s h l i b . sha512 ( s a l t + password ) . h e x d i g e s t ( )

de f s e t p a s swo rd ( s e l f , password ) :s e l f . pwd sa l t = base64 . b64encode ( os . urandom (32 ) )s e l f . pwd hash = s e l f . hash pas sword ( password , s e l f . pwd sa l t )

d e f check pas sword ( s e l f , password ) :r e t u r n s e l f . pwd hash == s e l f . hash pas sword ( password , s e l f . pwd sa l t )

• We use SHA512, a up-to-date cryptographic hash

• The hash is stored in hexadecimal coding

• All the password handling is done in User

Devert Alexandre — Using Flask — Slide 21/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Creating a test database

To make tests, it is good to have a test database.

Alex marmakoide@yahoo . f r a l e xThomas tweise@gmx . de thomasWei tangwe i@hotma i l . com weiXiang n c x a l i c e@ho tma i l . con x i ang

users.txt contains some fake user account definitions.

Devert Alexandre — Using Flask — Slide 22/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Creating a test database

The script db-init.py reads a text file and creates a newdatabase with the users defined in the text file

d b i n i t ( )

t r y :f o r l i n e i n a r g s . i n p u t f i l e :

l i n e = l i n e . s t r i p ( )i f l e n ( l i n e ) == 0 :

con t i nu e

tokens = l i n e . s p l i t ( )u s e r = User ( tokens [ 0 ] , t okens [ 1 ] )u s e r . s e t p a s swo rd ( tokens [ 2 ] )d b s e s s i o n . add ( u s e r )

e x cep t Va l u eE r r o r as e :s y s . s t d e r r . w r i t e ( ’ E r r o r wh i l e r e a d i n g ”%s”\n ’ % a rg s . i n p u t f i l e . name )s y s . s t d e r r . w r i t e ( ’%s\n ’ % e )s y s . e x i t ( 0 )

d b s e s s i o n . commit ( )

Reading the file and adding elements to the User table

Devert Alexandre — Using Flask — Slide 23/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Creating a test database

The script db-init.py reads a text file and creates a newdatabase with the users defined in the text file

# Command−l i n ep a r s e r = a r gp a r s e . ArgumentParser ( d e s c r i p t i o n = ’ Popu la te a da tabase from a t e x t f i l e ’ )p a r s e r . add argument ( ’ i n p u t f i l e ’ , t ype = a r gpa r s e . F i l eType ( ’ r ’ ) , d e f a u l t = s y s . s t d i n , h e l p = ’ a l i s t o f u s e r s ’ )a r g s = pa r s e r . p a r s e a r g s ( )

# De l e t e the db dump i f i t e x i s t si f os . path . e x i s t s ( d b f i l e n ame ) :

os . remove ( d b f i l e n ame )

We take the path of the input text file from command-line

Devert Alexandre — Using Flask — Slide 23/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Creating a test database

The script db-init.py reads a text file and creates a newdatabase with the users defined in the text file

impor t os , os . path , sys , a r g p a r s e

from l i n k y . da tabase impor t db f i l e n ame , d b i n i t , d b s e s s i o nfrom l i n k y . model impor t User

And of course, we need to import the proper definitions

Devert Alexandre — Using Flask — Slide 23/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The main user page

The run.py now contain a new URL : home, the main pagefor one user.

de f c h e c k u s e r i s l o g g e d ( ) :# Send ’ Unautho r i z ed ’ i f no u s e r l ogged i ni f g . u s e r i s None :

abo r t (401)

@app . r ou t e ( ’ /home ’ )de f home ( ) :

c h e c k u s e r i s l o g g e d ( )r e t u r n r e n d e r t emp l a t e ( ’ home . html ’ , u s e r = g . u s e r )

Devert Alexandre — Using Flask — Slide 24/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The main user page

The main page of a user, home.html, is kept to a bareminimum for now

{% extend s ” base . html ” %}

{% block con t en t %}<d i v c l a s s=” s i n g l e−column−l a you t−25”>

<d i v c l a s s=”middle−column”><d i v c l a s s = ” s e c t i o n ”>

<h2>Welcome , {{ u s e r . name }} !</h2></ d i v>

</ d i v></ d i v>{% endb lock %}

We of course extends base.html

Devert Alexandre — Using Flask — Slide 25/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The main user page

The logging page

Devert Alexandre — Using Flask — Slide 26/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging in

Logging in is a fairly complex affair

@app . r ou t e ( ’ / l o g i n ’ , methods = ( ’GET ’ , ’POST ’ ) )de f l o g i n ( ) :

# POST r e qu e s ti f r e q u e s t . method == ’POST ’ :# Try to f i n d the u s e rt r y :

u s e r = d b s e s s i o n . query ( User ) . f i l t e r ( User . ema i l == r e qu e s t . form [ ’ ema i l ’ ] ) . one ( )excep t sq l a l ch emy . orm . exc . NoResultFound :

e r r o r = ’ Thi s ema i l have not be r e g i s t e r e d ’r e t u r n r e n d e r t emp l a t e ( ’ l o g i n . html ’ , u s e r = g . use r , e r r o r = e r r o r )

# Check the u s e r passwordi f not u s e r . check pas sword ( r e q u e s t . form [ ’ password ’ ] ) :

e r r o r = ’Wrong password ’r e t u r n r e n d e r t emp l a t e ( ’ l o g i n . html ’ , u s e r = g . use r , e r r o r = e r r o r )

# Job dones e s s i o n [ ’ u s e r i d ’ ] = u s e r . i dr e t u r n r e d i r e c t ( u r l f o r ( ’ home ’ ) )

# GET Requeste l s e :

r e t u r n r e n d e r t emp l a t e ( ’ l o g i n . html ’ , u s e r = g . u s e r )

Devert Alexandre — Using Flask — Slide 27/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging in

Logging can send informations (the logging page) and receiveinformations (the logging informations)

@app . r ou t e ( ’ / l o g i n ’ , methods = ( ’GET ’ , ’POST ’ ) )de f l o g i n ( ) :

i f r e q u e s t . method == ’POST ’ :. . .

e l s e :r e t u r n r e n d e r t emp l a t e ( ’ l o g i n . html ’ , u s e r = g . u s e r )

Devert Alexandre — Using Flask — Slide 28/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging in

The logging page

Devert Alexandre — Using Flask — Slide 29/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging in

The logging page, after a logging error

Devert Alexandre — Using Flask — Slide 30/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging inThe logging page, login.html, defines a form with two fields

{% extend s ” base . html ” %}{% impor t ” u i . html ” as u i %}

{% block con t en t %}<d i v c l a s s=” s i n g l e−column−l a you t−25”>

<d i v c l a s s=”middle−column”>{%− c a l l u i . r e n d e r p a n e l ( ” Log in ” , ” c e n t e r ” ) −%}<form name=” l o g i n ” method=” pos t ” a c t i o n=”{{ u r l f o r ( ’ l o g i n ’ ) }}”>

< l a b e l>Emai l</ l a b e l><i n pu t type=” t e x t ” name=” ema i l ” maxlength=”254”/>

< l a b e l>Password</ l a b e l><i n pu t type=”password ” name=”password ”/>

<button type=” submit ”>Ente r</ button></ form>{% i f e r r o r i s d e f i n e d %}<hr /><p>{{ e r r o r }}</p>{% end i f %}{%− e n d c a l l %}

</ d i v></ d i v>{% endb lock %}

Devert Alexandre — Using Flask — Slide 31/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging in

Once the user press enter, the loggin information arePOSTed and processed

# POST r e qu e s ti f r e q u e s t . method == ’POST ’ :# Try to f i n d the u s e rt r y :

u s e r = d b s e s s i o n . query ( User ) . f i l t e r ( User . ema i l == r e qu e s t . form [ ’ ema i l ’ ] ) . one ( )excep t sq l a l c h emy . orm . exc . NoResultFound :

e r r o r = ’ Thi s ema i l have not be r e g i s t e r e d ’r e t u r n r e n d e r t emp l a t e ( ’ l o g i n . html ’ , u s e r = g . use r , e r r o r = e r r o r )

# Check the u s e r passwordi f not u s e r . check pas sword ( r e q u e s t . form [ ’ password ’ ] ) :

e r r o r = ’Wrong password ’r e t u r n r e n d e r t emp l a t e ( ’ l o g i n . html ’ , u s e r = g . use r , e r r o r = e r r o r )

# Job dones e s s i o n [ ’ u s e r i d ’ ] = u s e r . i dr e t u r n r e d i r e c t ( u r l f o r ( ’ home ’ ) )

Devert Alexandre — Using Flask — Slide 32/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging in

When trying to loggin in

1 Check that the users exists. If not, signal it.

2 Check that the password is correct. If not, signal it.

3 Create a user id session cookie variable, to keep track ofthe connected user.

4 Redirect to the user homepage

Devert Alexandre — Using Flask — Slide 33/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Logging out

Logging out is a fairly simple control

@app . r ou t e ( ’ / l o gou t ’ )d e f l o gou t ( ) :

s e s s i o n . pop ( ’ u s e r i d ’ , None )r e t u r n r e d i r e c t ( u r l f o r ( ’ i nd e x ’ ) )

• We associate this control to thelogout URL

• We remove the user id variable from the session

• We redirect the user to the default introduction page

Devert Alexandre — Using Flask — Slide 34/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Additional magic

We also defines the following methods

@app . b e f o r e r e q u e s tde f b e f o r e r e q u e s t ( ) :

# Ensure we got a u s e r i n s t a n c e i f the u s e r i s l ogged i ng . u s e r = Nonei f ’ u s e r i d ’ i n s e s s i o n :

g . u s e r = db s e s s i o n . query ( User ) . f i l t e r ( User . i d == s e s s i o n [ ’ u s e r i d ’ ] ) . one ( )

Before processing any request we make sure we have theright User instance

Devert Alexandre — Using Flask — Slide 35/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Additional magic

We also defines the following methods

@app . t e a r down r eque s tde f s hu t down s e s s i o n ( e x c e p t i o n = None ) :

d b s e s s i o n . remove ( )

We cleanup the with the database session once a request isprocessed

Devert Alexandre — Using Flask — Slide 35/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Additional magic

ui.html defines useful reusable user interface elements

{%− macro r e n d e r p a n e l ( t i t l e , s t y l e=” l e f t ” ) %}<d i v c l a s s=” pane l ”>

<h1 c l a s s=”{{ s t y l e }}”>{{ t i t l e }}</h1><d i v c l a s s=” pane l−con t en t ”>

<d i v c l a s s=”{{ s t y l e }}”>{{ c a l l e r ( ) }}

</ d i v></ d i v>

</ d i v>{%− endmacro %}

Devert Alexandre — Using Flask — Slide 36/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The root page

The root page have now a button for logging in and register

Devert Alexandre — Using Flask — Slide 37/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The root page

This is done with a tags and a bit of CSS in index.html

<d i v c l a s s = ”menu”><u l>

< l i><a h r e f=”{{ u r l f o r ( ’ l o g i n ’ ) }}”>Log in</a></ l i>< l i><a h r e f=”{{ u r l f o r ( ’ l o g i n ’ ) }}”>Re g i s t e r</a></ l i>

</ u l></ d i v>

Devert Alexandre — Using Flask — Slide 38/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Conclusion

• We have now one model (User), some views and somecontroller

• Users can login and logout

• Database and session management

Devert Alexandre — Using Flask — Slide 39/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Table of Contents

1 Introduction

2 Starting minimal

3 Database integration

4 User’s links

5 Posting links

6 Ordering the links

Devert Alexandre — Using Flask — Slide 40/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Objective

Objective of this step

• Define the Link object

• Showing all the links

• Showing the links for one user

Devert Alexandre — Using Flask — Slide 41/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The Link object

The link table

name SQL type

id INTEGER

url VARCHAR(1024)

comment VARCHAR(1024)

Devert Alexandre — Using Flask — Slide 42/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The Link object

We use SQLAlchemy to have an object Link mapped to thelink table

c l a s s L ink ( Base ) :t a b l e n ame = ’ l i n k ’

i d = Column ( I n t e g e r , p r ima r y k e y = True )u r l = Column ( S t r i n g (1024) )comment = Column ( S t r i n g (1024) )

de f i n i t ( s e l f , u r l ) :s e l f . u r l = u r l

Link is part of the our model for Linky, so it goes inmodel.py, like for User

Devert Alexandre — Using Flask — Slide 43/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The Link object

We also have to modelize the relationship between Link andUser : it’s a one-to-many relationship.In the User class

l i n k s = r e l a t i o n s h i p ( ’ L ink ’ , b a c k r e f = ’ u s e r ’ )

In the Link class

u s e r i d = Column ( I n t e g e r , Fore ignKey ( ’ u s e r . i d ’ ) )

Devert Alexandre — Using Flask — Slide 44/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The user’s home page

The user’s home page, home.html, displays a list of linksnamed linked list

{% extend s ” base . html ” %}{% impor t ” u i . html ” as u i %}

{% block con t en t %}<d i v c l a s s=” s i n g l e−column−l a you t−50”>

<d i v c l a s s=”middle−column”><d i v c l a s s = ”menu”>

<u l>< l i><a h r e f=”{{ u r l f o r ( ’ l ogout ’ ) }}”>Logout</a></ l i>

</ u l></ d i v>

<h2>The l a t e s t l i n k s</h2>{% f o r l i n k i n l i n k l i s t %}{{ u i . r e n d e r p o s t ( l i n k ) }}

{% end f o r %}</ d i v>

</ d i v>{% endb lock %}

The HTML code for a posted link is done by ui.render post

Devert Alexandre — Using Flask — Slide 45/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The user’s home page

The controler that renders home.html provides linked list

@app . r ou t e ( ’ /home ’ )de f home ( ) :

c h e c k u s e r i s l o g g e d ( )

l i n k s = db s e s s i o n . query ( L ink ) . a l l ( )r e t u r n r e n d e r t emp l a t e ( ’ home . html ’ , u s e r = g . use r , l i n k l i s t = l i n k s )

Later, we might want to render only some of the links, say,the 20 first ones, only from friends.

Devert Alexandre — Using Flask — Slide 46/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Rendering a posted link

ui.render post is defined in ui.html

{%− macro r e n d e r p o s t ( l i n k ) %}<d i v c l a s s=” pos t ”>

<h1>{{ l i n k . comment }}</h1><d i v c l a s s=” pane l−con t en t ”>

<a h r e f=”{{ l i n k . u r l }}”>{{ l i n k . u r l }}</a><p>

pos ted by<a h r e f=”{{ u r l f o r ( ’ show user ’ , name=l i n k . u s e r . name ) }}”>{{ l i n k . u s e r . name }}</a>

</p></ d i v>

</ d i v>{%− endmacro %}

Very easy to reuse, no code duplication, and style completlycontroled by CSS

Devert Alexandre — Using Flask — Slide 47/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Showing all posts from user

We define user.html, a page that shows post from one user

{% extend s ” base . html ” %}{% impor t ” u i . html ” as u i %}

{% block con t en t %}<d i v c l a s s=” s i n g l e−column−l a you t−50”>

<d i v c l a s s=”middle−column”><d i v c l a s s = ”menu”>

<u l>< l i><a h r e f=”{{ u r l f o r ( ’ home ’ ) }}”>Home</a></ l i>

</ u l></ d i v>

<h2>L i nk s from {{ owner . name }}</h2>{% f o r l i n k i n owner . l i n k s %}{{ u i . r e n d e r p o s t ( l i n k ) }}

{% e l s e %}{{ owner . name }} d id not pos t l i n k s y e t . . .

{% end f o r %}</ d i v>

</ d i v>{% endb lock %}

owner is the User instance whom post are shown

Devert Alexandre — Using Flask — Slide 48/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Showing all posts from user

The corresponding controller in run.py

@app . r ou t e ( ’ / u s e r/<name>’ )d e f show use r ( name ) :

c h e c k u s e r i s l o g g e d ( )

# Check i f the u s e r e x i s t st r y :

owner = db s e s s i o n . query ( User ) . f i l t e r ( User . name == name ) . one ( )excep t sq l a l c h emy . orm . exc . NoResultFound :

abo r t (404)

# Show the page f o r t ha t u s e rr e t u r n r e n d e r t emp l a t e ( ’ u s e r . html ’ , u s e r = g . use r , owner = owner )

If the user does not exist, we raise an error 404 (Not Found)

Devert Alexandre — Using Flask — Slide 49/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Showing all posts from user

The corresponding controller in run.py

@app . r ou t e ( ’ / u s e r/<name>’ )d e f show use r ( name ) :

c h e c k u s e r i s l o g g e d ( )

# Check i f the u s e r e x i s t st r y :

owner = db s e s s i o n . query ( User ) . f i l t e r ( User . name == name ) . one ( )excep t sq l a l c h emy . orm . exc . NoResultFound :

abo r t (404)

# Show the page f o r t ha t u s e rr e t u r n r e n d e r t emp l a t e ( ’ u s e r . html ’ , u s e r = g . use r , owner = owner )

We use a parametric URL. /user/SunWuKong will show thelinks posted by the user named SunWuKong

Devert Alexandre — Using Flask — Slide 49/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Generating the test database

We still need a simple way to generate a test database, withdb-init.py

• A simple text format

• Contains fake users

• Contains fake posted links from users

Use JSON file, it’s very easy to parse in Python, with thejson module

Devert Alexandre — Using Flask — Slide 50/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Generating the test database

A sample of the JSON file

{” u s e r s ” : [{

”name” : ” Alex ” ,” ema i l ” : ”marmakoide@yahoo . f r ” ,”pwd” : ” a l e x ” ,” l i n k s ” : [{

” u r l ” : ” h t tp : //www. pouet . net ” ,”comment” : ” Stay i n tune wi th the demoscene ! ”

} ,{

” u r l ” : ” h t tp : // theoatmea l . com/ comics / dog paradox ” ,”comment” : ”Ha ha , my dog the same”

}}

]}

Devert Alexandre — Using Flask — Slide 51/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Generating the test database

Reading the JSON file is one line of code

db data = j s o n . l oad ( ’my−f i l e . j s ’ )

This returns a structure that reflects the content of the file

Devert Alexandre — Using Flask — Slide 52/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Generating the test database

Then, we just traverse the returned structure and builddatabase objects

f o r u s e r d a t a i n db data [ ’ u s e r s ’ ] :# Crea te the u s e r i n s t a n c eu s e r = User ( u s e r d a t a [ ’ name ’ ] , u s e r d a t a [ ’ ema i l ’ ] )u s e r . s e t p a s swo rd ( u s e r d a t a [ ’ pwd ’ ] )

# Add each l i n ki f ’ l i n k s ’ i n u s e r d a t a :

f o r l i n k d a t a i n u s e r d a t a [ ’ l i n k s ’ ] :l i n k = L ink ( l i n k d a t a [ ’ u r l ’ ] )i f ’ comment ’ i n l i n k d a t a :

l i n k . comment = l i n k d a t a [ ’ comment ’ ]u s e r . l i n k s . append ( l i n k )

# Add the u s e rd b s e s s i o n . add ( u s e r )

Devert Alexandre — Using Flask — Slide 53/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Conclusion

• The model have one new object, Link

• The home page show all the links posted

• We have a page to show all posts from one user

Devert Alexandre — Using Flask — Slide 54/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Table of Contents

1 Introduction

2 Starting minimal

3 Database integration

4 User’s links

5 Posting links

6 Ordering the links

Devert Alexandre — Using Flask — Slide 55/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Objective

Objective of this step

• A new view to post links

Devert Alexandre — Using Flask — Slide 56/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

A new view : post.htmlWe define a new view, post.html : the form to post a link

{% extend s ” base . html ” %}{% impor t ” u i . html ” as u i %}

{% block con t en t %}<d i v c l a s s=” s i n g l e−column−l a you t−50”>

<d i v c l a s s=”middle−column”>{%− c a l l u i . r e n d e r p a n e l ( ” Log in ” , ” c e n t e r ” ) −%}<form name=” pos t ” method=” pos t ” a c t i o n=”{{ u r l f o r ( ’ p o s t l i n k ’ ) }}”>

< l a b e l>Link ’ s URL</ l a b e l><i n pu t type=” t e x t ” name=” u r l ” maxlength=”1024”/>

< l a b e l>Comment</ l a b e l><i n pu t type=” t e x t ” name=”comment” , maxlength=”1024”/>

<button type=” submit ”>Ente r</ button></ form>{% i f e r r o r i s d e f i n e d %}<hr /><p>{{ e r r o r }}</p>{% end i f %}{%− e n d c a l l %}

</ d i v></ d i v>{% endb lock %}

Devert Alexandre — Using Flask — Slide 57/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

The link posting controller

In run.py we define a new URL : the link posting controller

@app . r ou t e ( ’ / pos t ’ , methods = ( ’GET ’ , ’POST ’ ) )de f p o s t l i n k ( ) :

c h e c k u s e r i s l o g g e d ( )

# POST r e qu e s ti f r e q u e s t . method == ’POST ’ :# Crea te the l i n kl i n k = Link ( r e q u e s t . form [ ’ u r l ’ ] )l i n k . comment = r e qu e s t . form [ ’ comment ’ ]l i n k . u s e r = g . u s e r

# Update dbd b s e s s i o n . add ( l i n k )d b s e s s i o n . commit ( )r e t u r n r e d i r e c t ( u r l f o r ( ’ home ’ ) )

# GET Requeste l s e :

r e t u r n r e n d e r t emp l a t e ( ’ po s t . html ’ , u s e r = g . u s e r )

Devert Alexandre — Using Flask — Slide 58/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Access to the link posting view

We have now to give a simple way to access to the linkposting view.

<d i v c l a s s = ”menu”><u l>

< l i><a h r e f=”{{ u r l f o r ( ’ p o s t l i n k ’ ) }}”</a>New l i n k</ l i>< l i><a h r e f=”{{ u r l f o r ( ’ l ogout ’ ) }}”>Logout</a></ l i>

</ u l></ d i v>

In home.html, we put a button that link to link posting view.

Devert Alexandre — Using Flask — Slide 59/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Conclusion

• We added a new view and a new controller

• The changes were additions

• No changes to previous code

Devert Alexandre — Using Flask — Slide 60/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Table of Contents

1 Introduction

2 Starting minimal

3 Database integration

4 User’s links

5 Posting links

6 Ordering the links

Devert Alexandre — Using Flask — Slide 61/62

UNIVERSITY OF SCIENCE AND TECHNOLOGY OF CHINA SCHOOL OF SOFTWARE ENGINEERING OF USTC

Objective

Objective of this step

• Links should store the date of the post

• Links should be shown ordered by date

Devert Alexandre — Using Flask — Slide 62/62

Recommended