Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web development - Code to Deployment

Avatar for Devi Devi
September 27, 2012

Web development - Code to Deployment

Tutorial in Pycon India 2012

Avatar for Devi

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 !