====== Webapps with Flask ======
===== Starting point =====
==== Frameworks ====
* Flask
* [[https://pythonhosted.org/Flask-SQLAlchemy/index.html|Flask-SQLAlchemy]]
* [[https://flask-restless.readthedocs.org/en/latest|Flask-Restless]]
* Angular.js
Base from: [[https://www.youtube.com/watch?v=2geC50roans#t=599]]
==== First overview ====
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.restless import APIManager
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///digin.db'
db = SQLAlchemy(app)
class Card(db.Model):
id = db.Column(db.Integer, primary_key=True)
front = db.Column(db.Text)
rever = db.Column(db.Text)
db.create_all()
api_manager = APIManager(app, flask_sqlalchemy_db=db)
api_manager.create_api(Card, methods=['GET', 'POST', 'DELETE', 'PUT'])
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
It allows to access to different urls:
* [[http://127.0.0.1:5000/api/card]]
* [[http://127.0.0.1:5000/api/card/1]]
===== Model =====
==== Interact with model classes ====
Only importing the code file and using the class you will be interacting with the data base:
from person_app import Person
from person_app import db
p = Person(name='Juan', age=33)
Person.query.all()
db.session.add(p)
db.session.commit()
==== Relationships with SQLAlchemy ====
=== One to one ===
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
addresses = db.relationship('Address', backref='person',
lazy='dynamic')
class Address(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(50))
person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
=== One to many ===
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
addresses = db.relationship('Address',
backref=db.backref('person', lazy='joined'), lazy='dynamic')
=== Many to many ===
tags = db.Table('tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
)
class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
tags = db.relationship('Tag', secondary=tags,
backref=db.backref('pages', lazy='dynamic'))
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
=== Define fields ===
class Deck(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, nullable=False)
date = db.Column(db.DateTime, default=datetime.now())
cards = db.relationship('Card', backref='deck', lazy='dynamic')
class Card(db.Model):
id = db.Column(db.Integer, primary_key=True)
id_deck = db.Column(db.Integer,
db.ForeignKey('deck.id'),
nullable=False)
front = db.Column(db.Text)
rever = db.Column(db.Text)
=== Separate model in another file ===
The ''flaskext.sqlalchemy'' module does not have to be initialized with the app right away - you can do this instead:
# apps.members.models
from flaskext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Member(db.Model):
# fields here
pass
And then in your application setup you can call init_app:
# apps.application.py
from flask import Flask
from apps.members.models import db
app = Flask(__name__)
# later on
db.init_app(app)
Example:
# apps.shared.models
from flaskext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
# apps.members.models
from apps.shared.models import db
class Member(db.Model):
# TODO: Implement this.
pass
# apps.reporting.members
from flask import render_template
from apps.members.models import Member
def report_on_members():
# TODO: Actually use arguments
members = Member.filter(1==1).all()
return render_template("report.html", members=members)
# apps.reporting.routes
from flask import Blueprint
from apps.reporting.members import report_on_members
reporting = Blueprint("reporting", __name__)
reporting.route("/member-report", methods=["GET","POST"])(report_on_members)
# apps.application
from flask import Flask
from apps.shared import db
from apps.reporting.routes import reporting
app = Flask(__name__)
db.init_app(app)
app.register_blueprint(reporting)
Another example:
app = Flask(__name__, static_path='')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///digin.db'
db.init_app(app)
with app.app_context():
db.create_all()
===== HTML and JavaScript =====
==== Install JS libraries ====
$ sudo apt-get install nodejs
$ sudo apt-get install npm
$ sudo npm install -g bower
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
Inside the static folder...
$ bower install angular