Reputation: 3349
I am using flask-restplus
to create a RESTful API which connects to a MongoDB collection and provides information according to the API called.
HTTP GET
api/hashdoc/<str:product_id>
function: provides all a list
of the relevant information for the given product_id
in the Database.
example response:
[
{
"product_id": "ABC",
"metadata": {
...
},
"time_info": {
....
}
},
{
"product_id": "ABC",
"metadata": {
...
},
"time_info": {
...
}
}
]
HTTP GET
api/hashdoc/<str:product_id>?from=<str:ISO8601_timestamp>&to=<str:ISO8601_timestamp>
function: Should Provide a JSON response of information filtered using from
and to
values in the Database
example response:
{
"product_id": "ABC",
"metadata": {
...
},
"time_info": {
...
}
}
Within my hashdoc.py
I have the following code:
from flask import request, abort
from flask_restplus import Namespace, Resource, fields, reqparse
from databases.documentdb import mongo
# API
api = Namespace('hashdoc', description='Hash Document Operations')
# REQUEST PARSER HERE
event_duration_parser = reqparse.RequestParser()
event_duration_parser.add_argument('from', type=str, required=True, help='ISO8601 UTC Timestamp (ms precision)')
event_duration_parser.add_argument('to', type=str, required=True, help='ISO8601 UTC Timestamp (ms precision)')
## hash_doc = api.model(....) removed for brewity
@api.route('/<product_id>')
@api.param('product_id', 'EPC Product ID')
@api.response(404, 'No Values Exist for given Product ID.')
class HashDocListResource(Resource):
@api.marshal_list_with(hash_doc)
def get(self, product_id):
'''Fetch Hash Documents for given Product ID'''
print(product_id)
product_hash_doc = mongo.db['HashData'].find({'product_id': product_id}, {'_id': 0})
list_product_hashdoc = list(product_hash_doc)
if len(list_product_hashdoc):
return list_product_hashdoc, 200
else:
abort(404, {'error': 'No Values Exist for given Product ID.'})
@api.route('/<product_id>')
@api.param('product_id', 'EPC Product ID')
@api.response(404, 'No Values Exist for given Product ID & Time Range')
class HashDocResource(Resource):
@api.expect(event_duration_parser)
@api.marshal_with(hash_doc)
def get(self, product_id):
args = event_duration_parser.parse_args()
from_time = args.get('from')
to_time = args.get('to')
product_hash_doc_for_time_range = mongo.db['HashData'].find_one(
{'product_id': product_id,
# Filtering based on TIMESTAMPS HERE
{'_id': 0})
if product_hash_doc_for_time_range:
return product_hash_doc_for_time_range, 200
else:
abort(404, 'No Values Exist for given Product ID & Time Range')
with curl
I perform the following:
curl -XGET http://localhost:5000/api/hashdoc/ABC
which provides me the list
of the hash documents and the behaviour is correct. However when I do the following:
curl -XGET http://localhost:5000/api/hashdoc/ABC?from\="2019-11-05T14:32:31.830000Z"\&to\="2019-11-05T14:46:00.444000Z"
The Flask app still queries the api/hashdoc/ABC
and provides me the list and not the filtered document here.
How does one manage such API with request parameters? Does one need to implement them separately?
Does one have to perform a check if the from
and to
are not None
in the same resource class and then perform the query?
Upvotes: 0
Views: 433
Reputation: 2274
The Flask app still queries the api/hashdoc/ABC and provides me the list and not the filtered document here.
You created two resource classes with same route url. So it uses the one it sees first (which in your case is the HashDocListResource
).
How does one manage such API with request parameters? Does one need to implement them separately?
No, you don't make separate resource classes just for query params.
Does one have to perform a check if the from and to are not None in the same resource class and then perform the query?
Yes.
I am not sure why you are using find
in HashDocListResource
but find_one
in HashDocResource
. Is it that there can only be one HashDoc in given time range?
Sample implementation of the same.
from flask import request, abort
from flask_restplus import Namespace, Resource, fields, reqparse
from databases.documentdb import mongo
# API
api = Namespace('hashdoc', description='Hash Document Operations')
# REQUEST PARSER HERE
event_duration_parser = reqparse.RequestParser()
event_duration_parser.add_argument('from', type=str, required=True, help='ISO8601 UTC Timestamp (ms precision)')
event_duration_parser.add_argument('to', type=str, required=True, help='ISO8601 UTC Timestamp (ms precision)')
## hash_doc = api.model(....) removed for brewity
@api.route('/<product_id>')
@api.param('product_id', 'EPC Product ID')
@api.response(404, 'No Values Exist for given Product ID.')
class HashDocListResource(Resource):
@api.expect(event_duration_parser)
@api.marshal_list_with(hash_doc)
def get(self, product_id):
'''Fetch Hash Documents for given Product ID'''
args = event_duration_parser.parse_args()
from_time = args.get('from')
to_time = args.get('to')
query = {
'product_id': product_id,
}
if from_time and to_time:
query['your_time_stamp_field'] = {
'$lte': to_time
}
query['your_time_stamp_field'] = {
'$gte': from_time
}
projection = {'_id': 0}
product_hash_docs = mongo.db['HashData'].find(query, projection)
list_product_hashdoc = list(product_hash_docs)
if len(list_product_hashdoc):
return list_product_hashdoc, 200
else:
abort(404, {'error': 'No Values Exist for given Product ID.'})
Upvotes: 1