Project module
Queries
Set of Project queries.
Source code in kili/entrypoints/queries/project/__init__.py
class QueriesProject:
"""Set of Project queries."""
graphql_client: GraphQLClient
# pylint: disable=too-many-arguments,dangerous-default-value
@overload
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,
skip: int = 0,
fields: List[str] = [
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
],
first: Optional[int] = None,
disable_tqdm: bool = False,
*,
as_generator: Literal[True],
) -> Generator[Dict, None, None]:
...
@overload
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,
skip: int = 0,
fields: List[str] = [
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
],
first: Optional[int] = None,
disable_tqdm: bool = False,
*,
as_generator: Literal[False] = False,
) -> List[Dict]:
...
@typechecked
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,
skip: int = 0,
fields: List[str] = [
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
],
first: Optional[int] = None,
disable_tqdm: bool = False,
*,
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: 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` disables this filter.
skip: Number of projects to skip (they are ordered by their creation).
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.
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()
"""
where = ProjectWhere(
project_id=project_id,
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,
)
disable_tqdm = disable_tqdm_if_as_generator(as_generator, disable_tqdm)
options = QueryOptions(disable_tqdm, first, skip)
projects_gen = ProjectQuery(self.graphql_client)(where, fields, options)
if as_generator:
return projects_gen
return list(projects_gen)
@typechecked
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
"""Counts 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
"""
where = ProjectWhere(
project_id=project_id,
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,
)
return ProjectQuery(self.graphql_client).count(where)
count_projects(self, project_id=None, search_query=None, should_relaunch_kpi_computation=None, updated_at_gte=None, updated_at_lte=None, archived=None)
Counts 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/entrypoints/queries/project/__init__.py
@typechecked
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
"""Counts 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
"""
where = ProjectWhere(
project_id=project_id,
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,
)
return ProjectQuery(self.graphql_client).count(where)
projects(self, project_id=None, search_query=None, should_relaunch_kpi_computation=None, updated_at_gte=None, updated_at_lte=None, archived=None, skip=0, fields=['consensusTotCoverage', 'id', 'inputType', 'jsonInterface', 'minConsensusSize', 'reviewCoverage', 'roles.id', 'roles.role', 'roles.user.email', 'roles.user.id', 'title'], first=None, disable_tqdm=False, *, 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] |
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 |
skip |
int |
Number of projects to skip (they are ordered by their creation). |
0 |
fields |
List[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 |
disable_tqdm |
bool |
If |
False |
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/entrypoints/queries/project/__init__.py
@typechecked
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,
skip: int = 0,
fields: List[str] = [
"consensusTotCoverage",
"id",
"inputType",
"jsonInterface",
"minConsensusSize",
"reviewCoverage",
"roles.id",
"roles.role",
"roles.user.email",
"roles.user.id",
"title",
],
first: Optional[int] = None,
disable_tqdm: bool = False,
*,
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: 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` disables this filter.
skip: Number of projects to skip (they are ordered by their creation).
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.
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()
"""
where = ProjectWhere(
project_id=project_id,
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,
)
disable_tqdm = disable_tqdm_if_as_generator(as_generator, disable_tqdm)
options = QueryOptions(disable_tqdm, first, skip)
projects_gen = ProjectQuery(self.graphql_client)(where, fields, options)
if as_generator:
return projects_gen
return list(projects_gen)
Mutations
Set of Project mutations.
Source code in kili/entrypoints/mutations/project/__init__.py
class MutationsProject:
"""Set of Project mutations."""
graphql_client: GraphQLClient
# pylint: disable=too-many-arguments,too-many-locals
@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 dictionnary 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 = format_result("data", result)
for project_user in project_data["roles"]:
if project_user["user"]["email"] == user_email 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_project(
self,
project_id: str,
can_navigate_between_assets: Optional[bool] = None,
can_skip_asset: Optional[bool] = 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[str] = 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.
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.
Examples:
>>> kili.update_properties_in_project(project_id=project_id, title='New title')
!!! 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.
Example:
```
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.
"""
verify_argument_ranges(consensus_tot_coverage, min_consensus_size, review_coverage)
variables = {
"canNavigateBetweenAssets": can_navigate_between_assets,
"canSkipAsset": can_skip_asset,
"consensusMark": consensus_mark,
"consensusTotCoverage": consensus_tot_coverage,
"description": description,
"honeypotMark": honeypot_mark,
"instructions": instructions,
"inputType": input_type,
"jsonInterface": dumps(json_interface) if json_interface is not None else None,
"metadataTypes": metadata_types,
"minConsensusSize": min_consensus_size,
"numberOfAssets": number_of_assets,
"numberOfSkippedAssets": number_of_skipped_assets,
"numberOfRemainingAssets": number_of_remaining_assets,
"numberOfReviewedAssets": number_of_reviewed_assets,
"projectID": project_id,
"reviewCoverage": review_coverage,
"shouldRelaunchKpiComputation": should_relaunch_kpi_computation,
"title": title,
"useHoneyPot": use_honeypot,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
result = format_result("data", result)
variables.pop("projectID")
variables = {k: v for k, v in variables.items() if v is not None}
new_project_settings = services.get_project(self, project_id, list(variables.keys()))
result = {**result, **new_project_settings}
return result
@typechecked
def create_project(
self,
input_type: str,
json_interface: dict,
title: str,
description: str = "",
project_type: Optional[str] = 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_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`
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).
"""
variables = {
"data": {
"description": description,
"inputType": input_type,
"jsonInterface": dumps(json_interface),
"projectType": project_type,
"title": title,
}
}
result = self.graphql_client.execute(GQL_CREATE_PROJECT, variables)
result = format_result("data", result)
# We check during 60s for the project to be created
for attempt in Retrying(
stop=stop_after_delay(60),
wait=wait_fixed(1),
retry=retry_if_exception_type(NotFound),
reraise=True,
):
with attempt:
_ = services.get_project(self, project_id=result["id"], fields=["id"])
return result
@typechecked
def update_properties_in_role(self, role_id: str, project_id: str, user_id: str, role: str):
"""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 result object which indicates if the mutation was successful,
or an error message.
"""
variables = {
"roleID": role_id,
"projectID": project_id,
"userID": user_id,
"role": role,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_ROLE, variables)
return format_result("data", result)
@typechecked
def delete_from_roles(self, role_id: str):
"""Delete users by their role_id.
Args:
role_id: Identifier of the project user (not the ID of the user)
Returns:
A result object which indicates if the mutation was successful,
or an error message.
"""
variables = {"where": {"id": role_id}}
result = self.graphql_client.execute(GQL_DELETE_FROM_ROLES, variables)
return 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 result object which indicates if the mutation was successful,
or an error message.
"""
variables = {"where": {"id": project_id}}
result = self.graphql_client.execute(GQL_PROJECT_DELETE_ASYNCHRONOUSLY, variables)
return format_result("data", result)
@typechecked
def archive_project(self, project_id: str):
"""Archive a project.
Args:
project_id: Identifier of the project
Returns:
A result object which indicates if the mutation was successful, or an error message.
"""
variables = {
"projectID": project_id,
"archived": True,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return format_result("data", result)
@typechecked
def unarchive_project(self, project_id: str):
"""Unarchive a project.
Args:
project_id: Identifier of the project
Returns:
A result object which indicates if the mutation was successful,
or an error message.
"""
variables = {
"projectID": project_id,
"archived": False,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return 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: bool = False,
) -> 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(
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 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 |
typing_extensions.Literal['ADMIN', 'TEAM_MANAGER', 'REVIEWER', 'LABELER'] |
The role of the user. |
'LABELER' |
Returns:
Type | Description |
---|---|
Dict |
A dictionnary 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
@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 dictionnary 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 = format_result("data", result)
for project_user in project_data["roles"]:
if project_user["user"]["email"] == user_email 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 |
---|---|
A result object which indicates if the mutation was successful, or an error message. |
Source code in kili/entrypoints/mutations/project/__init__.py
@typechecked
def archive_project(self, project_id: str):
"""Archive a project.
Args:
project_id: Identifier of the project
Returns:
A result object which indicates if the mutation was successful, or an error message.
"""
variables = {
"projectID": project_id,
"archived": True,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return 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=False)
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 |
bool |
Disable tqdm progress bars. |
False |
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
@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: bool = False,
) -> 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(
from_project_id,
title,
description,
copy_json_interface,
copy_quality_settings,
copy_members,
copy_assets,
copy_labels,
disable_tqdm,
)
create_project(self, input_type, json_interface, title, description='', project_type=None)
Create a project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
input_type |
str |
Currently, one of |
required |
json_interface |
dict |
The json parameters of the project, see Edit your interface. |
required |
title |
str |
Title of the project. |
required |
description |
str |
Description of the project. |
'' |
project_type |
Optional[str] |
Currently, one of:
|
None |
Returns:
Type | Description |
---|---|
Dict[typing_extensions.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/entrypoints/mutations/project/__init__.py
@typechecked
def create_project(
self,
input_type: str,
json_interface: dict,
title: str,
description: str = "",
project_type: Optional[str] = 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_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`
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).
"""
variables = {
"data": {
"description": description,
"inputType": input_type,
"jsonInterface": dumps(json_interface),
"projectType": project_type,
"title": title,
}
}
result = self.graphql_client.execute(GQL_CREATE_PROJECT, variables)
result = format_result("data", result)
# We check during 60s for the project to be created
for attempt in Retrying(
stop=stop_after_delay(60),
wait=wait_fixed(1),
retry=retry_if_exception_type(NotFound),
reraise=True,
):
with attempt:
_ = services.get_project(self, project_id=result["id"], fields=["id"])
return result
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 |
---|---|
A result object which indicates if the mutation was successful, or an error message. |
Source code in kili/entrypoints/mutations/project/__init__.py
@typechecked
def delete_from_roles(self, role_id: str):
"""Delete users by their role_id.
Args:
role_id: Identifier of the project user (not the ID of the user)
Returns:
A result object which indicates if the mutation was successful,
or an error message.
"""
variables = {"where": {"id": role_id}}
result = self.graphql_client.execute(GQL_DELETE_FROM_ROLES, variables)
return 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 result object which indicates if the mutation was successful, or an error message. |
Source code in kili/entrypoints/mutations/project/__init__.py
@typechecked
def delete_project(self, project_id: str) -> str:
"""Delete a project permanently.
Args:
project_id: Identifier of the project
Returns:
A result object which indicates if the mutation was successful,
or an error message.
"""
variables = {"where": {"id": project_id}}
result = self.graphql_client.execute(GQL_PROJECT_DELETE_ASYNCHRONOUSLY, variables)
return 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 |
---|---|
A result object which indicates if the mutation was successful, or an error message. |
Source code in kili/entrypoints/mutations/project/__init__.py
@typechecked
def unarchive_project(self, project_id: str):
"""Unarchive a project.
Args:
project_id: Identifier of the project
Returns:
A result object which indicates if the mutation was successful,
or an error message.
"""
variables = {
"projectID": project_id,
"archived": False,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
return 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[typing_extensions.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
@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 format_result("data", result)
update_properties_in_project(self, project_id, can_navigate_between_assets=None, can_skip_asset=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 |
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[str] |
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. |
Examples:
>>> kili.update_properties_in_project(project_id=project_id, title='New title')
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.
Example:
kili.update_properties_in_project(
project_id = project_id,
metadata_types = {
'customConsensus': 'number',
'sensitiveData': 'string',
'uploadedFromCloud': 'string',
'modelLabelErrorScore': 'number'
}
)
string
type.
Source code in kili/entrypoints/mutations/project/__init__.py
@typechecked
def update_properties_in_project(
self,
project_id: str,
can_navigate_between_assets: Optional[bool] = None,
can_skip_asset: Optional[bool] = 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[str] = 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.
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.
Examples:
>>> kili.update_properties_in_project(project_id=project_id, title='New title')
!!! 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.
Example:
```
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.
"""
verify_argument_ranges(consensus_tot_coverage, min_consensus_size, review_coverage)
variables = {
"canNavigateBetweenAssets": can_navigate_between_assets,
"canSkipAsset": can_skip_asset,
"consensusMark": consensus_mark,
"consensusTotCoverage": consensus_tot_coverage,
"description": description,
"honeypotMark": honeypot_mark,
"instructions": instructions,
"inputType": input_type,
"jsonInterface": dumps(json_interface) if json_interface is not None else None,
"metadataTypes": metadata_types,
"minConsensusSize": min_consensus_size,
"numberOfAssets": number_of_assets,
"numberOfSkippedAssets": number_of_skipped_assets,
"numberOfRemainingAssets": number_of_remaining_assets,
"numberOfReviewedAssets": number_of_reviewed_assets,
"projectID": project_id,
"reviewCoverage": review_coverage,
"shouldRelaunchKpiComputation": should_relaunch_kpi_computation,
"title": title,
"useHoneyPot": use_honeypot,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_PROJECT, variables)
result = format_result("data", result)
variables.pop("projectID")
variables = {k: v for k, v in variables.items() if v is not None}
new_project_settings = services.get_project(self, project_id, list(variables.keys()))
result = {**result, **new_project_settings}
return 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 |
---|---|
A result object which indicates if the mutation was successful, or an error message. |
Source code in kili/entrypoints/mutations/project/__init__.py
@typechecked
def update_properties_in_role(self, role_id: str, project_id: str, user_id: str, role: str):
"""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 result object which indicates if the mutation was successful,
or an error message.
"""
variables = {
"roleID": role_id,
"projectID": project_id,
"userID": user_id,
"role": role,
}
result = self.graphql_client.execute(GQL_UPDATE_PROPERTIES_IN_ROLE, variables)
return format_result("data", result)