123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #!/bin/env python
- from flask import Flask
- from flask_restful import reqparse, abort, Api, Resource
- from flask_httpauth import HTTPBasicAuth
- from flask_sqlalchemy import SQLAlchemy
- import json
- # 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__)
- app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
- db = SQLAlchemy(app)
- api = Api(app)
- class Todo(db.Model):
- id = db.Column(db.Integer, primary_key=True)
- name = db.Column(db.String(20), unique=True, nullable=False)
- detail = db.Column(db.String(200), unique=False, nullable=False)
- def __repr__(self):
- return '<Todo {0}: {1}'.format(self.id, self.name)
- def serialize(self):
- return {'id': self.id, 'name': self.name, 'detail': self.detail}
- TODOS = {
- 'todo1': {'task': 'build an API'},
- 'todo2': {'task': '?????'},
- 'todo3': {'task': 'profit!'},
- }
- def abort_if_todo_doesnt_exist(todo_id):
- task = Todo.query.filter_by(id=todo_id).first()
- if task is None:
- abort(404, message="Todo {} doesn't exist".format(todo_id))
- return task
- # 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 TodoPath(Resource):
- def get(self, todo_id):
- t = abort_if_todo_doesnt_exist(todo_id)
- return { 'id': t.id, 'name': t.name, 'detail': t.detail }
- def delete(self, todo_id):
- t = abort_if_todo_doesnt_exist(todo_id)
- db.session.delete(t)
- db.session.commit()
- 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 = Todo(name=todo_id, detail=t)
- db.session.add(task)
- db.session.commit()
- return task.id, 201
- # TodoList
- # shows a list of all todos, and lets you POST to add new tasks
- class TodoList(Resource):
- def get(self):
- tasks = Todo.query.all()
- return [t.serialize() for t in tasks]
- # 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', '/todos/')
- # api.add_resource(TodoList, '/todos/')
- api.add_resource(TodoPath, '/todos/<todo_id>')
- if __name__ == '__main__':
- app.run(port=11022, debug=True)
|