-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathflask_api.py
More file actions
241 lines (177 loc) · 6.99 KB
/
Copy pathflask_api.py
File metadata and controls
241 lines (177 loc) · 6.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, jsonify, abort, request, url_for, g
from flask.ext.httpauth import HTTPBasicAuth
from models import movies, users, User
auth = HTTPBasicAuth()
app = Flask(__name__)
@app.route("/api/movies/", methods=['GET'])
@auth.login_required
def get_all_movies():
"""
only called in response to a 'GET' request.
return a list of all movie objects
"""
limit = int(request.args.get('limit', 10))
offset = int(request.args.get('offset', 0))
end = limit + offset
filter_query = request.args.get('filter', None)
return_movies = []
if filter_query:
filter_query = filter_query.replace("+"," ")
filters = filter_query.split(',')
for filter_str in filters:
[return_movies.append(movie) for movie in movies[offset:end] if filter_str in movie.values()]
# Using list comprehesion to say:
# for movie in movies[offset:end]:
# if filter_str in movie.values():
# return_movies.append(movie)
else:
return_movies = movies[offset:end]
return jsonify({"movies": return_movies})
# Uncomment to return a URI rather than strict ID for objects.
# return jsonify({'movies': [convert_id_to_uri(movie) for movie in return_movies]})
@app.route('/api/movies/', methods=['POST'])
@auth.login_required
def create_movie_object():
"""
only called in response to a 'POST' request.
Creates and persists a new movie object
return the saved movie object
"""
# Check to see if the json is there, and if it has the required fields.
if not request.json or not 'Title' in request.json or not 'Year' in request.json:
abort(400, {'message': 'Required fields Title, Year not in request.'})
# abort(400)
# Generate a new object from the request to save to DB.
movie = {
'id': movies[-1]['id'] + 1,
'Title': request.json['Title'],
'Plot': request.json.get('Plot', u""),
'Year': request.json['Year'],
'Rated': request.json.get('Rated', u""),
'Released': request.json.get('Released', u""),
'Runtime': request.json.get('Runtime', u""),
'Genre': request.json.get('Genre', u""),
'Director': request.json.get('Director', u""),
'Writer': request.json.get('Writer', u""),
'Actors': request.json.get('Actors', u""),
'Language': request.json.get('Language', u""),
'Country': request.json.get('Country', u""),
'Awards': request.json.get('Awards', u""),
'Poster': request.json.get('Poster', u""),
'Metascore': request.json.get('Metascore', u""),
'imdbRating': request.json.get('imdbRating', u"")
}
# save the new object. If you using an ORM, would be something like
# object.save()
movies.append(movie)
return jsonify({'movie': movie}), 201
@app.route('/api/movies/<int:movie_id>', methods=['GET'])
@auth.login_required
def get_movie_by_id(movie_id):
"""
only called in response to a 'GET' request.
return a movie object by id
"""
movie = [movie for movie in movies if movie['id'] == movie_id]
if len(movie) == 0:
abort(404)
return jsonify({'movie': movie[0]})
# return jsonify({'movie': convert_id_to_uri(movie[0])})
@app.route('/api/movies/<int:movie_id>', methods=['PUT'])
@auth.login_required
def update_task(movie_id):
# Get the object to update
movie = [movie for movie in movies if movie['id'] == movie_id]
# Validate the data
# Does the object exits?
if len(movie) == 0:
abort(404)
# Is there json in the request?
if not request.json:
abort(400, {'message': 'No json found in request'})
# Are the values valid types?
for key in movie[0]:
if key in request.json and type(request.json[key]) is not type(movie[0][key]):
message = "%s is %s. %s passed in from request" % (key, type(movie[0][key]), type(request.json[key]))
abort(400, {'message': message})
# This is a sample:
# We could write a test case for each field individually.
# if 'Title' in request.json and type(request.json['Title']) != unicode:
# abort(400, {'message': 'Title is not unicode'})
# Once everything looks good, update the object.
# Here we are saying use the value from the request if it exists,
# otherwise, default to the value already stored.
for key, value in movie[0].iteritems():
if key is not 'id':
print "%s > JSON: %s || Object: %s" % (key, request.json.get(key, "Not here"), str(value))
movie[0][key] = request.json.get(key, value)
return jsonify({'movie': movie[0]})
@app.route('/api/movies/<int:movie_id>', methods=['DELETE'])
@auth.login_required
def delete_task(movie_id):
# Get the object to delete
movie = [movie for movie in movies if movie['id'] == movie_id]
# Does the object exits?
if len(movie) == 0:
abort(404)
# Delete the object from the data store
movies.remove(movie[0])
# Return success!
return jsonify({'result': True})
@app.route('/api/users/', methods=['GET'])
def get_users():
# tmp_user = []
# for user in users:
# tmp_user.append(user.get_json())
return jsonify({"users":[user.get_json() for user in users]})
@app.route('/api/users/', methods=['POST'])
def create_user():
"""
only called in response to a 'POST' request.
Creates and persists a new user object
return the saved user object
"""
# Check to see if the json is there, and if it has the required fields.
if not request.json or not 'user' in request.json or not 'password' in request.json:
abort(400, {'message': 'Required fields "user", "password" not in request.'})
user = User(request.json['user'], request.json['password'])
# save the new object. If you using an ORM, would be something like
# object.save()
user.save()
return jsonify({'user': user.get_json()}), 201
@auth.verify_password
def verify_password(username, password):
user = [user for user in users if user.username == username]
if len(user) == 0 or not user[0].verify_password(password):
return False
g.user = user[0]
return True
#########################
# Custom Error Handling #
#########################
@app.errorhandler(400)
def custom400(error):
response = jsonify({'message': error.description['message'],
'status_code': 400,
'status': 'Bad Request'})
return response, 400
####################
# Helper Functions #
####################
def convert_id_to_uri(movie):
tmp = {}
for field in movie:
if field == 'id':
tmp['uri'] = url_for('get_movie_by_id',
movie_id=movie['id'],
_external=True)
else:
tmp[field] = movie[field]
return tmp
if __name__ == "__main__":
user = User("twaits", "Passphrase1")
user.save()
print user.__dict__
app.run(debug=True)