Building RESTful APIs with Flask
Flask is excellent for building REST APIs. You can use core Flask or extensions like Flask-RESTful for more structure.
Basic API Endpoint
from flask import jsonify
@app.route('/api/users')
def get_users():
users = User.query.all()
return jsonify([user.serialize() for user in users])
Flask-RESTful
from flask_restful import Api, Resource
api = Api(app)
class UserAPI(Resource):
def get(self, user_id):
user = User.query.get_or_404(user_id)
return user.serialize()
def put(self, user_id):
# Update user
pass
def delete(self, user_id):
# Delete user
pass
api.add_resource(UserAPI, '/api/users/<int:user_id>')
Request Parsing
from flask_restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('username', type=str, required=True)
parser.add_argument('email', type=str, required=True)
class UserListAPI(Resource):
def post(self):
args = parser.parse_args()
# Create new user with args
Authentication for APIs
from flask_httpauth import HTTPBasicAuth
auth = HTTPBasicAuth()
@auth.verify_password
def verify_password(username, password):
user = User.query.filter_by(username=username).first()
if user and check_password_hash(user.password, password):
return user
class PrivateAPI(Resource):
@auth.login_required
def get(self):
return {'message': 'Hello, %s!' % auth.current_user().username}
JWT Authentication
from flask_jwt_extended import JWTManager, jwt_required, create_access_token
app.config['JWT_SECRET_KEY'] = 'super-secret'
jwt = JWTManager(app)
@app.route('/api/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
user = User.query.filter_by(username=username).first()
if user and check_password_hash(user.password, password):
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token)
return jsonify({"msg": "Bad credentials"}), 401
@app.route('/api/protected')
@jwt_required()
def protected():
return jsonify(logged_in_as=current_user), 200
API Documentation
from flask_swagger_ui import get_swaggerui_blueprint
SWAGGER_URL = '/api/docs'
API_URL = '/static/swagger.json'
swaggerui_blueprint = get_swaggerui_blueprint(
SWAGGER_URL,
API_URL,
config={'app_name': "My API"}
)
app.register_blueprint(swaggerui_blueprint, url_prefix=SWAGGER_URL)
API Best Practices
- Use proper HTTP status codes
- Implement versioning (e.g., /api/v1/)
- Use consistent naming conventions
- Implement proper error handling
- Consider rate limiting