#!/bin/env python from flask import Flask from flask_restful import reqparse, abort, Api, Resource from flask_httpauth import HTTPBasicAuth # This "protects" paths with @auth.login_required auth = HTTPBasicAuth() # This is a very basic (and dumb) security model # We'll actually want the @auth.verify_password model, # which will let us use hashed passwords, etc. @auth.get_password def get_password(username): if username == 'admin': return '12345' return None @auth.error_handler def unauthorized(): return abort(401, message='Unauthorized access') app = Flask(__name__) api = Api(app) TODOS = { 'todo1': {'task': 'build an API'}, 'todo2': {'task': '?????'}, 'todo3': {'task': 'profit!'}, } def abort_if_todo_doesnt_exist(todo_id): if todo_id not in TODOS: abort(404, message="Todo {} doesn't exist".format(todo_id)) parser = reqparse.RequestParser() parser.add_argument('task') # Todo # shows a single todo item and lets you delete a todo item # Yes! You can add the @auth.login_required to methods of the class. ! \o/ ! class Todo(Resource): def get(self, todo_id): abort_if_todo_doesnt_exist(todo_id) return TODOS[todo_id] def delete(self, todo_id): abort_if_todo_doesnt_exist(todo_id) del TODOS[todo_id] return '', 204 @auth.login_required def put(self, todo_id): args = parser.parse_args() t = args['task'] if t is None: abort(400, message="I need text for the task. task=...") task = {'task': args['task']} TODOS[todo_id] = task return task, 201 # TodoList # shows a list of all todos, and lets you POST to add new tasks class TodoList(Resource): def get(self): return TODOS def post(self): args = parser.parse_args() todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1 todo_id = 'todo%i' % todo_id TODOS[todo_id] = {'task': args['task']} return TODOS[todo_id], 201 ## ## Actually setup the Api resource routing here ## api.add_resource(TodoList, '/todos') api.add_resource(Todo, '/todos/') if __name__ == '__main__': app.run(port=11022, debug=True)