Working with Projects
This page provides basic examples on how to work with projects. For full explanation of all options, refer to the conceptual part of the documentation.
Create a project¶
var project = await _projectClient.CreateProjectAsync(new CreateProjectInput { Name = "My First Project" });
Console.WriteLine(project.Id);
Get project details¶
var projectId = "fa36c0e0-1575-4b3c-8ebf-1c4e7e67e967"; // you need to know the GUID of the project, you can get it e.g. from Cloud Admin UI
var project = await _projectClient.GetProjectAsync(project.Id);
Console.WriteLine(project.Name);
List projects¶
There can be many projects in the tenant or in a project. Therefore, the GetProjectListAsync
method on ProjecClient
uses pagination, so that the client-server communication does not get overloaded. Specifying some ProjectListOptions
may greatly reduce the response size and therefore improve performance of your application.
List the 5 latest projects:
var options = new ProjectListOptions
{
SortBy = ProjectSortProperty.UpdatedAt,
SortOrder = Contracts.SortOrder.Desc,
Limit = 5,
};
var page = await _projectClient.GetProjectListAsync(options);
foreach (var project in page) {
Console.WriteList(project.Name);
}
The ProjectListOptions
can be useful also when finding project by Name:
var options = new ProjectListOptions
{
NamePrefix = "MyProject",
SortBy = ProjectSortProperty.Name,
SortOrder = Contracts.SortOrder.Asc,
Limit = 5,
};
var page = await _projectClient.GetProjectListAsync(options);
var project = page.SingleOrDefault(p => p.Name == "MyProject") ?? throw new InvalidOperationException("None or multiple projects with the name found);
Console.WriteList(project.id);
The methods above list projects directly under a specific project. If you want to get a recursive list, i.e. list of all subprojects within a project, use the HierarchyClient
. For instance, define a method and use it like this (including pagination):
private async IAsyncEnumerable<IEnumerable<DatasetRecursiveListOutput>> _GetAllProjects
(
Guid projectId,
[EnumeratorCancellation] CancellationToken cancellationToken = default
)
{
var page = await _hierarchyClient.GetRecursiveProjectListAsync(projectId, pageSizeLimit: 500, cancellationToken);
while (page != default)
{
if (!page.Items.Any())
yield break;
yield return page.Items;
page = await page.NextAsync(cancellationToken);
}
}
var projects = await _GetAllProject(projectId);
Update project members¶
When you create a project, you can also set a list of principals (e.g. users), who should be members of the project. You can also modify the member list after you create the project. You need to know the principal Id. Principal Id is created when the user is onboarded. As of May 2024, it is possible to get User id from Cloud Admin UI application. Alternatively, if you have sufficient privileges, you can list members of the Site (tenant). For that you either need to know the tenant Id, or you can get yours it from the UserClient
:
var me = await _userClient.GetMeAsync();
var tenantId = me.TenantId;
var tenantMembers = await _iamClient.ListTenantMembers(tenantId);
var user = tenantMembers.SingleOrDefault(m => m.Email == "desired@email.com") ?? throw new NullReferenceException("User not found");
var userId = ((UserIdentityOutput)user).UserIdentityId;
var member = new ProjectMemberInput() { UserId = userId, Role = "Contributor" };
await _projectClient.SetMembers(projectId, new[] { member });
To get a list of project members:
var members = await _projectClient.GetMembersAsync(projectId);
foreach (var m in members) {
Console.WriteLine($"{m.UserId}, {m.PrincipalType}, {m.Role}");
}
Very similar methods and usage exists also for Subprojects, i.e. for projects within projects.
Update project description and metadata¶
There might be multiple users updating a project, but we need to keep the data consistent. This is ensured by the "Row Version" mechanism. When updating a project, you need to supply a Row Version. If your version does not match the Row Version in the Platform, your update request will fail, because the data in the Platform has been edited between the time you got the project and sent your update request.
In this example, we update also project metadata. Notice how the myapp:lastaction
entry is prepended with a new piece of information. The way how project metadata is structured and used is up to the client application(s). For the Platform, it is a plain Dictionary<string, object>
. We recommend using namespacing by :
like showed in this example in order to keep metadata of different applications separate. However, since Project metadata is a dictionary of objects, you could also put metadata required by your application under one key, e.g {"myapp": {"lastaction": "some value"}}
.
var project = await _projectClient.GetProjectAsync(projectId);
var rowVersion = project.RowVersion;
var metadata = result.Metadata ?? new Dictionary<string, object>();
var myMetadata = new Dictionary<string, object>();
myMetadata["myapp:oneoffentry"] = "Simple entry that will overwrite the key in original metadata if it already exists";
var myActionNote = "updated 2024-04-30;";
metadata["myapp:lastaction"] = metadata.ContainsKey("myapp:lastaction")
? myActionNote + metadata["myapp:lastaction"].ToString()
: myActionNote;
metadata = metadata.Concat(myMetadata).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
await _projectClient.UpdateProjectAsync(new EditProjectInput() { Description = "", Metadata = metadata , RowVersion = rowVersion });
Move a project to a different project¶
The ProjectClient
has a method to move project to another project. The project is simply assigned to the new parent project and the project keeps its original project ID.
await client.MoveProjectAsync(sourceProjectId, targetProjectId);
Delete a project¶
To delete a project completely, set the parameter permanently
to true
. The default value of the parameter is false
, which means the project would be "soft deleted" and ends up in the Recycle Bin, where you still pay for the storage consumption. Note however, you cannot restore a permanently deleted project. Deleting a project deletes all datasets and their data under that project.
await projectClient.DeleteProjectAsync(subProject.Id, permanently: true);