예제 #1
0
    def test_item_deserialization_end_date_before_start_date(self):
        today = datetime.utcnow()
        yesterday = today - timedelta(days=1)
        sample = self.data_factory.create_item_sample(
            collection=self.collection.model,
            sample='item-1',
            properties={
                'start_datetime': isoformat(utc_aware(today)),
                "end_datetime": isoformat(utc_aware(yesterday))
            })

        # translate to Python native:
        serializer = ItemSerializer(data=sample.get_json('deserialize'))
        with self.assertRaises(ValidationError):
            serializer.is_valid(raise_exception=True)
예제 #2
0
    def to_representation(self, instance):
        ret = super().to_representation(instance)

        start = instance.extent_start_datetime
        end = instance.extent_end_datetime

        if start is not None:
            start = isoformat(start)

        if end is not None:
            end = isoformat(end)

        ret["temporal_extent"] = {"interval": [[start, end]]}

        return ret["temporal_extent"]
예제 #3
0
    def test_item_deserialization_update_remove_title(self):
        original_sample = self.data_factory.create_item_sample(
            collection=self.collection.model,
            sample='item-1',
        )
        sample = self.data_factory.create_item_sample(
            collection=self.collection.model,
            sample='item-2',
            name=original_sample["name"],
            properties={"datetime": isoformat(utc_aware(datetime.utcnow()))})
        serializer = ItemSerializer(original_sample.model,
                                    data=sample.get_json('deserialize'))
        serializer.is_valid(raise_exception=True)
        item = serializer.save()

        # mock a request needed for the serialization of links
        context = {
            'request':
            api_request_mocker.get(
                f'{STAC_BASE_V}/collections/{self.collection["name"]}/items/{sample["name"]}'
            )
        }
        serializer = ItemSerializer(item, context=context)
        python_native = serializer.data
        self.check_stac_item(sample.json, python_native,
                             self.collection["name"])
        self.assertNotIn('title',
                         python_native['properties'].keys(),
                         msg="Title was not removed")
예제 #4
0
    def get_extent(self, obj):
        start = obj.extent_start_datetime
        end = obj.extent_end_datetime
        if start is not None:
            start = isoformat(start)
        if end is not None:
            end = isoformat(end)

        bbox = []
        if obj.extent_geometry is not None:
            bbox = list(GEOSGeometry(obj.extent_geometry).extent)

        return {
            "spatial": {
                "bbox": [bbox]
            },
            "temporal": {
                "interval": [[start, end]]
            },
        }
예제 #5
0
    def _get_properties(self):
        properties = {}
        for attribute in self.__dict__:
            if not attribute.startswith('attr_properties_'):
                continue
            key = attribute[16:]
            value = getattr(self, attribute)
            properties[key] = value
            if key.endswith('datetime') and isinstance(value, datetime):
                properties[key] = isoformat(value)

        return properties
예제 #6
0
    def create_presigned_url(self, key, asset, part, upload_id, part_md5):
        '''Create a presigned url for an upload part on the backend

        Args:
            key: string
                key on the S3 backend for which we want to create a presigned url upload part
            asset: Asset
                Asset metadata model associated with the S3 backend key
            part: int
                Part number for which to create a presigned url for upload part
            upload_id: string
                Upload ID for which to create a presigned url
            part_md5: string
                base64 MD5 digest of the part

        Returns: dict(string, int, datetime)
            Dict {'url': string, 'part': int, 'expires': datetime}
        '''
        expires = utc_aware(datetime.utcnow() + timedelta(
            seconds=settings.AWS_PRESIGNED_URL_EXPIRES))
        params = {
            'Bucket': settings.AWS_STORAGE_BUCKET_NAME,
            'Key': key,
            'UploadId': upload_id,
            'PartNumber': part,
            'ContentMD5': part_md5,
        }
        url = self.call_s3_api(self.s3.generate_presigned_url,
                               'upload_part',
                               Params=params,
                               ExpiresIn=settings.AWS_PRESIGNED_URL_EXPIRES,
                               HttpMethod='PUT',
                               log_extra={
                                   'collection': asset.item.collection.name,
                                   'item': asset.item.name,
                                   'asset': asset.name,
                                   'upload_id': upload_id
                               })

        logger.info('Presigned url %s for %s part %s with expires %s created',
                    url,
                    key,
                    part,
                    isoformat(expires),
                    extra={
                        'upload_id': upload_id,
                        'asset': asset.name
                    })
        return {'url': url, 'part': part, 'expires': expires}
예제 #7
0
 def get_aborted(self, obj):
     if obj.status == AssetUpload.Status.ABORTED:
         return isoformat(obj.ended)
     return None
예제 #8
0
 def get_completed(self, obj):
     if obj.status == AssetUpload.Status.COMPLETED:
         return isoformat(obj.ended)
     return None
예제 #9
0
    def test_collection_serialization(self):
        collection_name = self.collection.model.name
        # mock a request needed for the serialization of links
        context = {
            'request':
            api_request_mocker.get(
                f'{STAC_BASE_V}/collections/{collection_name}')
        }

        # transate to Python native:
        serializer = CollectionSerializer(self.collection.model,
                                          context=context)
        python_native = serializer.data
        logger.debug('python native:\n%s', pformat(python_native))

        # translate to JSON:
        content = JSONRenderer().render(python_native)
        logger.debug('json string: %s', content.decode("utf-8"))

        expected = self.collection.get_json('serialize')
        expected.update({
            'created':
            isoformat(self.collection_created),
            'crs': ['http://www.opengis.net/def/crs/OGC/1.3/CRS84'],
            'extent':
            OrderedDict([('spatial', {
                'bbox': [[5.644711, 46.775054, 7.602408, 49.014995]]
            }),
                         ('temporal', {
                             'interval':
                             [['2020-10-28T13:05:10Z', '2020-10-28T13:05:10Z']]
                         })]),
            'itemType':
            'Feature',
            'links': [
                OrderedDict([
                    ('rel', 'self'),
                    ('href',
                     f'http://testserver/api/stac/v0.9/collections/{collection_name}'
                     ),
                ]),
                OrderedDict([
                    ('rel', 'root'),
                    ('href', 'http://testserver/api/stac/v0.9/'),
                ]),
                OrderedDict([
                    ('rel', 'parent'),
                    ('href', 'http://testserver/api/stac/v0.9/collections'),
                ]),
                OrderedDict([
                    ('rel', 'items'),
                    ('href',
                     f'http://testserver/api/stac/v0.9/collections/{collection_name}/items'
                     ),
                ]),
                OrderedDict([
                    ('href', 'https://www.example.com/described-by'),
                    ('rel', 'describedBy'),
                    ('type', 'description'),
                    ('title', 'This is an extra link'),
                ])
            ],
            'providers': [
                {
                    'name': 'provider-1',
                    'roles': ['licensor', 'producer'],
                    'description':
                    'This is a full description of the provider',
                    'url': 'https://www.provider.com'
                },
                {
                    'name': 'provider-2',
                    'roles': ['licensor'],
                    'description':
                    'This is a full description of a second provider',
                    'url': 'https://www.provider.com/provider-2'
                },
                {
                    'name': 'provider-3',
                },
            ],
            'stac_extensions': [
                'eo', 'proj', 'view',
                'https://data.geo.admin.ch/stac/geoadmin-extension/1.0/schema.json'
            ],
            'stac_version':
            settings.STAC_VERSION,
            'summaries': {
                'eo:gsd': [3.4],
                'geoadmin:variant': ['kgrs'],
                'proj:epsg': [2056],
            },
            'updated':
            isoformat(self.collection_created)
        })
        self.check_stac_collection(expected, python_native)
예제 #10
0
    def test_empty_collection_serialization(self):
        collection_name = self.collection.model.name
        # mock a request needed for the serialization of links
        context = {
            'request':
            api_request_mocker.get(
                f'{STAC_BASE_V}/collections/{collection_name}')
        }

        # transate to Python native:
        serializer = CollectionSerializer(self.collection.model,
                                          context=context)
        python_native = serializer.data
        logger.debug('python native:\n%s', pformat(python_native))

        # translate to JSON:
        content = JSONRenderer().render(python_native)
        logger.debug('json string: %s', content.decode("utf-8"))

        expected = self.collection.get_json('serialize')
        expected.update({
            'created':
            isoformat(self.collection_created),
            'crs': ['http://www.opengis.net/def/crs/OGC/1.3/CRS84'],
            'extent': {
                'spatial': {
                    'bbox': [[]]
                },
                'temporal': {
                    'interval': [[None, None]]
                }
            },
            'itemType':
            'Feature',
            'links': [
                OrderedDict([
                    ('rel', 'self'),
                    ('href',
                     f'http://testserver/api/stac/v0.9/collections/{collection_name}'
                     ),
                ]),
                OrderedDict([
                    ('rel', 'root'),
                    ('href', 'http://testserver/api/stac/v0.9/'),
                ]),
                OrderedDict([
                    ('rel', 'parent'),
                    ('href', 'http://testserver/api/stac/v0.9/'),
                ]),
                OrderedDict([
                    ('rel', 'items'),
                    ('href',
                     f'http://testserver/api/stac/v0.9/collections/{collection_name}/items'
                     ),
                ]),
                OrderedDict([
                    ('href', 'https://www.example.com/described-by'),
                    ('rel', 'describedBy'),
                    ('type', 'description'),
                    ('title', 'This is an extra collection link'),
                ])
            ],
            'providers': [
                {
                    'name': 'provider-1',
                    'roles': ['licensor', 'producer'],
                    'description':
                    'This is a full description of the provider',
                    'url': 'https://www.provider.com'
                },
                {
                    'name': 'provider-2',
                    'roles': ['licensor'],
                    'description':
                    'This is a full description of a second provider',
                    'url': 'https://www.provider.com/provider-2'
                },
                {
                    'name': 'provider-3',
                },
            ],
            'stac_version':
            settings.STAC_VERSION,
            'summaries': {},
            'updated':
            isoformat(self.collection_created)
        })
        self.check_stac_collection(expected, python_native)