예제 #1
0
    def describe(self, carrier: SomeResourceIds, **kwargs) -> SomeResources:
        """Describe a carrier or a list of carriers.

        Args:
            carrier: Identifier of the carrier to describe, or list of
                such identifiers.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: The carrier description or a list of carriers descriptions.

        """
        data = kwargs
        if isinstance(carrier, list):
            results = []
            ids_chunks = get_chunks(carrier, self._provider.max_per_describe)
            for ids_chunk in ids_chunks:
                data['carriers'] = ids_chunk
                descs = self._provider.post('describe-carriers', data=data)
                results += [Resource(**desc) for desc in descs]
            return results
        else:
            data['carrier'] = carrier
            desc = self._provider.post('describe-carrier', data=data)
            return Resource(**desc)
예제 #2
0
    def describe(self, flight: SomeResourceIds, **kwargs) -> SomeResources:
        """Describe a flight or a list of flights.

        Args:
            flight: Identifier of the flight to describe, or list of
                such identifiers.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            The flight description or a list of flight descriptions.

        """
        data = kwargs
        if isinstance(flight, list):
            results = []
            ids_chunks = get_chunks(flight, self._provider.max_per_describe)
            for ids_chunk in ids_chunks:
                data['flights'] = ids_chunk
                descs = self._provider.post('describe-flights', data=data)
                results += [Resource(**desc) for desc in descs]
            return results
        else:
            data['flight'] = flight
            desc = self._provider.post('describe-flight', data=data)
            return Resource(**desc)
예제 #3
0
    def describe(self, company: SomeResourceIds,
                 **kwargs) -> SomeResources:
        """Describe a company or multiple companies.

        Args:
            company: Identifier of the company to describe, or list of
            such identifiers.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            The company description or a list of company description.

        """
        data = kwargs
        if isinstance(company, list):
            results = []
            ids_chunks = get_chunks(company, self._provider.max_per_describe)
            for ids_chunk in ids_chunks:
                data['companies'] = ids_chunk
                descs = self._provider.post('describe-companies', data=data)
                results += [Resource(**desc) for desc in descs]
            return results
        else:
            data['company'] = company
            desc = self._provider.post('describe-company', data=data)
            return Resource(**desc)
    def describe(self, annotation: SomeResourceIds, **kwargs) -> SomeResources:
        """Describe a dataset or a list of datasets.

        Args:
            annotation: Identifier of the annotation to describe, or list of
                such identifiers.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            The annotation description or a list of annotation description.

        """
        data = kwargs
        if isinstance(annotation, list):
            results = []
            ids_chunks = get_chunks(annotation,
                                    self._provider.max_per_describe)
            for ids_chunk in ids_chunks:
                data['annotations'] = ids_chunk
                descs = self._provider.post('describe-annotations', data=data)
                results += [Resource(**desc) for desc in descs]
            return results
        else:
            data['annotation'] = annotation
            desc = self._provider.post('describe-annotation', data=data)
            return Resource(**desc)
    def describe(self, task: SomeResourceIds, **kwargs) -> SomeResources:
        """Describe a collection task.

        Args:
            task: Identifier of the collection task to describe, or list of
                such identifiers.

        Returns:
            Resource: The collection task description
                or a list of collection task descriptions.

        """
        data = kwargs
        if isinstance(task, list):
            results = []
            ids_chunks = get_chunks(task, self._provider.max_per_describe)
            for ids_chunk in ids_chunks:
                data['tasks'] = ids_chunk
                descs = self._provider.post('describe-tasks', data=data)
                results += [Resource(**desc) for desc in descs]
            return results
        else:
            data['task'] = task
            desc = self._provider.post('describe-task', data=data)
            return Resource(**desc)
예제 #6
0
    def describe(self, team: SomeResourceIds, **kwargs) -> SomeResources:
        """Describe a team or list of teams.

        Args:
            team: Identifier of the team to describe, or list of
                such identifiers.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: A team resource or a list of team resources.

        """
        data = kwargs
        if isinstance(team, list):
            results = []
            ids_chunks = get_chunks(team, self._provider.max_per_describe)
            for ids_chunk in ids_chunks:
                data['teams'] = ids_chunk
                descs = self._provider.post('describe-teams', data=data)
                results += [Resource(**desc) for desc in descs]
            return results
        else:
            data['team'] = team
            desc = self._provider.post('describe-team', data=data)
            return Resource(**desc)
예제 #7
0
    def create_datasets(self, datasets: List[dict]) -> Union[List[Resource]]:
        """Create several datasets *(bulk dataset creation)*.

        Args:
            datasets: List of dataset dictionnaries
                (refer to ``/create-datasets``
                definition in the Data Manager API for a detailed description
                of ``datasets``)

        Returns:
            A list of the created dataset descriptions.

        Example:
            >>> sdk.datasets.create_datasets(
            ... datasets=[{'name': 'My file dataset',
            ...            'project': '4037636c9a406900074dc253',
            ...            'type': 'file',
            ...            'components': [{'name': 'kind_of_file'}]},
            ...           {'name': 'My image',
            ...            'type': 'image',
            ...            'project': '4037636c9a406900074dc253',
            ...            'components': [{'name': 'image'}]}])
            [Resource(_id='406ee155647ec6006df3aa21'), ...]

        """
        for desc in datasets:
            if 'vertical_srs_wkt' in desc:
                desc['vertical_srs_wkt'] = \
                    expand_vertcrs_to_wkt(desc['vertical_srs_wkt'])

        data = {'datasets': datasets}
        created_datasets = self._provider.post('create-datasets', data=data)

        return [Resource(**dataset) for dataset in created_datasets]
예제 #8
0
    def create(self, *, geometry: dict = None, properties: dict = None,
               collection: ResourceId = None, **kwargs) -> Resource:
        """Create a feature.

        Args:
            geometry: A dictionary following GeoJSON specification.

            properties: Dictionary of properties.

            collection: Identifier of a collection to add the created
                feature to.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource for the created feature.

        """
        data = kwargs

        if geometry is not None:
            data['geometry'] = geometry

        if collection is not None:
            data['collection'] = collection

        if properties is not None:
            data['properties'] = properties

        desc = self._provider.post('create-feature', data=data)
        return Resource(**desc)
    def create(self,
               *,
               name: str,
               maker: str,
               type: str,
               company: ResourceId = None,
               unloaded_weight: dict = None,
               flight_time: dict = None,
               speed: dict = None,
               altitude: dict = None,
               compatible_sensor_models: List[ResourceId] = None,
               **kwargs) -> Resource:
        """Create a carrier model.

        Args:
            name: Carrier model name.

            maker: Maker name.

            type: Model type, among``fixed-wind``, ``multirotor``, ``ground-robot``,
            ``helicopter``, ``pedestrian``.

            company: Optional identifier of the company.

            unloaded_weight: Optional unloaded weight
                ``{ value: weight without sensor, unit: unit (g, kg) }``.

            flight_time : Optional flight time
                ``{ value: maximum flight time, unit: unit (min) }``.

            speed : Optional speed
                ``{ min: {value, unit}, max: {value, unit(m/s, mph ,ft/s, km/h, knot)} }``.

            altitude : Optional altitude ``{ min: {value, unit}, max: {value, unit(m, ft)} }``.

            compatible_sensor_models: Optional list of compatible sensors identifiers.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: A carrier model resource.
        """
        data = kwargs
        data.update({'name': name, 'maker': maker, 'type': type})

        for param_name, param_value in (('company', company),
                                        ('unloaded_weight', unloaded_weight),
                                        ('flight_time', flight_time),
                                        ('speed', speed), ('altitude',
                                                           altitude),
                                        ('unloaded_weight', unloaded_weight),
                                        ('compatible_sensor_models',
                                         compatible_sensor_models)):
            if param_value is not None:
                data[param_name] = param_value

        content = self._provider.post(path='create-carrier-model', data=data)

        return Resource(**content)
예제 #10
0
    def create(self, *, company: ResourceId, name: str, leader: ResourceId = None,
               **kwargs) -> Resource:
        """Create a team.

        Args:
            company: Identifier of the company.

            name: Team name.

            leader: Optional team leader (pilot id).

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: A team resource.
        """
        data = kwargs
        data.update({
            'name': name,
            'company': company,
        })

        if leader is not None:
            data['leader'] = leader

        content = self._provider.post(path='create-team', data=data)

        return Resource(**content)
예제 #11
0
    def search(self,
               *,
               project: ResourceId = None,
               filter: dict = None,
               limit: int = None,
               page: int = None,
               sort: dict = None,
               return_total: bool = False,
               **kwargs) -> Union[ResourcesWithTotal, List[Resource]]:
        """Search annotations.

        Args:
            project: Optional identifier of a project to search
                annotations for.

            filter: Search filter dictionary (refer to ``/search-annotations``
                in the Annotation API specification for a detailed
                description).

            limit: Optional Maximum number of results.

            page: Optional Page number (starting at page 1).

            sort: Optional. Sort the results on the specified attributes
                (``1`` is sorting in ascending order,
                ``-1`` is sorting in descending order).

            return_total: Optional. Change the type of return:
                If ``False`` (default), the method will return a
                limited list of resources (limited by ``limit`` value).
                If ``True``, the method will return a namedtuple with the
                total number of all results, and the limited list of resources.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            A list of annotation descriptions or a namedtuple
            with total number of results and list of annotation descriptions.

        """
        data = kwargs
        for name, value in [('filter', filter or {}), ('limit', limit),
                            ('page', page), ('sort', sort)]:
            if value is not None:
                data.update({name: value})

        if project is not None:
            data['filter'].update({'project': {'$eq': project}})

        r = self._provider.post('search-annotations', data=data)

        annotations = r.get('results')
        results = [Resource(**a) for a in annotations]

        if return_total is True:
            total = r.get('total')
            return ResourcesWithTotal(total=total, results=results)
        else:
            return results
    def create(self, name: str, *, client_type='sdk',
               expiration_date: datetime = None, **kwargs) -> Resource:
        """Create an OAuth client.

        This client will be used to generate a temporary connection
        token.

        Args:
            name: OAuth client name.

            client_type: Client type (only `sdk` is supported).

            expiration_date: Optional expiration date.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource for the client created.

        """
        data = kwargs
        data.update({
            'name': name,
            'client_type': client_type,
        })

        if expiration_date is not None:
            data['expiration_date'] = expiration_date

        desc = self._provider.post(path='create-client', data=data)
        return Resource(**desc)
예제 #13
0
    def search(self, *, name: str = None, filter: Dict = None,
               limit: int = None, page: int = None, sort: dict = None,
               return_total: bool = False,
               **kwargs) -> Union[ResourcesWithTotal, List[Resource]]:
        """Search for a list of analytics.

        Args:
            name: Optional Analytic name.

            filter: Search filter dictionary (refer to ``/search-analytics``
                definition in the Analytics-service API for a detailed description
                of ``filter``).

            limit: Optional Maximum number of results to extract.

            page: Optional Page number (starting at page 0).

            sort: Optional. Sort the results on the specified attributes
                (``1`` is sorting in ascending order,
                ``-1`` is sorting in descending order).

            return_total: Optional. Change the type of return:
                If ``False`` (default), the method will return a
                limited list of resources (limited by ``limit`` value).
                If ``True``, the method will return a namedtuple with the
                total number of all results, and the limited list of resources.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Analytics: A list of analytics resources OR a namedtuple
                with total number of results and list of analytics resources.

        """
        data = kwargs

        for prop_name, value in [('filter', filter or {}),
                                 ('limit', limit),
                                 ('page', page),
                                 ('sort', sort)]:
            if value is not None:
                data.update({prop_name: value})

        if name is not None:
            data['filter']['name'] = {'$eq': name}

        search_desc = self._provider.post(
            path='search-analytics', data=data, as_json=True)

        analytics = search_desc.get('results')

        results = [Resource(**analytic) for analytic in analytics]

        if return_total is True:
            total = search_desc.get('total')
            return ResourcesWithTotal(total=total, results=results)
        else:
            return results
예제 #14
0
    def test_initialization(self):
        """Test resource initialization."""
        r = Resource(**self.user_desc)
        self.assertEqual(r.id, '5aa7f7fd8e329e5d1858ee7e')

        with self.assertRaises(AttributeError):
            _ = r.fake_attribute

        del r.id  # For comparison
        assert self.user_desc == r.__dict__
예제 #15
0
    def create(self,
               dataset: Union[ResourceId, List[ResourceId]],
               *,
               duration: int = None,
               **kwargs) -> Resource:
        """Create a share token for a given dataset.

        Share token creation is restricted to users with admin profile
        or a manager role on their company.

        When sharing multiple datasets, all datasets are expected to
        belong to a single company.

        Args:
            dataset: Dataset identifier or list of dataset identifiers
                to create a share token for.

            duration: Optional duration in seconds of the created
                token. When equal to ``None`` (the default) the
                created token won't expire.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Dictionary with ``token``, ``expiration_date`` and
            ``scope`` keys.

        Example:
            >>> desc = sdk.share_tokens.create('5d08ebe86a17271b23bc0fcd')
            >>> desc.token[:16]
            'YfkX6oB5JB02L9x5'

        """
        data = kwargs
        if isinstance(dataset, list):
            dataset_ids = dataset
        else:
            dataset_ids = [dataset]

        data.update({'scope': {'datasets': dataset_ids}})

        datasets = self._sdk.datasets.describe(dataset_ids,
                                               fields={'include': ['company']})
        company_ids = set([d.company for d in datasets])
        if len(company_ids) != 1:
            raise RuntimeError('Expecting datasets in a single company')

        data['company'] = list(company_ids)[0]

        if duration is not None:
            data['duration'] = duration

        desc = self._provider.post(path='/create-share-token', data=data)
        return Resource(**desc)
예제 #16
0
    def describe_uploads_status(self, *,
                                flights: SomeResourceIds = None,
                                missions: SomeResourceIds = None,
                                projects: SomeResourceIds = None,
                                limit: int = None, page: int = None,
                                return_total: bool = False,
                                **kwargs) -> Union[ResourcesWithTotal, List[Resource]]:
        """Describe uncompleted flights status, descending sort by flight creation date.

        Args:
            flights: Optional Identifier of a flight or list of such identifiers.

            missions: Optional Identifier of a mission or list of such identifiers.

            projects: Optional Identifier of a project or list of such identifiers.

            limit: Optional Maximum number of results to extract.

            page: Optional Page number (starting at page 1).

            return_total: Optional Return the number of results found, default ``False``.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            A list of flights OR a namedtuple with total number of results and list of flights.
        """
        if flights is not None and not isinstance(flights, list):
            flights = [flights]
        if missions is not None and not isinstance(missions, list):
            missions = [missions]
        if projects is not None and not isinstance(projects, list):
            projects = [projects]
        data = kwargs
        for name, value in [('flights', flights),
                            ('missions', missions),
                            ('projects', projects),
                            ('page', page),
                            ('limit', limit)]:
            if value is not None:
                data.update({name: value})

        r = self._provider.post('describe-flight-uploads-status', data=data)
        descriptions = r.get('results')
        results = [Resource(id=desc.get('flight'), **desc) for desc in descriptions]

        if return_total is True:
            total = r.get('total')
            return ResourcesWithTotal(total=total, results=results)
        return results
예제 #17
0
    def create(self,
               *,
               carrier_model: str,
               team: ResourceId,
               serial_number: str,
               firmware: str = None,
               status: str = None,
               comment: str = None,
               **kwargs) -> Resource:
        """Create a carrier.

        Args:
            carrier_model: Identifier of the carrier model.

            team: Identifier of the team.

            serial_number: Serial number of the carrier.

            firmware : Optional firmware.

            status: Optional status,
                among ``ready``, ``in-maintenance``, ``out-of-service``.

            comment: Optional comment.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: A carrier resource.
        """
        data = kwargs
        data.update({
            'carrier_model': carrier_model,
            'team': team,
            'serial_number': serial_number
        })

        for param_name, param_value in (('status', status),
                                        ('comment', comment), ('firmware',
                                                               firmware)):
            if param_value is not None:
                data[param_name] = param_value

        content = self._provider.post(path='create-carrier', data=data)

        return Resource(**content)
    def delete(self, client: ResourceId, **kwargs) -> Resource:
        """Delete an OAuth client.

        Args:
            client: Identifier of OAuth client to delete.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Deleted resource.

        """
        data = kwargs
        data['client'] = client
        desc = self._provider.post(path='delete-client', data=data)
        return Resource(**desc)
예제 #19
0
    def cancel(self, product: ResourceId) -> Resource:
        """Cancel a running Analytics product.

        Args:
            product: Identifier of the product to cancel.

        Returns:
            The product description.

        Raises:
            ResponseError: When the ``product`` identifier is incorrect or has
                not been found.

        """
        data = {'product': product}
        desc = self._provider.post('cancel-product', data=data)
        return Resource(**desc)
예제 #20
0
    def describe(self, analytic: ResourceId, **kwargs) -> Resource:
        """Describe an analytic.

        Args:
            analytic: Identifier of the analytic to describe.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            The analytic description.

        """
        data = kwargs

        data['analytic'] = analytic
        desc = self._provider.post('describe-analytic', data=data)
        return Resource(**desc)
예제 #21
0
    def _create(self, dataset_type: str,
                component_names: Union[List[str], List[Dict[str, Any]]],
                **kwargs) -> Resource:
        components = _build_component_dict_list_from_names(component_names)

        if dataset_type not in ('file', 'mesh', 'image', 'raster',
                                'pcl', 'vector', 'file'):
            raise ValueError(f'Unsupported type "{dataset_type}"')

        adapted_params = _adapt_params(kwargs)
        if 'vertical_srs_wkt' in adapted_params:
            adapted_params['vertical_srs_wkt'] = \
                expand_vertcrs_to_wkt(kwargs['vertical_srs_wkt'])

        params = {'type': dataset_type, 'components': components}
        params.update(adapted_params)

        desc = self._provider.post('create-dataset', data=params)
        return Resource(**desc)
예제 #22
0
    def create_annotations(self, annotations: List[dict],
                           **kwargs) -> List[Resource]:
        """Create several annotations.

        Args:
            annotations: List of annotation descriptions, each
                description is a dictionary with keys among arguments of
                ``create()``.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Descriptions of the created annotations.

        """
        data = {'annotations': annotations}
        resp = self._provider.post('create-annotations', data=data)

        return [Resource(**desc) for desc in resp]
    def rename(self, task: ResourceId, *, name: str, **kwargs):
        """Rename a collection task.

        Args:
            task: Collection task to rename.

            name: New task name.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: The renamed collection task.

        """

        data = kwargs
        data.update({'task': task, 'name': name})

        content = self._provider.post('set-task-name', data=data)
        return Resource(**content)
예제 #24
0
    def describe(self, user: ResourceId = None, **kwargs) -> Resource:
        """Describe a user.

        Args:
            user: User identifier to describe.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            User : User resource.

        """
        data = kwargs

        if user:
            data['user'] = user

        content = self._provider.post(path='describe-user', data=data)

        return Resource(**content)
예제 #25
0
    def create_features(self, descriptions: Iterable[dict],
                        **kwargs) -> List[Resource]:
        """Create features.

        Args:
            descriptions: List of features descriptions, each
                description is a dictionary with keys among arguments
                of ``create()``.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            List of resource for the created features.

        """
        data = kwargs
        data['features'] = descriptions
        descs = self._provider.post('create-features', data=data)
        return [Resource(**desc)
                for desc in descs]
예제 #26
0
    def test_setattr(self):
        """Test setting resource attribute."""
        r = Resource(**self.user_desc)
        self.assertEqual(r.lastName, 'Eiffel')

        r.lastName = 'Courbet'
        self.assertEqual(r.lastName, 'Courbet')

        r.lastName = 'Choquet'
        self.assertEqual(r.lastName, 'Choquet')

        r.email = '*****@*****.**'
        self.assertEqual(r.lastName, 'Choquet')

        r.fake_attribute = 'value'
        self.assertEqual(r.fake_attribute, 'value')
예제 #27
0
    def set_leader(self, team: ResourceId, *, leader: ResourceId, **kwargs) -> Resource:
        """Set the team leader.

        Args:
            team: Identifier of the team.

            leader: Identifier of the pilot to promote to leader.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: The updated team resource.

        """

        data = kwargs
        data['team'] = team
        data['leader'] = leader

        desc = self._provider.post('set-team-leader', data=data)
        return Resource(**desc)
예제 #28
0
    def rename(self, team: ResourceId, name: str, **kwargs) -> Resource:
        """Rename a team.

        Args:
            team: Identifier of the team.

            name: New name.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resource: The updated team resource.

        """

        data = kwargs
        data['team'] = team
        data['name'] = name

        desc = self._provider.post('set-team-name', data=data)
        return Resource(**desc)
예제 #29
0
    def search(self,
               *,
               filter: dict = None,
               limit: int = None,
               page: int = None,
               sort: dict = None,
               **kwargs) -> List[Resource]:
        """Search carriers.

        Args:
            filter: Search filter dictionary.

            limit: Maximum number of results to extract.

            page: Page number (starting at page 0).

            sort: Sort the results on the specified attributes
                (``1`` is sorting in ascending order,
                ``-1`` is sorting in descending order).

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            Resources: A list of carrier resources.

        """

        data = kwargs

        for name, value in [('filter', filter or {}), ('limit', limit),
                            ('page', page), ('sort', sort)]:
            if value is not None:
                data.update({name: value})

        r = self._provider.post('search-carriers', data=data)
        results = r.get('results')

        return [Resource(**m) for m in results]
예제 #30
0
    def describe(self, product: ResourceId, **kwargs) -> Resource:
        """Describe an Analytics product.

        Args:
            product: Identifier of the product to describe.

            **kwargs: Optional keyword arguments. Those arguments are
                passed as is to the API provider.

        Returns:
            The product description.

        Raises:
            ResponseError: When the ``product`` identifier is incorrect or has
                not been found.

        """
        data = kwargs

        data['product'] = product
        desc = self._provider.post('describe-product', data=data)
        return Resource(**desc)