Lightweight web frameworks
-
Upload
jph98 -
Category
Technology
-
view
19.038 -
download
1
Transcript of Lightweight web frameworks
![Page 1: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/1.jpg)
![Page 2: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/2.jpg)
Welcome...
to the inaugural meeting of Chippenham Tech Chat...
![Page 3: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/3.jpg)
Meetup DetailsWill be hosted once a month at Mango/Scisys - Methuen Park
Presentations on various topics. If you're interested in doing one then propose it on the forum
Meetup grouphttp://www.meetup.com/Chippenham-Tech-Chat/
Google Groups Forumhttps://groups.google.com/forum/?fromgroups#!forum/chippenhamtechchat
![Page 5: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/5.jpg)
Overview
● A brief history of web applications● Past experience● An overview of lightweight web frameworks● An introduction to one web framework and
it's features● I won't go into
![Page 6: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/6.jpg)
Web Frameworks - A Brief History
● CGI and Perl - circa 1993● PHP, Coldfusion - circa 1995● ASP - circa 1998● JSP and Servlet Spec - circa 1999● Struts - circa 2001● Rails - circa 2005
How many are there today?
![Page 7: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/7.jpg)
261 !* at least
![Page 8: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/8.jpg)
Used Java Servlets and JSP around 1999/2000. First introduction - somewhat painful.
Then discovered Struts in 2001/2002 (pre 1.0 release). Vowed never to go back to JSP hell.
In 2005/2006 we migrated our legacy Struts apps to Struts 2. Better still.
SpringMVC came in around the same time.
Past Experience - Cathedrals
![Page 9: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/9.jpg)
Broken down into language (approx)
91 33 31 40
14 22 23 7
![Page 10: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/10.jpg)
Past Experience - Post Java
Then looked at PHP for doing more lightweight work. Used CakePHP 1.x then looked at CodeIgniter.
Used Dojo (pre 1.0 release) and Velocity to build a rich client Javascript application.
![Page 11: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/11.jpg)
Past Experience - First One Pager
Then ended up building a rich client interface in Google Web Toolkit 1.x
Then around 2007 went along to the Vancouver Ruby/Rails meetup. Talked about Rails/Merb then someone mentioned Sinatra.
Then picked up Flask, looked at Ratpack in Geecon this year
![Page 12: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/12.jpg)
Flask - Python
![Page 13: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/13.jpg)
Really?
![Page 14: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/14.jpg)
Here's what we would have have done back in the day with Apache Struts...
![Page 15: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/15.jpg)
1. Setup web.xml
2. Created an index.jsp to forward on to my app
3. Setup struts-config.xml and added a form and action mapping detailing my Action class
4. Create an Action & Action Form class
![Page 16: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/16.jpg)
5. Setup my forward on success
6. Put all this in a predefined folder structure
7. Package it all up into a war file
8. Deploy to Tomcat and Start
![Page 17: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/17.jpg)
then....
9. Fix the stupid errors
10. Deploy again and see Hello World in my browser. Maybe.
![Page 18: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/18.jpg)
easy...
![Page 19: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/19.jpg)
Others?
![Page 20: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/20.jpg)
There's others !!There's a bunch of other lightweight web frameworks in various languages:
● Flask - Python● Nancy - .NET● Ratpack - Groovy/Java● Berliner - CoffeeScript● Dancer - Perl
Classification of these...
![Page 21: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/21.jpg)
Web Framework Taxonomy
Sinatra, Flask, Berliner, Dancer, Ratpack, Nancy[Micro Frameworks]
Rails, Django[Lightweight Frameworks]
Play, Struts 2, Spring MVC[MOR]
Google Web Toolkit, JSF[Component Based]
Light
Heavy
![Page 22: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/22.jpg)
Sinatra - Ruby
#!/usr/bin/env rubyrequire 'rubygems'require 'sinatra'
get '/' do '<b>Hello, world!</b>'end
![Page 23: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/23.jpg)
Nancy - dot NET
public class SampleModule : Nancy.NancyModule{ public SampleModule() { Get["/"] = _ => "Hello World!"; }}
![Page 24: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/24.jpg)
Ratpack - Groovy
get("/helloworld") { "Hello, World!"}
![Page 25: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/25.jpg)
Berliner - Coffeescript
app = require 'berliner'app.get '/', -> 'Hello, world!'app.run 4567
![Page 26: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/26.jpg)
Properties of such frameworks?
● Minimalistic by default
● Self contained web server
● Modular with extensions available
![Page 27: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/27.jpg)
Some more on Flask...
![Page 28: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/28.jpg)
Python Flask Architecture
Based on Werkzeug so mod_wsgi based
Built in web server
Uses Jinja2 for templating
Hosting available on heroku, webfaction
Celery integration for async task/job queuing
![Page 29: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/29.jpg)
Flask Extension Modules
Example modules (will cover later):● Flask admin - generates an admin interface● Flask login - login mechanism● Flask cache - simple caching● Flask couchdb - couchdb module● Flask lesscss - less CSS template● Flask lettuce - BDD● Flask celery - distributed task queue
Extensions registry here:http://flask.pocoo.org/extensions/
![Page 30: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/30.jpg)
What can I use Flask for?
1. Projects with tight deadlines
2. Prototyping
3. In-house internal applications
4. Applications where system resources are limited, e.g. VM's hosted on Linode.com
![Page 31: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/31.jpg)
App
![Page 32: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/32.jpg)
Flask App - Log Viewer
A lightweight log viewer application, but without the overhead of indexing. Provides:
● Access to specific application logs for users instead of them ssh'ing to the server to "less" them.
● Retrieve the head or tail a log file
● Search in logs (with grep) for an expression
![Page 33: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/33.jpg)
Flask 0.9 utilising:● YAML (Yet Another Markup Language) for
configuration ● Jinja 2 templates for content separation● The LESS dynamic stylesheet module
Virtualenv - for creating an isolated Python environment to manage dependencies
Python 2.6.1 (CPython)
System Components
![Page 34: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/34.jpg)
Python Modules
Used additional Python wrappers for Grin - http://pypi.python.org/pypi/grin● Provides search features (wraps GNU grep)● Supports regex, before/after context● File/dir exclusion
Tailer - http://pypi.python.org/pypi/tailer/0.2.1● Display n lines of the head/tail of a file● Allows "follow" of a file
![Page 35: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/35.jpg)
Main UI
![Page 36: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/36.jpg)
Templating<!doctype html>{% include 'header.html' %}
{% include 'search.html' %}
{% macro genlink(func, filename) -%} <a href="{{func}}/{{ filename }}/{{ session['grepnumlines'] }}">{{func}}</a>{%- endmacro %}
{% for filename in session['validfiles']|sort %}<div class="logfile">
{{ session['validfiles'].get(filename)[0] }} -{{ genlink('head', filename) }} <span style="color:#cecece">|</span>
{{ genlink('tail', filename) }}- {{ session['validfiles'].get(filename)[1] }} bytes
</div>{% endfor %}
{% include 'footer.html' %}
![Page 37: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/37.jpg)
New route() for [email protected]("/grep/", methods=['GET', 'POST'])def grep():
"""Search through a file looking for a matching phrase"""
# Validate the form inputsif request is None or request.form is None:
return render_template('list.html',error='no search expression specified')
if request.form['expression'] is None or len(request.form['expression']) == 0:return render_template('list.html',error='no search expression specified')
expression = request.form['expression'].strip()output = ""filepaths = []
output += search_expr(output, filepaths, session.get('validfiles'), expression, request.form['grepbefore'], request.form['grepafter'])
if not output:return render_template('list.html', error='No results found for search expression')
expression = expression.decode('utf-8')highlight = '<span class="highlightmatch">' + expression + '</span>'highlightedoutput = output.decode('utf-8').replace(expression, highlight)
return render_template('results.html', output=highlightedoutput,filepaths=filepaths,expression=expression)
![Page 38: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/38.jpg)
Search Expression - using grindef search_for_expression(output, filepaths, validfiles, expression, grepbefore, grepafter):
"""Carry out search for expression (using grep context) on validfiles returning matching files as output"""
options = grin.Options()options['before_context'] = int(grepbefore)options['after_context'] = int(grepafter)options['use_color'] = Falseoptions['show_filename'] = Falseoptions['show_match'] = Trueoptions['show_emacs'] = Falseoptions['show_line_numbers'] = True
searchregexp = re.compile(expression)grindef = grin.GrepText(searchregexp, options)
for file in validfiles:filepath = validfiles.get(file)[0]report = grindef.grep_a_file(filepath)if report:
output += '<a name="filename' + str(anchorcount) + '"></a><h2>' + filepath + '</h2>'filepaths.append(filepath)reporttext = report.split("\n")for text in reporttext:
if text:output += "line " + text + "<br>"
return output
![Page 39: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/39.jpg)
Search UI
![Page 40: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/40.jpg)
Modules
![Page 41: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/41.jpg)
cache = Cache(app)cache.init_app(app)cache = Cache(config={'CACHE_TYPE': 'simple'})
#Use a decorator to cache a specific template [email protected](timeout=50)def index(): return render_template('index.html')
Flask Cache
![Page 42: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/42.jpg)
man = CouchDBManager()man.setup(app)
# Create a local proxy to get around the g.couch namespacecouch = LocalProxy(lambda: g.couch)
# Store a document and retrievedocument = dict(title="Hello", content="Hello, world!")couch[some_id] = documentdocument = couch.get(some_id)
Flask CouchDB
![Page 43: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/43.jpg)
from flask_mail import Message
@app.route("/")def index():
msg = Message("Hello", sender="[email protected]", recipients=["[email protected]"])
Flask Mail
![Page 44: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/44.jpg)
from flask import Flask, Response
from flask_principal import Principal, Permission, RoleNeed
app = Flask(__name__)
# load the extension
principals = Principal(app)
# Create a permission with a single Need, in this case a RoleNeed.
admin_permission = Permission(RoleNeed('admin'))
# protect a view with a principal for that need
@app.route('/admin')
@admin_permission.require()
def do_admin_index():
return Response('Only if you are an admin')
Flask Principles
![Page 45: Lightweight web frameworks](https://reader033.fdocuments.net/reader033/viewer/2022052618/554f6ae8b4c9058a148b4f23/html5/thumbnails/45.jpg)
Q&A