Projects
Projects group related resources with collaborators and storage. Use this resource for CRUD, archiving, collaborator management, and listing a project's volumes and workspaces.
Access it as client.projects on a Strongly client, or the same path on AsyncStrongly with await. All methods exist on both with identical signatures.
Quick start
from strongly import Strongly
client = Strongly()
# List (auto-paginates as you iterate) # filters: search, status, category, tag, sort
for project in client.projects.list():
print(project.id)
Methods
Core
list
list(*, search: str | None = None, status: str | None = None, category: str | None = None, tag: str | None = None, sort: str | None = None, limit: int | None = None) -> SyncPaginator[Project]
List the projects you can see, newest first.
Parameters
search(str | None, optional): Only projects whose name or description contains this text (case insensitive).status(str | None, optional): Only projects with this status:"active","paused"or"archived".category(str | None, optional): Only projects in this category:"machine-learning","data-analysis","development"or"research".tag(str | None, optional): Only projects carrying this tag.sort(str | None, optional): The order, as comma-separated wire field names, each prefixed with-for descending (for example"name"). The API's default is"-createdAt".limit(int | None, optional): The most projects to return;Nonereturns every one.
Returns
SyncPaginator[Project]: The projects, fetched a page at a time.
create
create(*, name: str, description: str, filesystem_type: str | None = None, github_config: Mapping[str, str] | None = None, tags: Sequence[str] | None = None) -> Project
Create a project, with its own code and data volume.
The project belongs to you and your organization. Its volume is
provisioned as it is created; when that fails the project is still
created, with filesystem_config.initialized False and the reason
in filesystem_config.init_error.
Parameters
name(str): The project's name, unique (ignoring case) among your organization's projects and volumes.description(str): What the project is for.filesystem_type(str | None, optional):"github"keeps the project's code in a GitHub repository. The API's default (and its choice for any other value) is"strongly", the platform's own storage.github_config(Mapping[str, str] | None, optional): The repository, for"github"(required there):repoUrl(an SSH URL),branchandsshKeyId(one ofUsers.github_ssh_keys).tags(Sequence[str] | None, optional): Tags for the project.
Returns
Project: The new project.
Raises
ConflictError: A project or volume in your organization already has this name (error_codeduplicate).ValidationError:nameis blank, orgithub_configis missing or invalid for a GitHub project.
retrieve
retrieve(project_id: str) -> Project
Retrieve a project you can see.
Parameters
project_id(str): The project's id.
Returns
Project: The project.
Raises
NotFoundError: There is no such project, or you cannot see it.
update
update(project_id: str, *, name: str | None = None, description: str | None = None, icon: str | None = None, category: str | None = None, tags: Sequence[str] | None = None, readme: str | None = None) -> Project
Update a project's details (its owner and editors).
Only the fields you give change; returns the project, as retrieve
does. Visibility is set with set_visibility, the status with
archive and restore.
Parameters
project_id(str): The project's id.name(str | None, optional): The project's name (1 to 100 characters), unique among your organization's projects and volumes.description(str | None, optional): Its description (up to 500 characters).icon(str | None, optional): Its icon:"folder","brain","code","database","chart-line","cpu","layers"or"package".category(str | None, optional):"machine-learning","data-analysis","development"or"research".tags(Sequence[str] | None, optional): The project's tags, replacing the current ones.readme(str | None, optional): The project's readme, in Markdown.
Raises
NotFoundError: There is no such project.PermissionDeniedError: You may not change the project (a viewer).ConflictError:nameis taken (error_codeduplicate).ValidationError:nameis blank orcategoryis not one of the four.
delete
delete(project_id: str, *, volume: Literal['delete', 'keep']) -> None
Delete a project and everything it owns.
The project's data is archived first. Its jobs (live runs are stopped), workspaces, run history, board and activity are deleted.
Parameters
project_id(str): The project's id.volume({"delete", "keep"}): What happens to the project's code and data volume:"delete"deletes it with its code and data;"keep"keeps it as a shared volume owned by the project's owner.
Raises
NotFoundError: There is no such project.PermissionDeniedError: You may not delete the project.ConflictError:volume="keep"and the owner already has a shared volume with this name (error_codeduplicate).
Lifecycle & actions
archive
archive(project_id: str) -> Project
Archive a project.
Its status becomes archived, and its own volumes are archived with it.
Parameters
project_id(str): The project's id.
Raises
UnprocessableEntityError: A workspace of the project is running or a job run is live.
restore
restore(project_id: str) -> Project
Restore an archived project to active, with the volumes archived with it.
Returns the project.
Parameters
project_id(str): The project's id.
Other
add_collaborator
add_collaborator(project_id: str, *, email: str, role: str, user_id: str | None = None) -> AddedCollaborator
Add a collaborator to a project (its owner and editors).
The user is found by user_id when given, else by email.
Parameters
project_id(str): The project's id.email(str): The collaborator's email address (the API requires it even withuser_id).role(str):"editor"(may change the project) or"viewer".user_id(str | None, optional): The collaborator's user id.
Returns
AddedCollaborator: The collaborator's user id.
Raises
NotFoundError: There is no such user (or they are outside your organization).ConflictError: The user is already a collaborator (error_codeduplicate).UnprocessableEntityError: You added yourself.ValidationError:roleis not"editor"or"viewer".
collaborator_removal_impact
collaborator_removal_impact(project_id: str, user_id: str) -> dict[str, Any]
Before removing a collaborator: their workspaces and jobs in the project.
Parameters
project_id(str): The project's ID.user_id(str): The collaborator's user ID.
counts
counts(*, status: str | None = None, category: str | None = None, search: str | None = None) -> dict[str, Any]
Count each project's workspaces and jobs, and those running or in error.
These are the Projects page's counts, per project and in total.
Parameters
status(str | None, optional): Only projects with this status (archived); every project not archived when omitted.category(str | None, optional): Only projects of this category.search(str | None, optional): Only projects whose name or description contains this.
deletion_impact
deletion_impact(project_id: str) -> dict[str, Any]
Before deleting a project: whether it can be, and what outside it still uses it.
Parameters
project_id(str): The project's ID.
list_activity
list_activity(project_id: str, *, sort: str | None = None, limit: int | None = None) -> SyncPaginator[ProjectActivity]
List a project's activity feed, newest first.
Parameters
project_id(str): The project's id.sort(str | None, optional): The order, as comma-separated wire field names, each prefixed with-for descending. The API's default is"-createdAt".limit(int | None, optional): The most entries to return;Nonereturns every one.
Returns
SyncPaginator[ProjectActivity]: The entries, fetched a page at a time.
list_collaborators
list_collaborators(project_id: str) -> list[ProjectCollaborator]
List who can reach a project: its owner, then its collaborators.
Parameters
project_id(str): The project's id.
Returns
list[ProjectCollaborator]: The owner and each collaborator with their role.
list_volumes
list_volumes(project_id: str) -> list[Volume]
List a project's volumes, archived ones included.
Parameters
project_id(str): The project's id.
Returns
list[Volume]: The volumes whose project is this one.
list_workspaces
list_workspaces(project_id: str, *, sort: str | None = None, limit: int | None = None) -> SyncPaginator[Workspace]
List a project's workspaces, newest first.
Parameters
project_id(str): The project's id.sort(str | None, optional): The order, as comma-separated wire field names, each prefixed with-for descending (for example"name"). The API's default is"-createdAt".limit(int | None, optional): The most workspaces to return;Nonereturns every one.
Returns
SyncPaginator[Workspace]: The workspaces, fetched a page at a time.
remove_collaborator
remove_collaborator(project_id: str, user_id: str) -> None
Remove a collaborator from a project.
Parameters
project_id(str): The project's id.user_id(str): The collaborator's user id; not the owner.
Raises
UnprocessableEntityError:user_idis the project's owner.
set_visibility
set_visibility(project_id: str, *, is_public: bool) -> Project
Allow all users of your organization on a project, or make it private.
A project that allows all users (visibility organization) can be found and used
by everyone in the organization; editing stays with its owner and
editors. A private one (private) is reached only by its owner and
collaborators.
Parameters
project_id(str): The project's id.is_public(bool):Trueto allow all users,Falsefor private.
stats
stats(project_id: str) -> ProjectStats
Return a project's statistics: its jobs, workspaces, volumes and cost.
Parameters
project_id(str): The project's id.
Returns
ProjectStats: The counts, hours and cost the platform records for the project.
transfer_ownership
transfer_ownership(project_id: str, *, new_owner_id: str) -> Project
Give a project to another user (its owner, or an admin).
The new owner owns the project and its volumes and leaves the collaborators; the previous owner stays on as an editor.
Parameters
project_id(str): The project's id.new_owner_id(str): The new owner's user id: an active user other than the owner.
Returns
Project: The project, itsownerthe new owner.
Raises
PermissionDeniedError: You are not the owner or an admin.ValidationError:new_owner_idis the current owner, or not an active user.
update_collaborator
update_collaborator(project_id: str, user_id: str, *, role: str) -> ProjectCollaborator
Change a collaborator's role.
Parameters
project_id(str): The project's id.user_id(str): The collaborator's user id.role(str):"editor"or"viewer".
Raises
NotFoundError: The user is not a collaborator.ValidationError:roleis not"editor"or"viewer".