Python Guild
2018.03.21
Web development with Flask
Flask is simple
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
And easy to setup
pip install flask
But it's also very flexible and modular
cat requirements.txt |grep flask
flask flask-admin
flask-sqlalchemy
flask-restful
flask-wtf
flask-login
flask-hashing
Simplicity is easy to abuse
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
@app.route("/user/login")
def login():
return "Hello World!"
@app.route("/user/signup")
def signup():
return "Hello World!"
@app.route("/video/upload")
def upload():
return "ddd"
@app.route("/Whatever")
def upload():
return "ddd"
This can turn ugly quickly. Use blueprints!
app.register_blueprint(home, url_prefix='/')
app.register_blueprint(user, url_prefix='/user')
app.register_blueprint(video, url_prefix='/video')
DB access?
SELECT * from ??
Rather not..
Use sqlalchemy!
user = db.session.query(models.Users).filter(models.Users.name == username).first()
Create table??
No.
Use Alembic for your migrations
ALCHEMY_URL=mysql+mysqlconnector://root:emarroot@localhost:3306/porghub APP_SECRET=mydevsecret alembic upgrade head
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 86bba768a6c8, Added initial tables
Server?
python app.py?
Werkzeug is ok for development, but for prod we might need something more heavy.
UWSGI/GUNICORN
Static files?
Flask can serve static files, if you really want it, but why would you do that?
Use NGINX like you would normally
server{
listen 80;
location /static {
root /usr/src;
}
location /{
include uwsgi_params;
uwsgi_pass uwsgi:3031;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}With time you'll need an admin interface
Why code, when you dont have to?
flask-admin
admin.add_view(MyModelView(models.Users, db.session,
column_list=['id', 'name', "description", "is_active", "is_admin"],
search_fields=['username'],
form_columns=['id', 'name', "description", "is_active", "is_admin"]))
Sessions?
session['userid'] = 'ugly'
use flask-login
user = db.session.query(models.Users).filter(models.Users.name == username).first()
if not user or user and not hashing.check_value(user.password, password, settings.SECRET):
flash("Failed to log you in with these credentials")
return render_template("login.html", form=form)
else:
#login
login_user(user)
return redirect('//')
Forms, and views
Flask-wtf
Jinja2
Template inheritance
Validations
Fun
login.html
{% extends "base.html" %}
{% block container %}
<body>
<div class = "container">
<h4>Register</h4>
<br>
{% from "_formhelpers.html" import render_field %}
<form method=post action="/user/login">
<dl>
{{render_field(form.username)}}
{{render_field(form.password)}}
<input name=_csrf_token type=hidden value="{{ csrf_token() }}">
</dl>
<p><input type=submit value=Login></p>
</form>
{% if error %}
<p class="error"><strong>Error:</strong>{{error}}</p>
{% endif %}
</div>
</body>
{% endblock %}
login form
class LoginForm(Form):
username = StringField('Username', [validators.DataRequired()])
password = PasswordField('Password', [validators.DataRequired()])
asdasdasda
By Bálint Csergő
asdasdasda
- 537