Esempio n. 1
0
    def create(client, topics, url, secret, project):
        """ Creates a Webhook.

        Args:
            client (Client): The Labelbox client used to connect
                to the server.
            topics (list of str): A list of topics this Webhook should
                get notifications for.
            url (str): The URL to which notifications should be sent
                by the Labelbox server.
            secret (str): A secret key used for signing notifications.
            project (Project or None): The project for which notifications
                should be sent. If None notifications are sent for all
                events in your organization.
        Returns:
            A newly created Webhook.
        """
        project_str = "" if project is None \
            else ("project:{id:\"%s\"}," % project.uid)

        query_str = """mutation CreateWebhookPyApi {
            createWebhook(data:{%s topics:{set:[%s]}, url:"%s", secret:"%s" }){%s}
        } """ % (project_str, " ".join(topics), url, secret,
                 query.results_query_part(Entity.Webhook))

        return Webhook(client, client.execute(query_str)["createWebhook"])
Esempio n. 2
0
    def create(client, topics, url, secret, project):
        """ Creates a Webhook.

        Args:
            client (Client): The Labelbox client used to connect
                to the server.
            topics (list of str): A list of topics this Webhook should
                get notifications for. Must be one of Webhook.Topic
            url (str): The URL to which notifications should be sent
                by the Labelbox server.
            secret (str): A secret key used for signing notifications.
            project (Project or None): The project for which notifications
                should be sent. If None notifications are sent for all
                events in your organization.
        Returns:
            A newly created Webhook.

        Raises:
            ValueError: If the topic is not one of Topic or status is not one of Status

        Information on configuring your server can be found here (this is where the url points to and the secret is set).
                        https://docs.labelbox.com/en/configure-editor/webhooks-setup#setup-steps

        """
        Webhook.validate_topics(topics)

        project_str = "" if project is None \
            else ("project:{id:\"%s\"}," % project.uid)

        query_str = """mutation CreateWebhookPyApi {
            createWebhook(data:{%s topics:{set:[%s]}, url:"%s", secret:"%s" }){%s}
        } """ % (project_str, " ".join(topics), url, secret,
                 query.results_query_part(Entity.Webhook))

        return Webhook(client, client.execute(query_str)["createWebhook"])
Esempio n. 3
0
    def create_metadata(self, meta_type, meta_value):
        """ Creates an asset metadata for this DataRow.

        Args:
            meta_type (str): Asset metadata type, must be one of:
                VIDEO, IMAGE, TEXT.
            meta_value (str): Asset metadata value.
        Returns:
            AssetMetadata DB object.
        """
        meta_type_param = "metaType"
        meta_value_param = "metaValue"
        data_row_id_param = "dataRowId"
        query_str = """mutation CreateAssetMetadataPyApi(
            $%s: MetadataType!, $%s: String!, $%s: ID!) {
            createAssetMetadata(data: {
                metaType: $%s metaValue: $%s dataRowId: $%s}) {%s}} """ % (
            meta_type_param, meta_value_param, data_row_id_param,
            meta_type_param, meta_value_param, data_row_id_param,
            query.results_query_part(Entity.AssetMetadata))

        res = self.client.execute(
            query_str, {
                meta_type_param: meta_type,
                meta_value_param: meta_value,
                data_row_id_param: self.uid
            })
        return Entity.AssetMetadata(self.client, res["createAssetMetadata"])
Esempio n. 4
0
    def labeler_performance(self):
        """ Returns the labeler performances for this Project.

        Returns:
            A PaginatedCollection of LabelerPerformance objects.
        """
        id_param = "projectId"
        query_str = """query LabelerPerformancePyApi($%s: ID!) {
            project(where: {id: $%s}) {
                labelerPerformance(skip: %%d first: %%d) {
                    count user {%s} secondsPerLabel totalTimeLabeling consensus
                    averageBenchmarkAgreement lastActivityTime}
            }}""" % (id_param, id_param, query.results_query_part(Entity.User))

        def create_labeler_performance(client, result):
            result["user"] = Entity.User(client, result["user"])
            # python isoformat doesn't accept Z as utc timezone
            result["lastActivityTime"] = datetime.fromisoformat(
                result["lastActivityTime"].replace('Z', '+00:00'))
            return LabelerPerformance(**{
                utils.snake_case(key): value
                for key, value in result.items()
            })

        return PaginatedCollection(self.client, query_str,
                                   {id_param: self.uid},
                                   ["project", "labelerPerformance"],
                                   create_labeler_performance)
Esempio n. 5
0
    def update(self, topics=None, url=None, status=None):
        """ Updates the Webhook.

        Args:
            topics (Optional[List[Topic]]): The new topics.
            url  Optional[str): The new URL value.
            status (Optional[Status]): The new status.
                If an argument is set to None then no updates will be made to that field.

        """

        # Webhook has a custom `update` function due to custom types
        # in `status` and `topics` fields.

        if topics is not None:
            self.validate_topics(topics)

        if status is not None:
            self.validate_value(status, self.Status)

        topics_str = "" if topics is None \
            else "topics: {set: [%s]}" % " ".join(topics)
        url_str = "" if url is None else "url: \"%s\"" % url
        status_str = "" if status is None else "status: %s" % status

        query_str = """mutation UpdateWebhookPyApi {
            updateWebhook(where: {id: "%s"} data:{%s}){%s}} """ % (
            self.uid, ", ".join(filter(None,
                                       (topics_str, url_str, status_str))),
            query.results_query_part(Entity.Webhook))

        self._set_field_values(self.client.execute(query_str)["updateWebhook"])
Esempio n. 6
0
def _make_request_data(project_id: str, name: str, content_length: int,
                       file_name: str) -> dict:
    query_str = """mutation createBulkImportRequestFromFilePyApi(
            $projectId: ID!, $name: String!, $file: Upload!, $contentLength: Int!) {
        createBulkImportRequest(data: {
            projectId: $projectId,
            name: $name,
            filePayload: {
                file: $file,
                contentLength: $contentLength
            }
        }) {
            %s
        }
    }
    """ % query.results_query_part(BulkImportRequest)
    variables = {
        "projectId": project_id,
        "name": name,
        "file": None,
        "contentLength": content_length
    }
    operations = json.dumps({"variables": variables, "query": query_str})

    return {
        "operations": operations,
        "map": (None, json.dumps({file_name: ["variables.file"]}))
    }
Esempio n. 7
0
    def labels(self, datasets=None, order_by=None):
        """ Custom relationship expansion method to support limited filtering.

        Args:
            datasets (iterable of Dataset): Optional collection of Datasets
                whose Labels are sought. If not provided, all Labels in
                this Project are returned.
            order_by (None or (Field, Field.Order)): Ordering clause.
        """
        Label = Entity.Label

        if datasets is not None:
            where = " where:{dataRow: {dataset: {id_in: [%s]}}}" % ", ".join(
                '"%s"' % dataset.uid for dataset in datasets)
        else:
            where = ""

        if order_by is not None:
            query.check_order_by_clause(Label, order_by)
            order_by_str = "orderBy: %s_%s" % (order_by[0].graphql_name,
                                               order_by[1].name.upper())
        else:
            order_by_str = ""

        id_param = "projectId"
        query_str = """query GetProjectLabelsPyApi($%s: ID!)
            {project (where: {id: $%s})
                {labels (skip: %%d first: %%d %s %s) {%s}}}""" % (
            id_param, id_param, where, order_by_str,
            query.results_query_part(Label))

        return PaginatedCollection(self.client, query_str,
                                   {id_param: self.uid}, ["project", "labels"],
                                   Label)
Esempio n. 8
0
    def create_from_url(cls, client, project_id: str, name: str,
                        url: str) -> 'BulkImportRequest':
        """
        Creates a BulkImportRequest from a publicly accessible URL
        to an ndjson file with predictions.

        Args:
            client (Client): a Labelbox client
            project_id (str): id of project for which predictions will be imported
            name (str): name of BulkImportRequest
            url (str): publicly accessible URL pointing to ndjson file containing predictions
        Returns:
            BulkImportRequest object
        """
        query_str = """mutation createBulkImportRequestPyApi(
                $projectId: ID!, $name: String!, $fileUrl: String!) {
            createBulkImportRequest(data: {
                projectId: $projectId,
                name: $name,
                fileUrl: $fileUrl
            }) {
                %s
            }
        }
        """ % query.results_query_part(cls)
        params = {"projectId": project_id, "name": name, "fileUrl": url}
        bulk_import_request_response = client.execute(query_str, params=params)
        return cls(client,
                   bulk_import_request_response["createBulkImportRequest"])
Esempio n. 9
0
    def from_name(cls, client, project_id: str,
                  name: str) -> 'BulkImportRequest':
        """ Fetches existing BulkImportRequest.

        Args:
            client (Client): a Labelbox client
            project_id (str): BulkImportRequest's project id
            name (str): name of BulkImportRequest
        Returns:
            BulkImportRequest object

        """
        query_str = """query getBulkImportRequestPyApi(
                $projectId: ID!, $name: String!) {
            bulkImportRequest(where: {
                projectId: $projectId,
                name: $name
            }) {
                %s
            }
        }
        """ % query.results_query_part(cls)
        params = {"projectId": project_id, "name": name}
        response = client.execute(query_str, params=params)
        return cls(client, response['bulkImportRequest'])
Esempio n. 10
0
 def create_benchmark(self):
     """ Creates a Benchmark for this Label.
     Return:
         The newly created Benchmark.
     """
     label_id_param = "labelId"
     query_str = """mutation CreateBenchmarkPyApi($%s: ID!) {
         createBenchmark(data: {labelId: $%s}) {%s}} """ % (
         label_id_param, label_id_param,
         query.results_query_part(Entity.Benchmark))
     res = self.client.execute(query_str, {label_id_param: self.uid})
     return Entity.Benchmark(self.client, res["createBenchmark"])
Esempio n. 11
0
    def create_prediction(self, label, data_row, prediction_model=None):
        """ Creates a Prediction within a Legacy Editor Project. Not supported
        in the new Editor.

        Args:
            label (str): The `label` field of the new Prediction.
            data_row (DataRow): The DataRow for which the Prediction is created.
            prediction_model (PredictionModel or None): The PredictionModel
                within which the new Prediction is created. If None then this
                Project's active_prediction_model is used.
        Return:
            A newly created Prediction.
        Raises:
            labelbox.excepions.InvalidQueryError: if given `prediction_model`
                is None and this Project's active_prediction_model is also
                None.
        """
        logger.warning(
            "`create_prediction` is deprecated and is not compatible with the new editor."
        )

        if prediction_model is None:
            prediction_model = self.active_prediction_model()
            if prediction_model is None:
                raise InvalidQueryError(
                    "Project '%s' has no active prediction model" % self.name)

        label_param = "label"
        model_param = "prediction_model_id"
        project_param = "project_id"
        data_row_param = "data_row_id"

        Prediction = Entity.Prediction
        query_str = """mutation CreatePredictionPyApi(
            $%s: String!, $%s: ID!, $%s: ID!, $%s: ID!) {createPrediction(
            data: {label: $%s, predictionModelId: $%s, projectId: $%s,
                   dataRowId: $%s})
            {%s}}""" % (label_param, model_param, project_param,
                        data_row_param, label_param, model_param,
                        project_param, data_row_param,
                        query.results_query_part(Prediction))
        params = {
            label_param: label,
            model_param: prediction_model.uid,
            data_row_param: data_row.uid,
            project_param: self.uid
        }
        res = self.client.execute(query_str, params)
        return Prediction(self.client, res["createPrediction"])
Esempio n. 12
0
    def members(self):
        """ Fetch all current members for this project

        Returns:
            A `PaginatedCollection of `ProjectMember`s

        """
        id_param = "projectId"
        query_str = """query ProjectMemberOverviewPyApi($%s: ID!) {
             project(where: {id : $%s}) { id members(skip: %%d first: %%d){ id user { %s } role { id name } }
           }
        }""" % (id_param, id_param, query.results_query_part(Entity.User))
        return PaginatedCollection(self.client, query_str,
                                   {id_param: str(self.uid)},
                                   ["project", "members"], ProjectMember)
Esempio n. 13
0
def get_project_invites(client, project_id):
    """
    Do not use. Only for testing.
    """
    id_param = "projectId"
    query_str = """query GetProjectInvitationsPyApi($from: ID, $first: PageSize, $%s: ID!) {
        project(where: {id: $%s}) {id
        invites(from: $from, first: $first) { nodes { %s
        projectInvites { projectId projectRoleName } } nextCursor}}}
    """ % (id_param, id_param, results_query_part(Invite))
    return PaginatedCollection(
        client,
        query_str, {id_param: project_id}, ['project', 'invites', 'nodes'],
        Invite,
        cursor_path=['project', 'invites', 'nextCursor'],
        experimental=True)
    def create_from_url(cls,
                        client,
                        project_id: str,
                        name: str,
                        url: str,
                        validate=True) -> 'BulkImportRequest':
        """
        Creates a BulkImportRequest from a publicly accessible URL
        to an ndjson file with predictions.

        Args:
            client (Client): a Labelbox client
            project_id (str): id of project for which predictions will be imported
            name (str): name of BulkImportRequest
            url (str): publicly accessible URL pointing to ndjson file containing predictions
            validate (bool): a flag indicating if there should be a validation
                if `url` is valid ndjson
        Returns:
            BulkImportRequest object
        """
        if validate:
            logger.warn(
                "Validation is turned on. The file will be downloaded locally and processed before uploading."
            )
            res = requests.get(url)
            data = ndjson.loads(res.text)
            _validate_ndjson(data, client.get_project(project_id))

        query_str = """mutation createBulkImportRequestPyApi(
                $projectId: ID!, $name: String!, $fileUrl: String!) {
            createBulkImportRequest(data: {
                projectId: $projectId,
                name: $name,
                fileUrl: $fileUrl
            }) {
                %s
            }
        }
        """ % query.results_query_part(cls)
        params = {"projectId": project_id, "name": name, "fileUrl": url}
        bulk_import_request_response = client.execute(query_str, params=params)
        return cls(client,
                   bulk_import_request_response["createBulkImportRequest"])
Esempio n. 15
0
    def update(self, topics=None, url=None, status=None):
        """ Updates this Webhook.
        Args:
            topics (list of str): The new topics value, optional.
            url (str): The new URL value, optional.
            status (str): The new status value, optional.
        """
        # Webhook has a custom `update` function due to custom types
        # in `status` and `topics` fields.
        topics_str = "" if topics is None \
            else "topics: {set: [%s]}" % " ".join(topics)
        url_str = "" if url is None else "url: \"%s\"" % url
        status_str = "" if status is None else "status: %s" % status

        query_str = """mutation UpdateWebhookPyApi {
            updateWebhook(where: {id: "%s"} data:{%s}){%s}} """ % (
            self.uid, ", ".join(filter(None,
                                       (topics_str, url_str, status_str))),
            query.results_query_part(Entity.Webhook))

        self._set_field_values(self.client.execute(query_str)["updateWebhook"])
Esempio n. 16
0
    def create_metadata(self, meta_type, meta_value):
        """ Attaches asset metadata to a DataRow.

            >>> datarow.create_metadata("TEXT", "This is a text message")

        Args:
            meta_type (str): Asset metadata type, must be one of:
                VIDEO, IMAGE, TEXT, IMAGE_OVERLAY (AssetMetadata.MetaType)
            meta_value (str): Asset metadata value.
        Returns:
            `AssetMetadata` DB object.
        Raises:
            ValueError: meta_type must be one of the supported types.
        """

        if meta_type not in self.supported_meta_types:
            raise ValueError(
                f"meta_type must be one of {self.supported_meta_types}. Found {meta_type}"
            )

        meta_type_param = "metaType"
        meta_value_param = "metaValue"
        data_row_id_param = "dataRowId"
        query_str = """mutation CreateAssetMetadataPyApi(
            $%s: AttachmentType!, $%s: String!, $%s: ID!) {
            createAssetMetadata(data: {
                metaType: $%s metaValue: $%s dataRowId: $%s}) {%s}} """ % (
            meta_type_param, meta_value_param, data_row_id_param,
            meta_type_param, meta_value_param, data_row_id_param,
            query.results_query_part(Entity.AssetMetadata))

        res = self.client.execute(
            query_str, {
                meta_type_param: meta_type,
                meta_value_param: meta_value,
                data_row_id_param: self.uid
            })
        return Entity.AssetMetadata(self.client, res["createAssetMetadata"])