Adding an API#
On this page you can find information relating to the steps required to add an API call handler to scrappi.
Creating an API Call Handler Class#
Most API’s download data from online catalogues.
These API call handlers all inherit from scrappi.api.base.BaseAPICallHandler and can make use of methods
within the class.
Required#
API call handlers all inherit from scrappi.api.base.BaseAPICallHandler and must therefore
contain the following methods, properties and attributes:
Docstring |
Extra Info |
||
|---|---|---|---|
@abstractmethods |
|||
|
|
||
|
|
Currently downloaded metadata are saved in folders within the path specified according to their acquisition date, e.g. ‘path/2022/08/21’ |
|
|
|
Currently downloaded products are saved in folders within the path specified according to their acquisition date, e.g. ‘path/2022/08/21’ |
|
@properties |
|||
|
|
Acceptable product types are ones from eodag, so |
|
class attributes |
|||
|
|
Name of api call handler, e.g. eodag |
New API’s should also be added to scrappi.api.factory.
Suggested implementations for abstract methods (using base class methods)#
A number of similar methods have been implemented across different API Call Handler Classes which might be useful to those considering contributing their own API Call Handler to scrappi. The format of these methods and their purpose can be found below.
Useful methods to consider implementing#
def _set_datetime(self, date_time):
"""
Convert input datetime to a datetime suited to the api query format
:param date_time: input datetime string or object
:return: datetime formatted in whichever way the api requires
"""
return self._get_datetime(date_time) # in required format for api querying
def _set_geom(self, geom):
"""
Convert input geometries to ones suited to the api query format
:param geom: input geometry
:return: geometry formatted in whichever way the api requires
"""
geom = self._get_geom(geom) # check and change geometries
if isinstance(geom, dict):
return geom # in required format for api querying
if isinstance(
geom,
(
shapely.geometry.base.BaseGeometry,
shapely.geometry.base.BaseMultipartGeometry,
),
):
return geom # in required format for api querying
else:
return geom # in required format for api querying
def _set_product_type(self, collection):
"""
Return appropriate product type for api
:param collection: collection name corresponding to desired product type
:return: corresponding product type required for querying the api
"""
product_type = self._get_product_type(collection) # check valid product type for api
return product_type # in required format for api querying
Suggested abstract method implementations#
Example perform_query implementation:
def perform_query(self, query: dict) -> list:
"""
Return catalogue product objects that satisfy query
:param query: catalogue query
:return: product objects satisfying query
"""
# convert input query to a style suitable for api
new_query = {
"dataset": self._set_product_type(query["collections"][0]),
"bbox": self._set_geom(query["geom"]),
"start_date": self._set_datetime(query["start_time"]),
"end_date": self._set_datetime(query["stop_time"]),
}
# query products
products = self.api.search(**new_query)
# store individual query results in ProductItem
product_list = []
for prod in products:
prod_dict = prod.as_dict()
product_list.append(
ProductItem(
constellation="Unknown",
collection=prod_dict["properties"]["product_type"],
id=prod_dict["id"],
geometry=Polygon(prod_dict["geometry"]["coordinates"][0]),
start_time=prod_dict["properties"]["startTime"],
stop_time=prod_dict["properties"]["completionTime"],
properties=prod_dict,
)
)
#now return them as ProductItemSet
return ProductItemSet(product_list)