Project module
Methods attached to the Kili client, to run actions on projects.
Source code in kili/presentation/client/project.py
class ProjectClientMethods(BaseClientMethods):
"""Methods attached to the Kili client, to run actions on projects."""
@typechecked
# pylint: disable=too-many-arguments
def create_project(
self,
title: str,
description: str = "",
input_type: Optional[InputType] = None,
json_interface: Optional[Dict] = None,
project_id: Optional[ProjectId] = None,
project_type: Optional[ProjectType] = None,
tags: Optional[ListOrTuple[str]] = None,
compliance_tags: Optional[ListOrTuple[ComplianceTag]] = None,
) -> Dict[Literal["id"], str]:
# pylint: disable=line-too-long
"""Create a project.
Args:
input_type: Currently, one of `IMAGE`, `PDF`, `TEXT` or `VIDEO`.
json_interface: The json parameters of the project, see Edit your interface.
title: Title of the project.
description: Description of the project.
project_id: Identifier of the project to copy.
project_type: Currently, one of:
- `IMAGE_CLASSIFICATION_MULTI`
- `IMAGE_CLASSIFICATION_SINGLE`
- `IMAGE_OBJECT_DETECTION_POLYGON`
- `IMAGE_OBJECT_DETECTION_RECTANGLE`
- `IMAGE_OBJECT_DETECTION_SEMANTIC`
- `IMAGE_POSE_ESTIMATION`
- `OCR`
- `PDF_CLASSIFICATION_MULTI`
- `PDF_CLASSIFICATION_SINGLE`
- `PDF_NAMED_ENTITY_RECOGNITION`
- `PDF_OBJECT_DETECTION_RECTANGLE`
- `SPEECH_TO_TEXT`
- `TEXT_CLASSIFICATION_MULTI`
- `TEXT_CLASSIFICATION_SINGLE`
- `TEXT_NER`
- `TEXT_TRANSCRIPTION`
- `TIME_SERIES`
- `VIDEO_CLASSIFICATION_SINGLE`
- `VIDEO_FRAME_CLASSIFICATION`
- `VIDEO_FRAME_OBJECT_TRACKING`
tags: Tags to add to the project. The tags must already exist in the organization.
compliance_tags: Compliance tags of the project.
Compliance tags are used to categorize projects based on the sensitivity of
the data being handled and the legal constraints associated with it.
Possible values are: `PHI` and `PII`.
Returns:
A dict with the id of the created project.
Examples:
>>> kili.create_project(input_type='IMAGE', json_interface=json_interface, title='Example')
!!! example "Recipe"
For more detailed examples on how to create projects,
see [the recipe](https://docs.kili-technology.com/recipes/creating-a-project).
"""
project_id = ProjectUseCases(self.kili_api_gateway).create_project(
input_type=input_type,
json_interface=json_interface,
title=title,
description=description,
project_id=project_id,
project_type=project_type,
compliance_tags=compliance_tags,
)
if tags is not None:
tag_use_cases = TagUseCases(self.kili_api_gateway)
tag_ids = tag_use_cases.get_tag_ids_from_labels(labels=tags)
tag_use_cases.tag_project(
project_id=project_id, tag_ids=cast(ListOrTuple[TagId], tag_ids), disable_tqdm=True
)
return {"id": project_id}
@overload
# pylint: disable=too-many-arguments
def projects(
self,
project_id: Optional[str] = None,
search_query: Optional[str] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
updated_at_gte: Optional[str] = None,
updated_at_lte: Optional[str] = None,
archived: Optional[bool] = None,
starred: Optional[bool] = None,
tags_in: Optional[ListOrTuple[str]] = None,
organization_id: Optional[str] = None,
fields: ListOrTuple[str] = (
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
),
first: Optional[int] = None,
skip: int = 0,
disable_tqdm: Optional[bool] = None,
*,
as_generator: Literal[True],
) -> Generator[Dict, None, None]:
...
@overload
# pylint: disable=too-many-arguments
def projects(
self,
project_id: Optional[str] = None,
search_query: Optional[str] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
updated_at_gte: Optional[str] = None,
updated_at_lte: Optional[str] = None,
archived: Optional[bool] = None,
starred: Optional[bool] = None,
tags_in: Optional[ListOrTuple[str]] = None,
organization_id: Optional[str] = None,
fields: ListOrTuple[str] = (
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
),
first: Optional[int] = None,
skip: int = 0,
disable_tqdm: Optional[bool] = None,
*,
as_generator: Literal[False] = False,
) -> List[Dict]:
...
@typechecked
# pylint: disable=too-many-arguments,too-many-locals
def projects(
self,
project_id: Optional[str] = None,
search_query: Optional[str] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
updated_at_gte: Optional[str] = None,
updated_at_lte: Optional[str] = None,
archived: Optional[bool] = None,
starred: Optional[bool] = None,
tags_in: Optional[ListOrTuple[str]] = None,
organization_id: Optional[str] = None,
fields: ListOrTuple[str] = (
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
),
first: Optional[int] = None,
skip: int = 0,
disable_tqdm: Optional[bool] = None,
*,
as_generator: bool = False,
) -> Iterable[Dict]:
# pylint: disable=line-too-long
"""Get a generator or a list of projects that match a set of criteria.
Args:
project_id: Select a specific project through its project_id.
search_query: Returned projects with a title or a description matching this [PostgreSQL ILIKE](https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE) pattern.
should_relaunch_kpi_computation: Deprecated, do not use.
updated_at_gte: Returned projects should have a label whose update date is greater or equal
to this date.
updated_at_lte: Returned projects should have a label whose update date is lower or equal to this date.
archived: If `True`, only archived projects are returned, if `False`, only active projects are returned.
`None` disables this filter.
starred: If `True`, only starred projects are returned, if `False`, only unstarred projects are returned.
`None` disables this filter.
tags_in: Returned projects should have at least one of these tags.
organization_id: Returned projects should belong to this organization.
fields: All the fields to request among the possible fields for the projects.
See [the documentation](https://docs.kili-technology.com/reference/graphql-api#project) for all possible fields.
first: Maximum number of projects to return.
skip: Number of projects to skip (they are ordered by their creation).
disable_tqdm: If `True`, the progress bar will be disabled.
as_generator: If `True`, a generator on the projects is returned.
!!! info "Dates format"
Date strings should have format: "YYYY-MM-DD"
Returns:
A list of projects or a generator of projects if `as_generator` is `True`.
Examples:
>>> # List all my projects
>>> kili.projects()
"""
tag_ids = (
TagUseCases(self.kili_api_gateway).get_tag_ids_from_labels(tags_in) if tags_in else None
)
disable_tqdm = disable_tqdm_if_as_generator(as_generator, disable_tqdm)
projects_gen = ProjectUseCases(self.kili_api_gateway).list_projects(
ProjectFilters(
id=ProjectId(project_id) if project_id else None,
archived=archived,
search_query=search_query,
should_relaunch_kpi_computation=should_relaunch_kpi_computation,
starred=starred,
updated_at_gte=updated_at_gte,
updated_at_lte=updated_at_lte,
created_at_gte=None,
created_at_lte=None,
organization_id=organization_id,
tag_ids=tag_ids,
),
fields,
options=QueryOptions(disable_tqdm=disable_tqdm, first=first, skip=skip),
)
if as_generator:
return projects_gen
return list(projects_gen)
@typechecked
# pylint: disable=too-many-arguments,too-many-locals
def update_properties_in_project(
self,
project_id: str,
can_navigate_between_assets: Optional[bool] = None,
can_skip_asset: Optional[bool] = None,
compliance_tags: Optional[ListOrTuple[ComplianceTag]] = None,
consensus_mark: Optional[float] = None,
consensus_tot_coverage: Optional[int] = None,
description: Optional[str] = None,
honeypot_mark: Optional[float] = None,
instructions: Optional[str] = None,
input_type: Optional[InputType] = None,
json_interface: Optional[dict] = None,
min_consensus_size: Optional[int] = None,
number_of_assets: Optional[int] = None,
number_of_skipped_assets: Optional[int] = None,
number_of_remaining_assets: Optional[int] = None,
number_of_reviewed_assets: Optional[int] = None,
review_coverage: Optional[int] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
title: Optional[str] = None,
use_honeypot: Optional[bool] = None,
metadata_types: Optional[dict] = None,
) -> Dict[str, Any]:
"""Update properties of a project.
Args:
project_id: Identifier of the project.
can_navigate_between_assets:
Activate / Deactivate the use of next and previous buttons in labeling interface.
can_skip_asset: Activate / Deactivate the use of skip button in labeling interface.
compliance_tags: Compliance tags of the project.
Compliance tags are used to categorize projects based on the sensitivity of
the data being handled and the legal constraints associated with it.
Possible values are: `PHI` and `PII`.
consensus_mark: Should be between 0 and 1.
consensus_tot_coverage: Should be between 0 and 100.
It is the percentage of the dataset that will be annotated several times.
description: Description of the project.
honeypot_mark: Should be between 0 and 1
instructions: Instructions of the project.
input_type: Currently, one of `IMAGE`, `PDF`, `TEXT` or `VIDEO`.
json_interface: The json parameters of the project, see Edit your interface.
min_consensus_size: Should be between 1 and 10
Number of people that will annotate the same asset, for consensus computation.
number_of_assets: Defaults to 0
number_of_skipped_assets: Defaults to 0
number_of_remaining_assets: Defaults to 0
number_of_reviewed_assets: Defaults to 0
review_coverage: Allow to set the percentage of assets
that will be queued in the review interface.
Should be between 0 and 100
should_relaunch_kpi_computation: Technical field, added to indicate changes
in honeypot or consensus settings
title: Title of the project
use_honeypot: Activate / Deactivate the use of honeypot in the project
metadata_types: Types of the project metadata.
Should be a `dict` of metadata fields name as keys and metadata types as values.
Currently, possible types are: `string`, `number`
Returns:
A dict with the changed properties which indicates if the mutation was successful,
else an error message.
!!! example "Change Metadata Types"
Metadata fields are by default interpreted as `string` types. To change the type
of a metadata field, you can use the `update_properties_in_project` function with the
metadata_types argument. `metadata_types` is given as a dict of metadata field names
as keys and metadata types as values.
```python
kili.update_properties_in_project(
project_id = project_id,
metadata_types = {
'customConsensus': 'number',
'sensitiveData': 'string',
'uploadedFromCloud': 'string',
'modelLabelErrorScore': 'number'
}
)
```
Not providing a type for a metadata field or providing an unsupported one
will default to the `string` type.
"""
return ProjectUseCases(self.kili_api_gateway).update_properties_in_project(
ProjectId(project_id),
can_navigate_between_assets=can_navigate_between_assets,
can_skip_asset=can_skip_asset,
compliance_tags=compliance_tags,
consensus_mark=consensus_mark,
consensus_tot_coverage=consensus_tot_coverage,
description=description,
honeypot_mark=honeypot_mark,
instructions=instructions,
input_type=input_type,
json_interface=json_interface,
min_consensus_size=min_consensus_size,
number_of_assets=number_of_assets,
number_of_skipped_assets=number_of_skipped_assets,
number_of_remaining_assets=number_of_remaining_assets,
number_of_reviewed_assets=number_of_reviewed_assets,
review_coverage=review_coverage,
should_relaunch_kpi_computation=should_relaunch_kpi_computation,
use_honeypot=use_honeypot,
title=title,
metadata_types=metadata_types,
)
@typechecked
# pylint: disable=too-many-arguments
def count_projects(
self,
project_id: Optional[str] = None,
search_query: Optional[str] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
updated_at_gte: Optional[str] = None,
updated_at_lte: Optional[str] = None,
archived: Optional[bool] = None,
) -> int:
# pylint: disable=line-too-long
"""Count the number of projects with a search_query.
Args:
project_id: Select a specific project through its project_id.
search_query: Returned projects with a title or a description matching this [PostgreSQL ILIKE](https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE) pattern.
should_relaunch_kpi_computation: Technical field, added to indicate changes in honeypot
or consensus settings
updated_at_gte: Returned projects should have a label
whose update date is greater
or equal to this date.
updated_at_lte: Returned projects should have a label
whose update date is lower or equal to this date.
archived: If `True`, only archived projects are returned, if `False`, only active projects are returned.
None disable this filter.
!!! info "Dates format"
Date strings should have format: "YYYY-MM-DD"
Returns:
The number of projects with the parameters provided
"""
return ProjectUseCases(self.kili_api_gateway).count_projects(
ProjectFilters(
id=ProjectId(project_id) if project_id else None,
search_query=search_query,
should_relaunch_kpi_computation=should_relaunch_kpi_computation,
updated_at_gte=updated_at_gte,
updated_at_lte=updated_at_lte,
archived=archived,
)
)
count_projects(self, project_id=None, search_query=None, should_relaunch_kpi_computation=None, updated_at_gte=None, updated_at_lte=None, archived=None)
Count the number of projects with a search_query.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
Optional[str] |
Select a specific project through its project_id. |
None |
search_query |
Optional[str] |
Returned projects with a title or a description matching this PostgreSQL ILIKE pattern. |
None |
should_relaunch_kpi_computation |
Optional[bool] |
Technical field, added to indicate changes in honeypot or consensus settings |
None |
updated_at_gte |
Optional[str] |
Returned projects should have a label whose update date is greater or equal to this date. |
None |
updated_at_lte |
Optional[str] |
Returned projects should have a label whose update date is lower or equal to this date. |
None |
archived |
Optional[bool] |
If |
None |
Dates format
Date strings should have format: "YYYY-MM-DD"
Returns:
Type | Description |
---|---|
int |
The number of projects with the parameters provided |
Source code in kili/presentation/client/project.py
def count_projects(
self,
project_id: Optional[str] = None,
search_query: Optional[str] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
updated_at_gte: Optional[str] = None,
updated_at_lte: Optional[str] = None,
archived: Optional[bool] = None,
) -> int:
# pylint: disable=line-too-long
"""Count the number of projects with a search_query.
Args:
project_id: Select a specific project through its project_id.
search_query: Returned projects with a title or a description matching this [PostgreSQL ILIKE](https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE) pattern.
should_relaunch_kpi_computation: Technical field, added to indicate changes in honeypot
or consensus settings
updated_at_gte: Returned projects should have a label
whose update date is greater
or equal to this date.
updated_at_lte: Returned projects should have a label
whose update date is lower or equal to this date.
archived: If `True`, only archived projects are returned, if `False`, only active projects are returned.
None disable this filter.
!!! info "Dates format"
Date strings should have format: "YYYY-MM-DD"
Returns:
The number of projects with the parameters provided
"""
return ProjectUseCases(self.kili_api_gateway).count_projects(
ProjectFilters(
id=ProjectId(project_id) if project_id else None,
search_query=search_query,
should_relaunch_kpi_computation=should_relaunch_kpi_computation,
updated_at_gte=updated_at_gte,
updated_at_lte=updated_at_lte,
archived=archived,
)
)
create_project(self, title, description='', input_type=None, json_interface=None, project_id=None, project_type=None, tags=None, compliance_tags=None)
Create a project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
input_type |
Optional[Literal['IMAGE', 'PDF', 'TEXT', 'VIDEO', 'LLM_RLHF']] |
Currently, one of |
None |
json_interface |
Optional[Dict] |
The json parameters of the project, see Edit your interface. |
None |
title |
str |
Title of the project. |
required |
description |
str |
Description of the project. |
'' |
project_id |
Optional[ProjectId] |
Identifier of the project to copy. |
None |
project_type |
Optional[Literal['IMAGE_CLASSIFICATION_SINGLE', 'IMAGE_CLASSIFICATION_MULTI', 'IMAGE_OBJECT_DETECTION_RECTANGLE', 'IMAGE_OBJECT_DETECTION_POLYGON', 'IMAGE_OBJECT_DETECTION_SEMANTIC', 'IMAGE_POSE_ESTIMATION', 'OCR', 'PDF_CLASSIFICATION_SINGLE', 'PDF_CLASSIFICATION_MULTI', 'PDF_OBJECT_DETECTION_RECTANGLE', 'PDF_NAMED_ENTITY_RECOGNITION', 'SPEECH_TO_TEXT', 'TEXT_CLASSIFICATION_SINGLE', 'TEXT_CLASSIFICATION_MULTI', 'TEXT_TRANSCRIPTION', 'TEXT_NER', 'TIME_SERIES', 'VIDEO_CLASSIFICATION_SINGLE', 'VIDEO_OBJECT_DETECTION', 'VIDEO_FRAME_CLASSIFICATION', 'VIDEO_FRAME_OBJECT_TRACKING']] |
Currently, one of:
|
None |
tags |
Union[List[str], Tuple[str, ...]] |
Tags to add to the project. The tags must already exist in the organization. |
None |
compliance_tags |
Union[List[Literal['PHI', 'PII']], Tuple[Literal['PHI', 'PII'], ...]] |
Compliance tags of the project.
Compliance tags are used to categorize projects based on the sensitivity of
the data being handled and the legal constraints associated with it.
Possible values are: |
None |
Returns:
Type | Description |
---|---|
Dict[Literal['id'], str] |
A dict with the id of the created project. |
Examples:
>>> kili.create_project(input_type='IMAGE', json_interface=json_interface, title='Example')
Recipe
For more detailed examples on how to create projects, see the recipe.
Source code in kili/presentation/client/project.py
def create_project(
self,
title: str,
description: str = "",
input_type: Optional[InputType] = None,
json_interface: Optional[Dict] = None,
project_id: Optional[ProjectId] = None,
project_type: Optional[ProjectType] = None,
tags: Optional[ListOrTuple[str]] = None,
compliance_tags: Optional[ListOrTuple[ComplianceTag]] = None,
) -> Dict[Literal["id"], str]:
# pylint: disable=line-too-long
"""Create a project.
Args:
input_type: Currently, one of `IMAGE`, `PDF`, `TEXT` or `VIDEO`.
json_interface: The json parameters of the project, see Edit your interface.
title: Title of the project.
description: Description of the project.
project_id: Identifier of the project to copy.
project_type: Currently, one of:
- `IMAGE_CLASSIFICATION_MULTI`
- `IMAGE_CLASSIFICATION_SINGLE`
- `IMAGE_OBJECT_DETECTION_POLYGON`
- `IMAGE_OBJECT_DETECTION_RECTANGLE`
- `IMAGE_OBJECT_DETECTION_SEMANTIC`
- `IMAGE_POSE_ESTIMATION`
- `OCR`
- `PDF_CLASSIFICATION_MULTI`
- `PDF_CLASSIFICATION_SINGLE`
- `PDF_NAMED_ENTITY_RECOGNITION`
- `PDF_OBJECT_DETECTION_RECTANGLE`
- `SPEECH_TO_TEXT`
- `TEXT_CLASSIFICATION_MULTI`
- `TEXT_CLASSIFICATION_SINGLE`
- `TEXT_NER`
- `TEXT_TRANSCRIPTION`
- `TIME_SERIES`
- `VIDEO_CLASSIFICATION_SINGLE`
- `VIDEO_FRAME_CLASSIFICATION`
- `VIDEO_FRAME_OBJECT_TRACKING`
tags: Tags to add to the project. The tags must already exist in the organization.
compliance_tags: Compliance tags of the project.
Compliance tags are used to categorize projects based on the sensitivity of
the data being handled and the legal constraints associated with it.
Possible values are: `PHI` and `PII`.
Returns:
A dict with the id of the created project.
Examples:
>>> kili.create_project(input_type='IMAGE', json_interface=json_interface, title='Example')
!!! example "Recipe"
For more detailed examples on how to create projects,
see [the recipe](https://docs.kili-technology.com/recipes/creating-a-project).
"""
project_id = ProjectUseCases(self.kili_api_gateway).create_project(
input_type=input_type,
json_interface=json_interface,
title=title,
description=description,
project_id=project_id,
project_type=project_type,
compliance_tags=compliance_tags,
)
if tags is not None:
tag_use_cases = TagUseCases(self.kili_api_gateway)
tag_ids = tag_use_cases.get_tag_ids_from_labels(labels=tags)
tag_use_cases.tag_project(
project_id=project_id, tag_ids=cast(ListOrTuple[TagId], tag_ids), disable_tqdm=True
)
return {"id": project_id}
projects(self, project_id=None, search_query=None, should_relaunch_kpi_computation=None, updated_at_gte=None, updated_at_lte=None, archived=None, starred=None, tags_in=None, organization_id=None, fields=('consensusTotCoverage', 'id', 'inputType', 'jsonInterface', 'minConsensusSize', 'reviewCoverage', 'roles.id', 'roles.role', 'roles.user.email', 'roles.user.id', 'title'), first=None, skip=0, disable_tqdm=None, *, as_generator=False)
Get a generator or a list of projects that match a set of criteria.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
Optional[str] |
Select a specific project through its project_id. |
None |
search_query |
Optional[str] |
Returned projects with a title or a description matching this PostgreSQL ILIKE pattern. |
None |
should_relaunch_kpi_computation |
Optional[bool] |
Deprecated, do not use. |
None |
updated_at_gte |
Optional[str] |
Returned projects should have a label whose update date is greater or equal to this date. |
None |
updated_at_lte |
Optional[str] |
Returned projects should have a label whose update date is lower or equal to this date. |
None |
archived |
Optional[bool] |
If |
None |
starred |
Optional[bool] |
If |
None |
tags_in |
Union[List[str], Tuple[str, ...]] |
Returned projects should have at least one of these tags. |
None |
organization_id |
Optional[str] |
Returned projects should belong to this organization. |
None |
fields |
Union[List[str], Tuple[str, ...]] |
All the fields to request among the possible fields for the projects. See the documentation for all possible fields. |
('consensusTotCoverage', 'id', 'inputType', 'jsonInterface', 'minConsensusSize', 'reviewCoverage', 'roles.id', 'roles.role', 'roles.user.email', 'roles.user.id', 'title') |
first |
Optional[int] |
Maximum number of projects to return. |
None |
skip |
int |
Number of projects to skip (they are ordered by their creation). |
0 |
disable_tqdm |
Optional[bool] |
If |
None |
as_generator |
bool |
If |
False |
Dates format
Date strings should have format: "YYYY-MM-DD"
Returns:
Type | Description |
---|---|
Iterable[Dict] |
A list of projects or a generator of projects if |
Examples:
>>> # List all my projects
>>> kili.projects()
Source code in kili/presentation/client/project.py
def projects(
self,
project_id: Optional[str] = None,
search_query: Optional[str] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
updated_at_gte: Optional[str] = None,
updated_at_lte: Optional[str] = None,
archived: Optional[bool] = None,
starred: Optional[bool] = None,
tags_in: Optional[ListOrTuple[str]] = None,
organization_id: Optional[str] = None,
fields: ListOrTuple[str] = (
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
),
first: Optional[int] = None,
skip: int = 0,
disable_tqdm: Optional[bool] = None,
*,
as_generator: bool = False,
) -> Iterable[Dict]:
# pylint: disable=line-too-long
"""Get a generator or a list of projects that match a set of criteria.
Args:
project_id: Select a specific project through its project_id.
search_query: Returned projects with a title or a description matching this [PostgreSQL ILIKE](https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE) pattern.
should_relaunch_kpi_computation: Deprecated, do not use.
updated_at_gte: Returned projects should have a label whose update date is greater or equal
to this date.
updated_at_lte: Returned projects should have a label whose update date is lower or equal to this date.
archived: If `True`, only archived projects are returned, if `False`, only active projects are returned.
`None` disables this filter.
starred: If `True`, only starred projects are returned, if `False`, only unstarred projects are returned.
`None` disables this filter.
tags_in: Returned projects should have at least one of these tags.
organization_id: Returned projects should belong to this organization.
fields: All the fields to request among the possible fields for the projects.
See [the documentation](https://docs.kili-technology.com/reference/graphql-api#project) for all possible fields.
first: Maximum number of projects to return.
skip: Number of projects to skip (they are ordered by their creation).
disable_tqdm: If `True`, the progress bar will be disabled.
as_generator: If `True`, a generator on the projects is returned.
!!! info "Dates format"
Date strings should have format: "YYYY-MM-DD"
Returns:
A list of projects or a generator of projects if `as_generator` is `True`.
Examples:
>>> # List all my projects
>>> kili.projects()
"""
tag_ids = (
TagUseCases(self.kili_api_gateway).get_tag_ids_from_labels(tags_in) if tags_in else None
)
disable_tqdm = disable_tqdm_if_as_generator(as_generator, disable_tqdm)
projects_gen = ProjectUseCases(self.kili_api_gateway).list_projects(
ProjectFilters(
id=ProjectId(project_id) if project_id else None,
archived=archived,
search_query=search_query,
should_relaunch_kpi_computation=should_relaunch_kpi_computation,
starred=starred,
updated_at_gte=updated_at_gte,
updated_at_lte=updated_at_lte,
created_at_gte=None,
created_at_lte=None,
organization_id=organization_id,
tag_ids=tag_ids,
),
fields,
options=QueryOptions(disable_tqdm=disable_tqdm, first=first, skip=skip),
)
if as_generator:
return projects_gen
return list(projects_gen)
update_properties_in_project(self, project_id, can_navigate_between_assets=None, can_skip_asset=None, compliance_tags=None, consensus_mark=None, consensus_tot_coverage=None, description=None, honeypot_mark=None, instructions=None, input_type=None, json_interface=None, min_consensus_size=None, number_of_assets=None, number_of_skipped_assets=None, number_of_remaining_assets=None, number_of_reviewed_assets=None, review_coverage=None, should_relaunch_kpi_computation=None, title=None, use_honeypot=None, metadata_types=None)
Update properties of a project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
str |
Identifier of the project. |
required |
can_navigate_between_assets |
Optional[bool] |
Activate / Deactivate the use of next and previous buttons in labeling interface. |
None |
can_skip_asset |
Optional[bool] |
Activate / Deactivate the use of skip button in labeling interface. |
None |
compliance_tags |
Union[List[Literal['PHI', 'PII']], Tuple[Literal['PHI', 'PII'], ...]] |
Compliance tags of the project.
Compliance tags are used to categorize projects based on the sensitivity of
the data being handled and the legal constraints associated with it.
Possible values are: |
None |
consensus_mark |
Optional[float] |
Should be between 0 and 1. |
None |
consensus_tot_coverage |
Optional[int] |
Should be between 0 and 100. It is the percentage of the dataset that will be annotated several times. |
None |
description |
Optional[str] |
Description of the project. |
None |
honeypot_mark |
Optional[float] |
Should be between 0 and 1 |
None |
instructions |
Optional[str] |
Instructions of the project. |
None |
input_type |
Optional[Literal['IMAGE', 'PDF', 'TEXT', 'VIDEO', 'LLM_RLHF']] |
Currently, one of |
None |
json_interface |
Optional[dict] |
The json parameters of the project, see Edit your interface. |
None |
min_consensus_size |
Optional[int] |
Should be between 1 and 10 Number of people that will annotate the same asset, for consensus computation. |
None |
number_of_assets |
Optional[int] |
Defaults to 0 |
None |
number_of_skipped_assets |
Optional[int] |
Defaults to 0 |
None |
number_of_remaining_assets |
Optional[int] |
Defaults to 0 |
None |
number_of_reviewed_assets |
Optional[int] |
Defaults to 0 |
None |
review_coverage |
Optional[int] |
Allow to set the percentage of assets that will be queued in the review interface. Should be between 0 and 100 |
None |
should_relaunch_kpi_computation |
Optional[bool] |
Technical field, added to indicate changes in honeypot or consensus settings |
None |
title |
Optional[str] |
Title of the project |
None |
use_honeypot |
Optional[bool] |
Activate / Deactivate the use of honeypot in the project |
None |
metadata_types |
Optional[dict] |
Types of the project metadata.
Should be a |
None |
Returns:
Type | Description |
---|---|
Dict[str, Any] |
A dict with the changed properties which indicates if the mutation was successful, else an error message. |
Change Metadata Types
Metadata fields are by default interpreted as string
types. To change the type
of a metadata field, you can use the update_properties_in_project
function with the
metadata_types argument. metadata_types
is given as a dict of metadata field names
as keys and metadata types as values.
kili.update_properties_in_project(
project_id = project_id,
metadata_types = {
'customConsensus': 'number',
'sensitiveData': 'string',
'uploadedFromCloud': 'string',
'modelLabelErrorScore': 'number'
}
)
Not providing a type for a metadata field or providing an unsupported one
will default to the string
type.
Source code in kili/presentation/client/project.py
def update_properties_in_project(
self,
project_id: str,
can_navigate_between_assets: Optional[bool] = None,
can_skip_asset: Optional[bool] = None,
compliance_tags: Optional[ListOrTuple[ComplianceTag]] = None,
consensus_mark: Optional[float] = None,
consensus_tot_coverage: Optional[int] = None,
description: Optional[str] = None,
honeypot_mark: Optional[float] = None,
instructions: Optional[str] = None,
input_type: Optional[InputType] = None,
json_interface: Optional[dict] = None,
min_consensus_size: Optional[int] = None,
number_of_assets: Optional[int] = None,
number_of_skipped_assets: Optional[int] = None,
number_of_remaining_assets: Optional[int] = None,
number_of_reviewed_assets: Optional[int] = None,
review_coverage: Optional[int] = None,
should_relaunch_kpi_computation: Optional[bool] = None,
title: Optional[str] = None,
use_honeypot: Optional[bool] = None,
metadata_types: Optional[dict] = None,
) -> Dict[str, Any]:
"""Update properties of a project.
Args:
project_id: Identifier of the project.
can_navigate_between_assets:
Activate / Deactivate the use of next and previous buttons in labeling interface.
can_skip_asset: Activate / Deactivate the use of skip button in labeling interface.
compliance_tags: Compliance tags of the project.
Compliance tags are used to categorize projects based on the sensitivity of
the data being handled and the legal constraints associated with it.
Possible values are: `PHI` and `PII`.
consensus_mark: Should be between 0 and 1.
consensus_tot_coverage: Should be between 0 and 100.
It is the percentage of the dataset that will be annotated several times.
description: Description of the project.
honeypot_mark: Should be between 0 and 1
instructions: Instructions of the project.
input_type: Currently, one of `IMAGE`, `PDF`, `TEXT` or `VIDEO`.
json_interface: The json parameters of the project, see Edit your interface.
min_consensus_size: Should be between 1 and 10
Number of people that will annotate the same asset, for consensus computation.
number_of_assets: Defaults to 0
number_of_skipped_assets: Defaults to 0
number_of_remaining_assets: Defaults to 0
number_of_reviewed_assets: Defaults to 0
review_coverage: Allow to set the percentage of assets
that will be queued in the review interface.
Should be between 0 and 100
should_relaunch_kpi_computation: Technical field, added to indicate changes
in honeypot or consensus settings
title: Title of the project
use_honeypot: Activate / Deactivate the use of honeypot in the project
metadata_types: Types of the project metadata.
Should be a `dict` of metadata fields name as keys and metadata types as values.
Currently, possible types are: `string`, `number`
Returns:
A dict with the changed properties which indicates if the mutation was successful,
else an error message.
!!! example "Change Metadata Types"
Metadata fields are by default interpreted as `string` types. To change the type
of a metadata field, you can use the `update_properties_in_project` function with the
metadata_types argument. `metadata_types` is given as a dict of metadata field names
as keys and metadata types as values.
```python
kili.update_properties_in_project(
project_id = project_id,
metadata_types = {
'customConsensus': 'number',
'sensitiveData': 'string',
'uploadedFromCloud': 'string',
'modelLabelErrorScore': 'number'
}
)
```
Not providing a type for a metadata field or providing an unsupported one
will default to the `string` type.
"""
return ProjectUseCases(self.kili_api_gateway).update_properties_in_project(
ProjectId(project_id),
can_navigate_between_assets=can_navigate_between_assets,
can_skip_asset=can_skip_asset,
compliance_tags=compliance_tags,
consensus_mark=consensus_mark,
consensus_tot_coverage=consensus_tot_coverage,
description=description,
honeypot_mark=honeypot_mark,
instructions=instructions,
input_type=input_type,
json_interface=json_interface,
min_consensus_size=min_consensus_size,
number_of_assets=number_of_assets,
number_of_skipped_assets=number_of_skipped_assets,
number_of_remaining_assets=number_of_remaining_assets,
number_of_reviewed_assets=number_of_reviewed_assets,
review_coverage=review_coverage,
should_relaunch_kpi_computation=should_relaunch_kpi_computation,
use_honeypot=use_honeypot,
title=title,
metadata_types=metadata_types,
)
Set of Project mutations.
Source code in kili/entrypoints/mutations/project/__init__.py
class MutationsProject(BaseOperationEntrypointMixin):
"""Set of Project mutations."""
@typechecked
def append_to_roles(
self,
project_id: str,
user_email: str,
role: Literal["ADMIN", "TEAM_MANAGER", "REVIEWER", "LABELER"] = "LABELER",
) -> Dict:
"""Add a user to a project.
!!! info
If the user does not exist in your organization, he/she is invited and added
both to your organization and project. This function can also be used to change
the role of the user in the project.
Args:
project_id: Identifier of the project
user_email: The email of the user.
This email is used as the unique identifier of the user.
role: The role of the user.
Returns:
A dictionary with the project user information.
Examples:
>>> kili.append_to_roles(project_id=project_id, user_email='john@doe.com')
"""
variables = {
"data": {"role": role, "userEmail": user_email},
"where": {"id": project_id},
}
result = self.graphql_client.execute(GQL_APPEND_TO_ROLES, variables)
project_data = self.format_result("data", result)
for project_user in project_data["roles"]:
if project_user["user"]["email"] == user_email.lower() and project_user["role"] == role:
return project_user
raise MutationError(
f"Failed to mutate user {user_email} to role {role} for project {project_id}."
)
@typechecked
def update_properties_in_role(
self, role_id: str, project_id: str, user_id: str, role: str
) -> Dict:
"""Update properties of a role.
!!! info
To be able to change someone's role, you must be either of:
- an admin of the project
- a team manager of the project
- an admin of the organization
Args:
role_id: Role identifier of the user. E.g. : 'to-be-deactivated'
project_id: Identifier of the project
user_id: The email or identifier of the user with updated role
role: The new role.
Possible choices are: `ADMIN`, `TEAM_MANAGER`, `REVIEWER`, `LABELER`
Returns:
A dictionary with the project user information.
"""
variables = {
"roleID": role_id,
"projectID": project_id,
"userID": user_id,
"role": role,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_ROLE, variables)
return self.format_result("data", result)
@typechecked
def delete_from_roles(self, role_id: str) -> Dict[Literal["id"], str]:
"""Delete users by their role_id.
Args:
role_id: Identifier of the project user (not the ID of the user)
Returns:
A dict with the project id.
"""
variables = {"where": {"id": role_id}}
result = self.graphql_client.execute(GQL_DELETE_FROM_ROLES, variables)
return self.format_result("data", result)
@typechecked
def delete_project(self, project_id: str) -> str:
"""Delete a project permanently.
Args:
project_id: Identifier of the project
Returns:
A string with the deleted project id.
"""
variables = {"where": {"id": project_id}}
result = self.graphql_client.execute(GQL_PROJECT_DELETE_ASYNCHRONOUSLY, variables)
return self.format_result("data", result)
@typechecked
def archive_project(self, project_id: str) -> Dict[Literal["id"], str]:
"""Archive a project.
Args:
project_id: Identifier of the project.
Returns:
A dict with the id of the project.
"""
variables = {
"projectID": project_id,
"archived": True,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return self.format_result("data", result)
@typechecked
def unarchive_project(self, project_id: str) -> Dict[Literal["id"], str]:
"""Unarchive a project.
Args:
project_id: Identifier of the project
Returns:
A dict with the id of the project.
"""
variables = {
"projectID": project_id,
"archived": False,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return self.format_result("data", result)
@typechecked
def copy_project( # pylint: disable=too-many-arguments
self,
from_project_id: str,
title: Optional[str] = None,
description: Optional[str] = None,
copy_json_interface: bool = True,
copy_quality_settings: bool = True,
copy_members: bool = True,
copy_assets: bool = False,
copy_labels: bool = False,
disable_tqdm: Optional[bool] = None,
) -> str:
"""Create new project from an existing project.
Args:
from_project_id: Project ID to copy from.
title: Title for the new project. Defaults to source project
title if `None` is provided.
description: Description for the new project. Defaults to empty string
if `None` is provided.
copy_json_interface: Include json interface in the copy.
copy_quality_settings: Include quality settings in the copy.
copy_members: Include members in the copy.
copy_assets: Include assets in the copy.
copy_labels: Include labels in the copy.
disable_tqdm: Disable tqdm progress bars.
Returns:
The created project ID.
Examples:
>>> kili.copy_project(from_project_id="clbqn56b331234567890l41c0")
"""
return ProjectCopier(self).copy_project( # pyright: ignore[reportGeneralTypeIssues]
from_project_id,
title,
description,
copy_json_interface,
copy_quality_settings,
copy_members,
copy_assets,
copy_labels,
disable_tqdm,
)
@typechecked
def update_project_anonymization(
self, project_id: str, should_anonymize: bool = True
) -> Dict[Literal["id"], str]:
"""Anonymize the project for the labelers and reviewers.
!!! info
Compatible with versions of the Kili app >= 2.135.0
Args:
project_id: Identifier of the project
should_anonymize: The value to be applied. Defaults to `True`.
Returns:
A dict with the id of the project which indicates if the mutation was successful,
or an error message.
Examples:
>>> kili.update_project_anonymization(project_id=project_id)
>>> kili.update_project_anonymization(project_id=project_id, should_anonymize=False)
"""
variables = {
"input": {
"id": project_id,
"shouldAnonymize": should_anonymize,
}
}
result = self.graphql_client.execute(GQL_PROJECT_UPDATE_ANONYMIZATION, variables)
return self.format_result("data", result)
append_to_roles(self, project_id, user_email, role='LABELER')
Add a user to a project.
Info
If the user does not exist in your organization, he/she is invited and added both to your organization and project. This function can also be used to change the role of the user in the project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
str |
Identifier of the project |
required |
user_email |
str |
The email of the user. This email is used as the unique identifier of the user. |
required |
role |
Literal['ADMIN', 'TEAM_MANAGER', 'REVIEWER', 'LABELER'] |
The role of the user. |
'LABELER' |
Returns:
Type | Description |
---|---|
Dict |
A dictionary with the project user information. |
Examples:
>>> kili.append_to_roles(project_id=project_id, user_email='john@doe.com')
Source code in kili/entrypoints/mutations/project/__init__.py
def append_to_roles(
self,
project_id: str,
user_email: str,
role: Literal["ADMIN", "TEAM_MANAGER", "REVIEWER", "LABELER"] = "LABELER",
) -> Dict:
"""Add a user to a project.
!!! info
If the user does not exist in your organization, he/she is invited and added
both to your organization and project. This function can also be used to change
the role of the user in the project.
Args:
project_id: Identifier of the project
user_email: The email of the user.
This email is used as the unique identifier of the user.
role: The role of the user.
Returns:
A dictionary with the project user information.
Examples:
>>> kili.append_to_roles(project_id=project_id, user_email='john@doe.com')
"""
variables = {
"data": {"role": role, "userEmail": user_email},
"where": {"id": project_id},
}
result = self.graphql_client.execute(GQL_APPEND_TO_ROLES, variables)
project_data = self.format_result("data", result)
for project_user in project_data["roles"]:
if project_user["user"]["email"] == user_email.lower() and project_user["role"] == role:
return project_user
raise MutationError(
f"Failed to mutate user {user_email} to role {role} for project {project_id}."
)
archive_project(self, project_id)
Archive a project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
str |
Identifier of the project. |
required |
Returns:
Type | Description |
---|---|
Dict[Literal['id'], str] |
A dict with the id of the project. |
Source code in kili/entrypoints/mutations/project/__init__.py
def archive_project(self, project_id: str) -> Dict[Literal["id"], str]:
"""Archive a project.
Args:
project_id: Identifier of the project.
Returns:
A dict with the id of the project.
"""
variables = {
"projectID": project_id,
"archived": True,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return self.format_result("data", result)
copy_project(self, from_project_id, title=None, description=None, copy_json_interface=True, copy_quality_settings=True, copy_members=True, copy_assets=False, copy_labels=False, disable_tqdm=None)
Create new project from an existing project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
from_project_id |
str |
Project ID to copy from. |
required |
title |
Optional[str] |
Title for the new project. Defaults to source project
title if |
None |
description |
Optional[str] |
Description for the new project. Defaults to empty string
if |
None |
copy_json_interface |
bool |
Include json interface in the copy. |
True |
copy_quality_settings |
bool |
Include quality settings in the copy. |
True |
copy_members |
bool |
Include members in the copy. |
True |
copy_assets |
bool |
Include assets in the copy. |
False |
copy_labels |
bool |
Include labels in the copy. |
False |
disable_tqdm |
Optional[bool] |
Disable tqdm progress bars. |
None |
Returns:
Type | Description |
---|---|
str |
The created project ID. |
Examples:
>>> kili.copy_project(from_project_id="clbqn56b331234567890l41c0")
Source code in kili/entrypoints/mutations/project/__init__.py
def copy_project( # pylint: disable=too-many-arguments
self,
from_project_id: str,
title: Optional[str] = None,
description: Optional[str] = None,
copy_json_interface: bool = True,
copy_quality_settings: bool = True,
copy_members: bool = True,
copy_assets: bool = False,
copy_labels: bool = False,
disable_tqdm: Optional[bool] = None,
) -> str:
"""Create new project from an existing project.
Args:
from_project_id: Project ID to copy from.
title: Title for the new project. Defaults to source project
title if `None` is provided.
description: Description for the new project. Defaults to empty string
if `None` is provided.
copy_json_interface: Include json interface in the copy.
copy_quality_settings: Include quality settings in the copy.
copy_members: Include members in the copy.
copy_assets: Include assets in the copy.
copy_labels: Include labels in the copy.
disable_tqdm: Disable tqdm progress bars.
Returns:
The created project ID.
Examples:
>>> kili.copy_project(from_project_id="clbqn56b331234567890l41c0")
"""
return ProjectCopier(self).copy_project( # pyright: ignore[reportGeneralTypeIssues]
from_project_id,
title,
description,
copy_json_interface,
copy_quality_settings,
copy_members,
copy_assets,
copy_labels,
disable_tqdm,
)
delete_from_roles(self, role_id)
Delete users by their role_id.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
role_id |
str |
Identifier of the project user (not the ID of the user) |
required |
Returns:
Type | Description |
---|---|
Dict[Literal['id'], str] |
A dict with the project id. |
Source code in kili/entrypoints/mutations/project/__init__.py
def delete_from_roles(self, role_id: str) -> Dict[Literal["id"], str]:
"""Delete users by their role_id.
Args:
role_id: Identifier of the project user (not the ID of the user)
Returns:
A dict with the project id.
"""
variables = {"where": {"id": role_id}}
result = self.graphql_client.execute(GQL_DELETE_FROM_ROLES, variables)
return self.format_result("data", result)
delete_project(self, project_id)
Delete a project permanently.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
str |
Identifier of the project |
required |
Returns:
Type | Description |
---|---|
str |
A string with the deleted project id. |
Source code in kili/entrypoints/mutations/project/__init__.py
def delete_project(self, project_id: str) -> str:
"""Delete a project permanently.
Args:
project_id: Identifier of the project
Returns:
A string with the deleted project id.
"""
variables = {"where": {"id": project_id}}
result = self.graphql_client.execute(GQL_PROJECT_DELETE_ASYNCHRONOUSLY, variables)
return self.format_result("data", result)
unarchive_project(self, project_id)
Unarchive a project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
str |
Identifier of the project |
required |
Returns:
Type | Description |
---|---|
Dict[Literal['id'], str] |
A dict with the id of the project. |
Source code in kili/entrypoints/mutations/project/__init__.py
def unarchive_project(self, project_id: str) -> Dict[Literal["id"], str]:
"""Unarchive a project.
Args:
project_id: Identifier of the project
Returns:
A dict with the id of the project.
"""
variables = {
"projectID": project_id,
"archived": False,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return self.format_result("data", result)
update_project_anonymization(self, project_id, should_anonymize=True)
Anonymize the project for the labelers and reviewers.
Info
Compatible with versions of the Kili app >= 2.135.0
Parameters:
Name | Type | Description | Default |
---|---|---|---|
project_id |
str |
Identifier of the project |
required |
should_anonymize |
bool |
The value to be applied. Defaults to |
True |
Returns:
Type | Description |
---|---|
Dict[Literal['id'], str] |
A dict with the id of the project which indicates if the mutation was successful, or an error message. |
Examples:
>>> kili.update_project_anonymization(project_id=project_id)
>>> kili.update_project_anonymization(project_id=project_id, should_anonymize=False)
Source code in kili/entrypoints/mutations/project/__init__.py
def update_project_anonymization(
self, project_id: str, should_anonymize: bool = True
) -> Dict[Literal["id"], str]:
"""Anonymize the project for the labelers and reviewers.
!!! info
Compatible with versions of the Kili app >= 2.135.0
Args:
project_id: Identifier of the project
should_anonymize: The value to be applied. Defaults to `True`.
Returns:
A dict with the id of the project which indicates if the mutation was successful,
or an error message.
Examples:
>>> kili.update_project_anonymization(project_id=project_id)
>>> kili.update_project_anonymization(project_id=project_id, should_anonymize=False)
"""
variables = {
"input": {
"id": project_id,
"shouldAnonymize": should_anonymize,
}
}
result = self.graphql_client.execute(GQL_PROJECT_UPDATE_ANONYMIZATION, variables)
return self.format_result("data", result)
update_properties_in_role(self, role_id, project_id, user_id, role)
Update properties of a role.
Info
To be able to change someone's role, you must be either of:
- an admin of the project
- a team manager of the project
- an admin of the organization
Parameters:
Name | Type | Description | Default |
---|---|---|---|
role_id |
str |
Role identifier of the user. E.g. : 'to-be-deactivated' |
required |
project_id |
str |
Identifier of the project |
required |
user_id |
str |
The email or identifier of the user with updated role |
required |
role |
str |
The new role.
Possible choices are: |
required |
Returns:
Type | Description |
---|---|
Dict |
A dictionary with the project user information. |
Source code in kili/entrypoints/mutations/project/__init__.py
def update_properties_in_role(
self, role_id: str, project_id: str, user_id: str, role: str
) -> Dict:
"""Update properties of a role.
!!! info
To be able to change someone's role, you must be either of:
- an admin of the project
- a team manager of the project
- an admin of the organization
Args:
role_id: Role identifier of the user. E.g. : 'to-be-deactivated'
project_id: Identifier of the project
user_id: The email or identifier of the user with updated role
role: The new role.
Possible choices are: `ADMIN`, `TEAM_MANAGER`, `REVIEWER`, `LABELER`
Returns:
A dictionary with the project user information.
"""
variables = {
"roleID": role_id,
"projectID": project_id,
"userID": user_id,
"role": role,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_ROLE, variables)
return self.format_result("data", result)