$30 off During Our Annual Pro Sale. View Details »

Web development - Code to Deployment

Devi
September 27, 2012

Web development - Code to Deployment

Tutorial in Pycon India 2012

Devi

September 27, 2012
Tweet

More Decks by Devi

Other Decks in Technology

Transcript

  1. What are we going to do • Get introduced to

    Flask and templates ◦ write a simple hello world app • Simple Quotes website ◦ design urls • Get into SQLAlchemy - the database stuff ◦ design the quote model ◦ see how SQLAlchemy works, on terminal ◦ get the basic website working
  2. More to do ... • Learn about SQLAlchemy relationships ◦

    get tags working • Add AJAX ◦ get votes working • Get ready for Heroku ◦ push and deploy !!
  3. "Hello World!" in Flask from flask import Flask app =

    Flask(__name__) @app.route('/') def hello(): return 'Hello World!' if __name__ == '__main__': app.run()
  4. "Hello" app with templates • A template is simply a

    text file, which can generate any text-based format like HTML, XML etc • Jinja2 ◦ templating language for Python ◦ fast, widely used, designer friendly, easy-to-debug and secure ◦ template inheritance support
  5. Now, let's build Quottit A simple website of quotes to

    post, vote, tag, list quotations. • / • /add • /t/<tag_name> • /a/<author_name> • /v/
  6. Quote Model in Flask-SQLAlchemy class Quote(db.Model): __tablename__ = 'quotes' id

    = db.Column(db.Integer, primary_key=True) text = db.Column(db.Text, nullable=False) author = db.Column(db.String(128)) votes = db.Column(db.Integer, default=0) created_at = db.Column(db.DateTime, nullable=False, default=db.func.now())
  7. SQLAlchemy - Insert, Delete, Select, Update >>> q = Quote(text='...',

    author='...') >>> db.session.add(q) >>> db.session.commit() >>> db.session.delete(q) >>> db.session.commit() Methods operating on BaseQuery Object all(), get(), get_or_404() filter(), filter_by() update() order_by(...), group_by() limit()
  8. Add quotes now... class QuoteForm(Form): text = TextAreaField('Quote', [validators.Required()]) author

    = TextField('Author', [validators.Required()]) In Template: <form method="post" action="url_for('add')"> {{form.text.label}}</span>{{form.text(rows=3, cols=50)}} {{form.author.label}}</span>{{form.author(size=50)}} <input type="submit" value="Add"> </form>
  9. In the view: @app.route('/add', methods=['POST']) def add(): form = QuoteForm(request.form)

    if form.validate(): author = slugify(form.author.data) q = Quote(text=form.text.data, author=author) db.session.add(q) db.session.commit() ... if method is GET, data can be accessed as in request. args('<name>') Get the data and validate
  10. Tags - Many-to-many relationships quote_tags = db.Table('quote_tags', db.Column('quote_id', db.Integer, db.ForeignKey('quotes.

    id')), db.Column('tag_id', db.Integer, db.ForeignKey('tags.id')) ) class Tag(db.Model): __tablename__ = 'tags' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), nullable=False) class Quote(db.Model): ... tags = db.relationship('Tag', secondary='quote_tags', backref='quotes')
  11. Add votes through AJAX In the View: @app.route('/v/', methods=['POST']) def

    vote(): rf = request.form vote, qid = int(rf.get('vote')), int(rf.get('qid')) q = Quote.query.get_or_404(qid) if q and vote in (1, -1): Quote.query.filter_by(id=qid).update({'votes':q.votes+vote}) db.session.commit() return jsonify(votes=q.votes) In the template: $.post('/v/', {'qid': parseInt(qid), vote: parseInt(vote)}, function(d){ update_vote(qid, d['votes']); });
  12. Why? • Agile deployment for Python, Ruby, Java etc •

    Get up and running in minutes. • Deploy instantly with git • Never think about servers, instances or VMS! • Scaling is a single command thing How? $ echo "web: python run.py" >> Procfile $ pip freeze > requirements.txt #add psycopg too $ heroku login $ heroku create $ git push heroku master Ready to deployment - Heroku
  13. More on Heroku $ heroku rename NEWAPPNAME #rename your app

    $ heroku logs # what's happenening? $ heroku ps # what are running $ heroku addons:add heroku-postgresql --app $ heroku addons # list the accessories $ heroku config # see/set the configuration variables $ heroku run bash # shell on the server in your app's env $ heroku releases # revision history of deployments $ heroku rollback # oops, revert back the last release $ heroku restart $ heroku scale web=3 worker+1
  14. Deploying with gunicorn Let's use gunicorn as the web server

    instead of the Flask's default HTTP server, which is intended for development. $ echo "gunicorn" >> requirements.txt $ echo "web: gunicorn run:app -b 0.0.0.0:$PORT" > Procfile $ git commit Procfile requirements.txt -m "use gunicorn" $ git push heroku master Yeah, It's that simple !