def test_api_paging_extension(): item_collection = request(ITEM_COLLECTION) item_collection["stac_version"] = STAC_VERSION for feat in item_collection["features"]: feat["stac_version"] = STAC_VERSION item_collection["links"] += [ { "title": "next page", "rel": "next", "method": "GET", "href": "http://next" }, { "title": "previous page", "rel": "previous", "method": "POST", "href": "http://prev", "body": { "key": "value" }, }, ] model = ItemCollection(**item_collection) links = model.to_dict()["links"] # Make sure we can mix links and pagination links normal_link = Link(**links[0]) assert normal_link.rel == "self" next_link = PaginationLink(**links[1]) assert next_link.rel == "next" previous_link = PaginationLink(**links[2]) assert previous_link.rel == "previous" assert previous_link.body == {"key": "value"}
def test_item_collection(): test_item_coll = request(ITEM_COLLECTION) test_item_coll["stac_version"] = STAC_VERSION for feat in test_item_coll["features"]: feat["stac_version"] = STAC_VERSION valid_item_coll = ItemCollection(**test_item_coll).to_dict() for idx, feat in enumerate(test_item_coll["features"]): dict_match(feat, valid_item_coll["features"][idx])
def test_api_context_extension(): item_collection = request(ITEM_COLLECTION) item_collection.update( {"context": { "returned": 10, "limit": 10, "matched": 100 }}) ItemCollection(**item_collection)
def test_api_context_extension_invalid(): item_collection = request(ITEM_COLLECTION) item_collection.update( {"context": { "returned": 20, "limit": 10, "matched": 100 }}) with pytest.raises(ValidationError): ItemCollection(**item_collection)
def test_api_context_extension(): item_collection = request(ITEM_COLLECTION) item_collection["stac_version"] = STAC_VERSION for feat in item_collection["features"]: feat["stac_version"] = STAC_VERSION item_collection.update( {"context": { "returned": 10, "limit": 10, "matched": 100 }}) ItemCollection(**item_collection)
def test_api_context_extension_invalid(): item_collection = request(ITEM_COLLECTION) item_collection["stac_version"] = STAC_VERSION for feat in item_collection["features"]: feat["stac_version"] = STAC_VERSION item_collection.update( {"context": { "returned": 20, "limit": 10, "matched": 100 }}) with pytest.raises(ValidationError): ItemCollection(**item_collection)
def item_collection(self, id: str, limit: int = 10, token: str = None, **kwargs) -> ItemCollection: """Read an item collection from the database.""" with self.session.reader.context_session() as session: collection_children = (session.query(self.item_table).join( self.collection_table).filter( self.collection_table.id == id).order_by( self.item_table.datetime.desc(), self.item_table.id)) count = None if self.extension_is_enabled(ContextExtension): count_query = collection_children.statement.with_only_columns( [func.count()]).order_by(None) count = collection_children.session.execute( count_query).scalar() token = self.get_token(token) if token else token page = get_page(collection_children, per_page=limit, page=(token or False)) # Create dynamic attributes for each page page.next = (self.insert_token(keyset=page.paging.bookmark_next) if page.paging.has_next else None) page.previous = (self.insert_token( keyset=page.paging.bookmark_previous) if page.paging.has_previous else None) links = [] if page.next: links.append( PaginationLink( rel=Relations.next, type="application/geo+json", href= f"{kwargs['request'].base_url}collections/{id}/items?token={page.next}&limit={limit}", method="GET", )) if page.previous: links.append( PaginationLink( rel=Relations.previous, type="application/geo+json", href= f"{kwargs['request'].base_url}collections/{id}/items?token={page.previous}&limit={limit}", method="GET", )) response_features = [] for item in page: item.base_url = str(kwargs["request"].base_url) response_features.append(schemas.Item.from_orm(item)) context_obj = None if self.extension_is_enabled(ContextExtension): context_obj = { "returned": len(page), "limit": limit, "matched": count } return ItemCollection( type="FeatureCollection", context=context_obj, features=response_features, links=links, )
def item_collection( self, id: str, limit: int = 10, token: str = None, **kwargs ) -> ItemCollection: """Read an item collection from the database""" try: collection_children = ( self.reader_session.query(self.table) .join(self.collection_table) .filter(self.collection_table.id == id) .order_by(self.table.datetime.desc(), self.table.id) ) count = None if config.settings.api_extension_is_enabled(config.ApiExtensions.context): count_query = collection_children.statement.with_only_columns( [func.count()] ).order_by(None) count = collection_children.session.execute(count_query).scalar() token = self.pagination_client.get(token) if token else token page = get_page(collection_children, per_page=limit, page=(token or False)) # Create dynamic attributes for each page page.next = ( self.pagination_client.insert(keyset=page.paging.bookmark_next) if page.paging.has_next else None ) page.previous = ( self.pagination_client.insert(keyset=page.paging.bookmark_previous) if page.paging.has_previous else None ) except errors.NotFoundError: raise except Exception as e: logger.error(e, exc_info=True) raise errors.DatabaseError( "Unhandled database error when getting collection children" ) links = [] if page.next: links.append( PaginationLink( rel=Relations.next, type="application/geo+json", href=f"{kwargs['request'].base_url}collections/{id}/items?token={page.next}&limit={limit}", method="GET", ) ) if page.previous: links.append( PaginationLink( rel=Relations.previous, type="application/geo+json", href=f"{kwargs['request'].base_url}collections/{id}/items?token={page.previous}&limit={limit}", method="GET", ) ) response_features = [] for item in page: item.base_url = str(kwargs["request"].base_url) response_features.append(schemas.Item.from_orm(item)) context_obj = None if config.settings.api_extension_is_enabled(ApiExtensions.context): context_obj = {"returned": len(page), "limit": limit, "matched": count} return ItemCollection( type="FeatureCollection", context=context_obj, features=response_features, links=links, )
def test_item_collection(): test_item_coll = request(ITEM_COLLECTION) valid_item_coll = ItemCollection(**test_item_coll).to_dict() for idx, feat in enumerate(test_item_coll["features"]): dict_match(feat, valid_item_coll["features"][idx])