Skip to content

Commit

Permalink
Update REST API to be more parsimonious and thus faster!
Browse files Browse the repository at this point in the history
  • Loading branch information
jlegrand62 committed Aug 28, 2024
1 parent 128ee2c commit d26aeb3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 83 deletions.
6 changes: 3 additions & 3 deletions src/plantdb/cli/fsdb_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from plantdb.rest_api import PointCloudGroundTruth
from plantdb.rest_api import Refresh
from plantdb.rest_api import Scan
from plantdb.rest_api import ScanList
from plantdb.rest_api import ScansList
from plantdb.rest_api import Sequence
from plantdb.test_database import DATASET
from plantdb.test_database import test_database
Expand Down Expand Up @@ -78,8 +78,8 @@ def main():
logger.info(f"Found {len(db.list_scans())} scans dataset to serve in local plant database.")

# Initialize RESTful resources to serve:
api.add_resource(ScanList, '/scans',
resource_class_args=tuple([db, logger]))
api.add_resource(ScansList, '/scans',
resource_class_args=tuple([db]))
api.add_resource(Scan, '/scans/<string:scan_id>',
resource_class_args=tuple([db, logger]))
api.add_resource(File, '/files/<path:path>',
Expand Down
69 changes: 15 additions & 54 deletions src/plantdb/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
from flask import send_file
from flask import send_from_directory
from flask_restful import Resource
from jinja2.sandbox import unsafe

from plantdb import webcache
from plantdb.io import read_json
from plantdb.log import configure_logger
Expand Down Expand Up @@ -174,53 +176,6 @@ def get_scan_template(scan_id: str, error=False) -> dict:
}


def list_scans_info(scans, query=None, **kwargs):
"""List scans information.
Parameters
----------
scans : list of plantdb.fsdb.Scan
The list of scan instances to get information from.
query : str, optional
A scan filtering query, to be matched in the scan metadata.
Other Parameters
----------------
logger : logging.Logger
A logger to use with this method, default to a logger created on the fly with a `module.function` name.
Returns
-------
list of dict
The list of scans information dictionaries.
Examples
--------
>>> from plantdb.rest_api import list_scans_info
>>> from plantdb.test_database import test_database
>>> db = test_database('real_plant_analyzed')
>>> db.connect()
>>> scans_info = list_scans_info(db.get_scans())
>>> print(scans_info)
[{'id': 'real_plant_analyzed', 'metadata': {'date': '2023-12-15 16:37:15', 'species': 'N/A', 'plant': 'N/A', 'environment': 'Lyon indoor', 'nbPhotos': 60, 'files': {'metadatas': None, 'archive': None}}, 'thumbnailUri': '', 'hasTriangleMesh': True, 'hasPointCloud': True, 'hasPcdGroundTruth': False, 'hasCurveSkeleton': True, 'hasAnglesAndInternodes': True, 'hasSegmentation2D': False, 'hasSegmentedPcdEvaluation': False, 'hasPointCloudEvaluation': False, 'hasManualMeasures': False, 'hasAutomatedMeasures': True, 'hasSegmentedPointCloud': False, 'error': False, 'hasTreeGraph': True}]
>>> db.disconnect()
"""
logger = kwargs.get("logger", configure_logger(__name__))

res = []
for scan in scans:
metadata = scan.get_metadata()
if query is not None and not (query.lower() in json.dumps(metadata).lower()):
continue # filter scans info list by matching the query with metadata keys
try:
scan_info = get_scan_info(scan)
except:
logger.error(f"Could not obtain information from scan dataset '{scan.id}'...")
scan_info = get_scan_template(scan.id, error=True)
res.append(scan_info)
return res


def get_scan_info(scan, **kwargs):
"""Get the information related to a single scan dataset.
Expand Down Expand Up @@ -501,12 +456,11 @@ def get_scan_data(scan, **kwargs):
return scan_data


class ScanList(Resource):
class ScansList(Resource):
"""Concrete RESTful resource to serve the list of scan datasets and some info upon request (GET method)."""

def __init__(self, db, logger):
def __init__(self, db):
self.db = db
self.logger = logger

def get(self):
"""Returns a list of scan dataset information.
Expand All @@ -523,13 +477,19 @@ def get(self):
>>> import json
>>> # Get an info dict about all dataset:
>>> res = requests.get("http://127.0.0.1:5000/scans")
>>> scans = json.loads(res.content)
>>> scans_list = json.loads(res.content)
>>> # List the known dataset id:
>>> print([scan['id'] for scan in scans])
>>> print(scans_list)
['arabidopsis000', 'virtual_plant_analyzed', 'real_plant_analyzed', 'real_plant', 'virtual_plant', 'models']
>>> res = requests.get('http://127.0.0.1:5000/scans?filterQuery={"object":{"species":"Arabidopsis.*"}}&fuzzy="true"')
>>> res.content.decode()
"""
return list_scans_info(self.db.get_scans(), query=request.args.get('filterQuery'), logger=self.logger)
query = request.args.get('filterQuery', None)
fuzzy = request.args.get('fuzzy', False, type=bool)
if query is not None:
query = json.loads(query)
return self.db.list_scans(query=query, fuzzy=fuzzy)


class Scan(Resource):
Expand Down Expand Up @@ -565,7 +525,8 @@ def get(self, scan_id):
2024-08-19 11:12:25
"""
return get_scan_data(self.db.get_scan(scan_id), logger=self.logger)
#return get_scan_data(self.db.get_scan(scan_id), logger=self.logger)
return get_scan_info(self.db.get_scan(scan_id), logger=self.logger)


class File(Resource):
Expand Down
53 changes: 27 additions & 26 deletions src/plantdb/rest_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,31 @@ def test_db_availability(host=REST_API_URL, port=REST_API_PORT):
return True


def list_scan_names(host=REST_API_URL, port=REST_API_PORT):
"""List the names of the scan datasets served by the PlantDB REST API.
Parameters
----------
host : str, optional
The IP address of the PlantDB REST API. Defaults to ``"127.0.0.1"``.
port : str or int, optional
The port of the PlantDB REST API. Defaults to ``5000``.
Returns
-------
list
The list of scan dataset names served by the PlantDB REST API.
Examples
--------
>>> from plantdb.rest_api_client import list_scan_names
>>> # This example requires the PlantDB REST API to be active (`fsdb_rest_api --test` from plantdb library)
>>> print(list_scan_names())
['arabidopsis000', 'real_plant', 'real_plant_analyzed', 'virtual_plant', 'virtual_plant_analyzed']
"""
return sorted(requests.get(url=f"{base_url(host, port)}/scans").json())


def get_scans_info(host=REST_API_URL, port=REST_API_PORT):
"""Retrieve the information dictionary for all scans from the PlantDB REST API.
Expand All @@ -116,7 +141,8 @@ def get_scans_info(host=REST_API_URL, port=REST_API_PORT):
>>> # This example requires the PlantDB REST API to be active (`fsdb_rest_api --test` from plantdb library)
>>> get_scans_info()
"""
return requests.get(url=f"{base_url(host, port)}/scans").json()
scan_list = list_scan_names(host, port)
return [requests.get(url=f"{base_url(host, port)}/scans/{scan}").json() for scan in scan_list]


def parse_scans_info(host=REST_API_URL, port=REST_API_PORT):
Expand Down Expand Up @@ -180,31 +206,6 @@ def get_scan_data(scan_id, host=REST_API_URL, port=REST_API_PORT):
return requests.get(url=f"{base_url(host, port)}/scans/{scan_id}").json()


def list_scan_names(host=REST_API_URL, port=REST_API_PORT):
"""List the names of the scan datasets served by the PlantDB REST API.
Parameters
----------
host : str, optional
The IP address of the PlantDB REST API. Defaults to ``"127.0.0.1"``.
port : str or int, optional
The port of the PlantDB REST API. Defaults to ``5000``.
Returns
-------
list
The list of scan dataset names served by the PlantDB REST API.
Examples
--------
>>> from plantdb.rest_api_client import list_scan_names
>>> # This example requires the PlantDB REST API to be active (`fsdb_rest_api --test` from plantdb library)
>>> print(list_scan_names())
['arabidopsis000', 'real_plant', 'real_plant_analyzed', 'virtual_plant', 'virtual_plant_analyzed']
"""
return sorted(parse_scans_info(host, port).keys())


def scan_preview_image_url(scan_id, host=REST_API_URL, port=REST_API_PORT, size="thumb"):
"""Get the URL to the preview image for a scan dataset served by the PlantDB REST API.
Expand Down

0 comments on commit d26aeb3

Please sign in to comment.