Python Code Camp for Professionals 1/4

Post on 29-Jan-2018

138 views 0 download

transcript

Build a

Python Web APP

Ingredients

• Python

• Web server framework

• Database

• Love

Bottle + GEvent

• Async is cool

• More efficient use of CPU

• Best for I/O-bound applications

Install Bottle + Gevent

pip install gevent

pip install bottle

easy_install gevent

easy_install bottle

Hello World

from gevent import monkey; monkey.patch_all()

from bottle import run, route

@route('/hello')

def fxn():

return "Hello World!"

run(server='gevent', host="localhost", port=8001, debug=True)

unfbnjm

Step

Import gevent and bottle

Magically replace synchronous libraries with asynccounterparts

from gevent import monkey;

monkey.patch_all()

from bottle import run, route

Step

Assign the url /hello to the function below@route('/hello')

Define a python functiondef fxn():

Return “Hello World!” to the browserreturn "Hello World!"

Activate the gevent server, listen on port 8001

run(server='gevent', host="localhost", port=8001,

debug=True)

Accepting Inputs

Via the urlhttp://www.gloopgroup.com/profile/paolo

Via query stringhttps://www.google.com.ph/?ion=1&q=gloopgroup

Via POST bodyFile upload to a website

Inputs in Bottle

Via the url

@route('/input1/<name>')

def greet(name):

return "Hello "+name

Visit: localhost:8001/input1/paolo

Inputs in BottleVia query string

@route('/sum')

def sum():

total = 0

start = request.query.get("start")

end = request.query.get("end")

for i in range(start,end):

total += i

return "Sum of "+str(start) + " to " + str(end) + " = " +

str(total)

Visit: localhost:8001/sum?start=1&end=10

Inputs in BottleVia POST body

@route('/login', method="POST")

def login():

username = request.forms.get("username")

password = request.forms.get("password")

acceptedpasswords = ["gloopgroup", "devconph" ,

"adventuretime"]

if password in acceptedpasswords:

return "Welcome "+ username

else:

return "Unauthorized"

Visit: localhost:8001/login using login page

Activity 1

Create a calculator api:http://localhost:8001/operation/operand1/operand2

will return the value of

operand1 <operation> operand2

Example:

/subtraction/10/2 will output 8

Common Return TYPESPlain Text

Similar to what we were doing earlier

Common Return TYPESBinary

When returning files like images, video, audio, pdfs…

Common Return TYPESJSON

The common return type for APIs

Example: FB API

/{userid}/friends

{

"data": [

{

"name": "Terence Pua",

"id": "608407"

},

{

"name": "Gene Paul Quevedo",

"id": "10153785024974240"

},

{

"name": "Jc Velasquez",

"id": "722462218"

},

{

"name": "Jomel C. Imperio",

"id": "779287017"

}

],

"summary": {

"total_count": 770

}

}

Common Return TYPESHTML

Return web pages with dynamic/static content<!DOCTYPE html><html itemscope itemtype="http://schema.org/QAPage"><head>

<title>regex - Validate email address in JavaScript? - Stack Overflow</title><link rel="shortcut icon" href="//cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico?v=4f32ecc8f43d"><link rel="apple-touch-icon image_src" href="//cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon.png?v=c78bd457575a"><link rel="search" type="application/opensearchdescription+xml" title="Stack Overflow" href="/opensearch.xml"><meta name="twitter:card" content="summary"><meta name="twitter:domain" content="stackoverflow.com"/><meta property="og:type" content="website" />

<meta property="og:image" itemprop="image primaryImageOfPage" content="http://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png?v=73d79a89bded&a" />

<meta name="twitter:title" property="og:title" itemprop="title name" content="Validate email address in JavaScript?" /><meta name="twitter:description" property="og:description" itemprop="description" content="How can an email address be validated

in JavaScript?" /><meta property="og:url" content="http://stackoverflow.com/questions/46155/validate-email-address-in-javascript"/><link rel="canonical" href="http://stackoverflow.com/questions/46155/validate-email-address-in-javascript" />

Returning JSON ObjectJSON

Simply return a dictionary or list

@route("/json")

def jason():

return {"lastname":"bourne", "alias":"David Webb"}

Returning Static HTMLHTML

Use static_file from bottle

@route("/loginpage")

def loginpage():

return static_file("login.html", root=".")

Testing the POST Handler

Visit localhost:8081/loginpage

Type your name and use any of these as passwordg

gloopgroup, devconph, adventuretime

Click submit

The POST Request Cycle<form action="/login" method="POST">

Method dictates what kind of request happens when submittedAction tells the browser where to submit the request

<input type="text" name="username">

Adds a text input that will be associated to the username field

<input type="password" name="password">

Adds a password input that will be associated to the password field

<input type="submit">

Adds a button that submits the form when clicked

Returning Dynamic HTMLHTML

Use a templating engine:

• Library that can substitute variables into a template quickly and cleanly

• Isolates the designer’s job of designing and the coder’s job of coding

Install Tenjin

pip install tenjin

easy_install tenjin

Using Tenjinfrom gevent import monkey;

monkey.patch_all()

from bottle import run, route, request

import tenjin

from tenjin.helpers import *

@route("/introduction/<name>/<age>/<work>")

def template1(name, age, work):

context = {"name":name, "age":age, "work":work}

return engine.render("introduction.html", context);

engine = tenjin.Engine(path=['.'])

run(server='gevent', host="localhost", port=8001, debug=True)

The template<!doctype html>

<html lang="en">

<head>

<title>Login</title>

</head>

<body>

<h1>${name}</h1>

<h2>Age:${age}<h2>

<h2>Work:${work}<h2>

</body>

</html>

Stepfrom gevent import monkey;

monkey.patch_all()

from bottle import run, route, request

import tenjin

from tenjin.helpers import *

Import all libraries, including tenjin and all helper methods

@route("/introduction/<name>/<age>/<work>")

Define a route for the url, and define variables in it

def template1(name, age, work):

Declare a request handler and receive the variables from the url

Stepcontext = {"name":name, "age":age, "work":work}

Define a context variable, which is a dictionary of values that will be substituted into the template

return engine.render("introduction.html", context);

Render the template called introduction.html using the context variable named context, and return it to the browser

engine = tenjin.Engine(path=['.'])

Instructs the templating engine to look for the templates in the directories listed in path

Step (Inside the template)

<!doctype html>

<html lang="en">

<head>

<title>Login</title>

</head>

<body>

<h1>${name}</h1>

<h2>Age:${age}<h2>

<h2>Work:${work}<h2>

</body>

</html>

{

"name":"Paolo",

"age":"30",

"work":"Synergist"

}

+

Displaying Lists

@route("/spell/<word>")

def template1(word):

letters = list(word)

context = {"letters":letters, "word":word}

return engine.render("speller.html", context);

Step@route("/spell/<word>")

Define a route that accepts a variable assigned to word

def speller(word):

Define a handler that accepts a variable named word

letters = list(word)

Convert the text string into a list object. From a string “word”, it becomes a list [“w”, “o”, “r”, “d”]

Stepcontext = {"letters":letters}

Define a context variable, which contains the list of letters we just created

return engine.render("speller.html", context);

Render the template called speller.html using the context variable named context, and return it to the browser

Step (Inside the template)

<?py for letter in letters: ?>

Loop on the elements of the list named letters

<h3>${letter}</h3><br>

Display the element letter along with the html

<?py #endfor ?>

Denote where the loop ends in the template

<a href="/greet/${word}">greet ${word}</a>Create a link that will call the greet API we created earlier

{"letters":["s", "u", "s", "h", "i"]}

Highlighting Names

@route("/profiles/<name>")

def profile(name):

users = [

{"name":"Em", "image":"http://goo.gl/aDxeu1", "age":30,

"work":"Futurist"},

{"name":"Paolo", "image":"http://goo.gl/5k2oZr", "age":30,

"work":"Synergist"}

]

context = {"users":users, "name":name}

return engine.render("profiles.html", context)

Stepusers = [

{"name":"Em", "image":"http://goo.gl/aDxeu1", "age":30, "work":"Futurist"},

{"name":"Paolo", "image":"http://goo.gl/5k2oZr", "age":30, "work":"Synergist"}

]

Define a list of dictionaries, with each dictionary object containing information about a user. It contains information name, url of the image, age, and work

context = {"users":users, "name":name}

Define a conext containing the name to be highlighted, and the list of users

return engine.render("profiles.html", context)

Render the template named profiles.html with the context

Step (Inside the template)

<?py for user in users: ?>

Loop on the elements of the list named users, each element in the list can be referred to using the user variable

<div style="height:100px;">

Create a div element in the html to contain one user element

<img src="${user['image']}" style="float:left;

height:100%;"/>

Place an image in the html coming from the url defined in user[‘image’]

Step (Inside the template)

<?py if name==user["name"]: ?>

Compare the current user’s name to the name entered in the url

<strong>Name: ${user['name']}</strong>

This happens when the above condition is true, display the name as bold characters

<?py else: ?>

Add an else handler that executes if condition is not met

Step (Inside the template)

Name: ${user['name']}

This happens when primary condition is not met, display the user’s name without any decorations

<?py #endif ?>

Denote where the if statement ends

Make a Sushi Menu

Create a menu using all the sushi items in the sushilist variable

Display the image and name of the sushi

When the menu item is clicked, it should display another page containing the name, image, price, and rating of the sushi (defined in the sushilist variable)

The most creative presentation of the menu wins a prize

Activity 1

pip install gevent

pip install bottle

Cost per Mille =• Cost per 1000 impressions

• Abuse of statistics

• i.e. Magic

• i.e. It sucks

• Not based on empirical measured data

ADVERTISING!

Eyeballs

cost

How many are watching me right now?How many are paying attention?How many are interested?How many are still reading this part?How about now?Now?

ROUTER ON

PROMISCUOUS MODE

DEVICEs SENDING

PROBE REQUESTS

PYTHON

+TCPDUMPWe get this

Pilot Installation

23000Passers-by

39%viewed

10%Finished

Meh…

Map movement

Geofencing alternative

Detection

perimeter

snoop

turn off your phones

when going to the lagoon