Created
February 25, 2019 17:38
-
-
Save cuahutli/90394ad8809af4c3ca1160252e2acc52 to your computer and use it in GitHub Desktop.
Ejemplo de como crear una api con Flask que incluye conexión a Base de Datos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
from flask import Flask, abort, request, jsonify, g, url_for | |
from flask.ext.sqlalchemy import SQLAlchemy | |
from sqlalchemy.inspection import inspect | |
from flask.ext.httpauth import HTTPBasicAuth | |
from passlib.apps import custom_app_context as pwd_context | |
from itsdangerous import (TimedJSONWebSignatureSerializer | |
as Serializer, BadSignature, SignatureExpired) | |
# initialization | |
app = Flask(__name__) | |
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog' | |
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' | |
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True | |
# extensions | |
db = SQLAlchemy(app) | |
auth = HTTPBasicAuth() | |
class ToJson(object): | |
def to_json(self): | |
return {c: getattr(self, c) for c in inspect(self).attrs.keys()} | |
@staticmethod | |
def to_json_list(l): | |
return [m.to_json() for m in l] | |
class User(db.Model, ToJson): | |
__tablename__ = 'users' | |
id = db.Column(db.Integer, primary_key=True) | |
username = db.Column(db.String(32), index=True) | |
password_hash = db.Column(db.String(64)) | |
def hash_password(self, password): | |
self.password_hash = pwd_context.encrypt(password) | |
def verify_password(self, password): | |
return pwd_context.verify(password, self.password_hash) | |
def generate_auth_token(self, expiration=30): | |
s = Serializer(app.config['SECRET_KEY'], expires_in=expiration) | |
return s.dumps({'id': self.id}) | |
def to_json(self): | |
d = ToJson.to_json(self) #se genera el json | |
del d['password_hash'] #se excluye del resultado el campo password_hash | |
return d | |
@staticmethod | |
def verify_auth_token(token): | |
s = Serializer(app.config['SECRET_KEY']) | |
try: | |
data = s.loads(token) | |
except SignatureExpired: | |
return None # valid token, but expired | |
except BadSignature: | |
return None # invalid token | |
user = User.query.get(data['id']) | |
return user | |
@auth.verify_password | |
def verify_password(username_or_token, password): | |
# first try to authenticate by token | |
user = User.verify_auth_token(username_or_token) | |
if not user: | |
# try to authenticate with username/password | |
user = User.query.filter_by(username=username_or_token).first() | |
if not user or not user.verify_password(password): | |
return False | |
g.user = user | |
return True | |
@app.route('/api/users', methods=['POST']) | |
def new_user(): | |
username = request.json.get('username') | |
password = request.json.get('password') | |
print username | |
if username is None or password is None: | |
print "entre" | |
abort(400) # missing arguments | |
if User.query.filter_by(username=username).first() is not None: | |
print "aqui ando" | |
print User.query.filter_by(username=username).first() | |
abort(400) # existing user | |
user = User(username=username) | |
user.hash_password(password) | |
db.session.add(user) | |
db.session.commit() | |
return (jsonify({'username': user.username}), 201, | |
{'Location': url_for('get_user', id=user.id, _external=True)}) | |
@app.route('/api/users/<int:id>') | |
def get_user(id): | |
user = User.query.get(id) | |
if not user: | |
abort(400) | |
return jsonify(user.to_json()) | |
@app.route('/api/users/list') | |
def get_users(): | |
users = User.query.all() | |
return jsonify({'users':User.to_json_list(users)}) | |
@app.route('/api/token') | |
@auth.login_required | |
def get_auth_token(): | |
token = g.user.generate_auth_token(600) | |
return jsonify({'token': token.decode('ascii'), 'duration': 600}) | |
@app.route('/api/resource') | |
@auth.login_required | |
def get_resource(): | |
return jsonify({'data': 'Hello, %s!' % g.user.username}) | |
if __name__ == "__main__": | |
if not os.path.exists('db.sqlite'): | |
db.create_all() | |
# app.run(debug = True) | |
# app.run(host=os.getenv('host','0.0.0.0'), port=int(os.getenv('port',8080))) | |
app.debug = True | |
app.run(port=int(os.getenv('port',8080))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment