I am using flask-restplus
to create a RESTful API which connects to a MongoDB collection and provides information according to the API called.
API Design
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": {
...
}
}
Current Implementation
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')
Tests
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?