This is the official documentation of the forestadmin-agent-django and forestadmin-agent-flask Python agents.
Steps
Creating a custom data source will require you to work on the 3 following steps:
Declare the structure of the data
Declare the API capabilities
Code a translation layer
Minimal example
from typings import Optionalfrom forestadmin.agent_toolkit.utils.context import Userfrom forestadmin.datasource_toolkit.collections import Collectionfrom forestadmin.datasource_toolkit.datasources import Datasourcefrom forestadmin.datasource_toolkit.interfaces.query.aggregation import AggregateResult, Aggregationfrom forestadmin.datasource_toolkit.interfaces.query.filter.paginated import PaginatedFilterfrom forestadmin.datasource_toolkit.interfaces.query.filter.unpaginated import Filterfrom forestadmin.datasource_toolkit.interfaces.query.projections import Projectionfrom forestadmin.datasource_toolkit.interfaces.records import RecordsDataAliasimport requests # client for the target API# The real work is in writing this module# Expect a full featured query translation module to be over 1000 LOCsfrom.forest_query_translation import QueryGenerator# Minimal implementation of a readonly data sourceclassMyCollection(Collection):def__init__(self,datasource):# Set name of the collection once importedsuper().__init__("MyCollection", datasource)# structure self.add_field("id", {"type": "Column","column_type": "Number","is_primary_key": True,"is_read_only": True, # field is readonly# As we are using the query translation strategy => define capabilities"filter_operators": set(), # field is not filterable"is_sortable": False, # field is not sortable }) self.add_field("title", {"type": "Column","column_type": "String","is_read_only": True,"filter_operators": set(),"is_sortable": False, })asyncdeflist(self,caller: User,filter_: PaginatedFilter,projection: Projection ) -> List[RecordsDataAlias]: params = QueryGenerator.generate_list_query_string(filter_, projection) response = requests.get('https://my-api/my-collection', params)return response.json()["items"]asyncdefaggregate(self,caller: User,filter_: Filter,aggregation: Aggregation,limit: Optional[int] ) -> List[AggregateResult]: params = QueryGenerator.generate_aggregate_query_string( filter_, aggregation, limit ) response = requests.get('https://my-api/my-collection', params)return response.json()["items"]classMyDatasource(Datasource):def__init__(self):super().__init__() self.add_collection(MyCollection(self))
from custom_datasources.my_datasource import MyDatasourceagent.add_datasource(MyDatasource())
Read more
Implementing a data source using the "query translation" strategy is an advanced concept: you will need to have a deep understanding of Forest Admin internals.
This strategy is a good match when writing data sources for full-featured databases.
Before starting, it is highly advised to read and understand the following sections: