Skip to content

ProjectOperations

Access via client.projects.

crucible.resources.projects.ProjectOperations

Project-related API operations.

Access via: client.projects.get(), client.projects.list(), etc.

get(project_ref=None, include_metadata=False, include_members=False, project_id=None, project_mfid=None)

Get a project by canonical MFID or human-readable project slug.

The response always includes project_id, organization, status, title.

The lead field is a public-safe user record containing canonical identity, username, and name, but never email.

scientific_metadata is only ever populated for members/admins — include_metadata is silently ignored for non-members. Same gating applies to members (list of {unique_id, username, first_name, last_name, role}) with include_members - non-members always get members: None regardless of the flag.

Parameters:

Name Type Description Default
project_ref str

Project MFID or project slug. Lookup accepts legacy slugs outside the current write limits.

None
project_id str

Explicit project slug

None
project_mfid str

Explicit project MFID

None
include_metadata bool

Whether to include scientific metadata (members/admins only)

False
include_members bool

Whether to include the member list (members/admins only)

False

Returns:

Name Type Description
Dict Dict

Project information, with membership-gated fields as described above

list(orcid=None, include_metadata=False, limit=DEFAULT_LIMIT, offset=0, accessible_to_user=None, accessible_to_project=None)

List all accessible projects.

Each project dict includes a lead key with the project lead's public-safe user record.

Parameters:

Name Type Description Default
orcid str

Filter projects by those associated with a certain user

None
include_metadata bool

Include scientific metadata in results

False
limit int

Maximum number of results to return (default: 100)

DEFAULT_LIMIT
offset int

Starting position in the full result set (default: 0)

0
accessible_to_user Optional[Union[str, Sequence[str]]]

User reference or references whose effective access must include every result

None
accessible_to_project Optional[Union[str, Sequence[str]]]

Project reference or references whose direct access must include every result

None

Returns:

Type Description
List[Dict]

List[Dict]: Project metadata including project_id, title, organization, lead

create(project, scientific_metadata=None)

Create a new project.

Any authenticated user may create a project. The selected lead must be an existing user.

Parameters:

Name Type Description Default
project Union[Project, Dict]

A Project model instance or a dict with project_id, organization, and project_lead_email. Alternatively, pass a flexible project_lead field (ORCID, username, or email - resolved server-side) instead of the three explicit project_lead_orcid/project_lead_email/ project_lead_username fields; providing both is a 400, as is providing neither.

required
scientific_metadata Dict

Scientific metadata to attach after creation.

None

Returns:

Name Type Description
Dict Dict

Created project object

Example

from crucible.models import Project project = Project( ... project_id="my-project", ... organization="Molecular Foundry", ... project_lead_email="lead@lbl.gov" ... ) result = client.projects.create(project)

update(proj_id, **kwargs)

Partially update a project record.

Requires admin permissions.

Leadership changes are not accepted here (422) - use transfer_ownership() instead, which moves owner standing and the denormalized lead pointer atomically.

Note the identifying parameter is named proj_id, not project_id - project_id is itself now a valid field in **kwargs (it renames the project), and the two would collide if both were named the same.

Parameters:

Name Type Description Default
proj_id str

Unique project identifier

required
**kwargs

Fields to update. Accepted: project_id (renames the project), organization, status, title.

{}

Returns:

Name Type Description
Dict Dict

Updated project object

search(q, limit=20)

Fuzzy search across all projects (not just the caller's). Available to all authenticated users — supports project discovery ahead of request_join().

Matches against both title and project_id. Results never include lead or scientific_metadata, regardless of membership.

Parameters:

Name Type Description Default
q str

Search term (min 3 chars). Typo-tolerant.

required
limit int

Max results (default 20, max 50).

20

Returns:

Type Description
List[Dict]

List[Dict]: Matching ProjectRead records, ranked by relevance.

get_users(project_id, limit=DEFAULT_LIMIT, offset=0)

Get users associated with a project.

Requires admin permissions.

Parameters:

Name Type Description Default
project_id str

Unique project identifier

required
limit int

Maximum number of results to return (default: 100)

DEFAULT_LIMIT
offset int

Starting position in the full result set (default: 0)

0

Returns:

Type Description
List[ProjectMember]

List[ProjectMember]: Project team members (excludes project lead)

add_user(user_unique_id=None, project_id=None, email=None, username=None, role=None)

Add a user to a project.

Requires editor or above in the project. The granted role must be strictly below the caller's role. Editors may grant contributor or viewer, admins may also grant editor, and owners may also grant admin. Platform administrators retain their bypass. Ownership changes use transfer_ownership().

Email and username inputs are resolved before the canonical membership request.

Parameters:

Name Type Description Default
user_unique_id str

Canonical user ORCID or MFID

None
project_id str

Unique project identifier

None
email str

User's email address

None
username str

User's username

None
role str

Role to grant (default: contributor)

None

Returns:

Type Description
List[ProjectMember]

List[ProjectMember]: Updated list of project users

update_user_role(project_id, user_unique_id, role)

Change a member's role in a project.

Requires editor or above in the project. Both the member's current role and their requested role must be strictly below the caller's role. Platform administrators retain their bypass. Ownership changes use transfer_ownership().

Parameters:

Name Type Description Default
project_id str

Unique project identifier

required
user_unique_id str

Canonical user ORCID or MFID

required
role str

New role to grant

required

Returns:

Type Description
List[ProjectMember]

List[ProjectMember]: Updated list of project users

remove_user(project_id, user_unique_id=None, email=None, username=None)

Remove a user from a project.

Project owners and platform administrators may remove members. A member may also remove themselves.

Email and username inputs are resolved before the canonical membership request.

Parameters:

Name Type Description Default
project_id str

Unique project identifier

required
user_unique_id str

Canonical user ORCID or MFID

None
email str

User's email address

None
username str

User's username

None

Returns:

Type Description
List[ProjectMember]

List[ProjectMember]: Updated list of project users

request_join(project_id, reason=None)

Request to join this project. Any authenticated user.

Delegates to client.access_groups.request_join() — see there for full list/approve/reject operations on join requests.

Parameters:

Name Type Description Default
project_id str

Unique project identifier.

required
reason Optional[str]

Optional explanation for the request.

None

Returns:

Name Type Description
Dict Dict

The created JoinRequest record (status will be "pending").

Raises:

Type Description
HTTPError 404

Project doesn't exist.

HTTPError 409

Already a member, or already has a pending request.

list_join_requests(project_id, status=None, limit=DEFAULT_LIMIT, offset=0)

List join requests for this project. Admin or the project lead only.

Delegates to client.access_groups.list_join_requests(group_name=project_id).

Parameters:

Name Type Description Default
project_id str

Unique project identifier.

required
status Optional[str]

Filter by "pending", "approved", or "rejected".

None
limit int

Maximum number of results.

DEFAULT_LIMIT
offset int

Starting position in the full result set.

0

Returns:

Type Description
List[Dict]

List[Dict]: Matching JoinRequest records, most recent first.