Skip to content

Commit

Permalink
refactor; Implemented API endopints
Browse files Browse the repository at this point in the history
  • Loading branch information
doctrino committed Jan 20, 2024
1 parent 26b5cbc commit f76ce95
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 8 deletions.
24 changes: 18 additions & 6 deletions cognite/client/_api/projects.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
from __future__ import annotations

from typing import Sequence, overload

from cognite.client._api_client import APIClient
from cognite.client.data_classes import Project, ProjectUpdate, ProjectWrite
from cognite.client.data_classes import Project, ProjectList, ProjectUpdate, ProjectURLNameList, ProjectWrite


class ProjectsAPI(APIClient):
_RESOURCE_PATH = "/projects"

@overload
def create(self, item: ProjectWrite) -> Project:
...

@overload
def create(self, item: Sequence[ProjectWrite]) -> ProjectList:
...

def create(self, item: ProjectWrite | Sequence[ProjectWrite]) -> Project | ProjectList:
"""`Create a project <https://developer.cognite.com/api#tag/Projects/operation/createProject>`_"""
raise NotImplementedError
return self._create_multiple(item, list_cls=ProjectList, resource_cls=Project, input_resource_cls=ProjectWrite)

def retrieve(self, project: str) -> Project:
"""`Retrieve a project <https://developer.cognite.com/api#tag/Projects/operation/getProject>`_"""
raise NotImplementedError
item = self._get(f"{self._RESOURCE_PATH}/{project}")
return Project._load(item.json(), cognite_client=self._cognite_client)

def update(self, item: ProjectWrite | ProjectUpdate) -> Project:
"""`Update a project <https://developer.cognite.com/api#tag/Projects/operation/updateProject>`_"""
raise NotImplementedError
return self._update_multiple(item, list_cls=ProjectList, resource_cls=Project, update_cls=ProjectUpdate)

def list(self) -> list[str]:
def list(self) -> ProjectURLNameList:
"""`List all projects <https://developer.cognite.com/api#tag/Projects/operation/listProjects>`_"""
raise NotImplementedError
items = self._get(self._RESOURCE_PATH)
return ProjectURLNameList.load(items.json(), cognite_client=self._cognite_client)
16 changes: 15 additions & 1 deletion cognite/client/data_classes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,17 @@
LabelDefinitionWrite,
LabelFilter,
)
from cognite.client.data_classes.projects import Claim, OIDCConfiguration, Project, ProjectUpdate, ProjectWrite
from cognite.client.data_classes.projects import (
Claim,
OIDCConfiguration,
Project,
ProjectList,
ProjectUpdate,
ProjectURLName,
ProjectURLNameList,
ProjectWrite,
ProjectWriteList,
)
from cognite.client.data_classes.raw import (
Database,
DatabaseList,
Expand Down Expand Up @@ -561,6 +571,10 @@
"Project",
"ProjectUpdate",
"ProjectWrite",
"ProjectURLName",
"ProjectURLNameList",
"ProjectWriteList",
"ProjectList",
"OIDCConfiguration",
"Claim",
]
41 changes: 40 additions & 1 deletion cognite/client/data_classes/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
CogniteObjectUpdate,
CognitePrimitiveUpdate,
CogniteResource,
CogniteResourceList,
CogniteUpdate,
PropertySpec,
WriteableCogniteResource,
)
from cognite.client.data_classes.user_profiles import UserProfilesConfiguration

Expand Down Expand Up @@ -110,7 +112,24 @@ def dump(self, camel_case: bool = True) -> dict[str, Any]:
return output


class ProjectCore(CogniteResource, ABC):
class ProjectURLName(CogniteResource):
"""A project URL name is a unique identifier for a project.
Args:
url_name (str): The URL name of the project. This is used as part of the request path in API calls.
Valid URL names contain between 3 and 32 characters, and may only contain English letters, digits and hyphens,
must contain at least one letter and may not start or end with a hyphen.
"""

def __init__(self, url_name: str) -> None:
self.url_name = url_name

@classmethod
def _load(cls, resource: dict[str, Any], cognite_client: CogniteClient | None = None) -> ProjectURLName:
return cls(url_name=resource["urlName"])


class ProjectCore(WriteableCogniteResource["ProjectWrite"], ABC):
"""Projects are used to isolate data in CDF rom each other. All objects in CDF belong to a single project,
and objects in different projects are isolated from each other.
Expand Down Expand Up @@ -168,6 +187,10 @@ def __init__(
# is required for the Read format but not the Write format.
self.user_profiles_configuration = user_profiles_configuration

def as_write(self) -> ProjectWrite:
"""Returns this instance which is a Project Write"""
return self

@classmethod
def _load(cls, resource: dict[str, Any], cognite_client: CogniteClient | None = None) -> ProjectWrite:
return cls(
Expand Down Expand Up @@ -230,6 +253,10 @@ def __init__(
# is required for the Read format but not the Write format.
self.user_profiles_configuration = user_profiles_configuration

def as_write(self) -> ProjectWrite:
"""Returns this instance which is a Project Write"""
raise NotImplementedError("Project cannot be used as a ProjectWrite")

@classmethod
def _load(cls, resource: dict[str, Any], cognite_client: CogniteClient | None = None) -> Project:
return cls(
Expand Down Expand Up @@ -301,3 +328,15 @@ def _get_update_properties(cls) -> list[PropertySpec]:
PropertySpec("oidc_configuration", is_nullable=True),
PropertySpec("user_profiles_configuration", is_nullable=False),
]


class ProjectURLNameList(CogniteResourceList[ProjectURLName]):
_RESOURCE = ProjectURLName


class ProjectList(CogniteResourceList[Project]):
_RESOURCE = Project


class ProjectWriteList(CogniteResourceList[ProjectWrite]):
_RESOURCE = ProjectWrite
20 changes: 20 additions & 0 deletions tests/tests_integration/test_api/test_projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from __future__ import annotations

import pytest

from cognite.client.data_classes import ProjectURLName, ProjectURLNameList


@pytest.fixture(scope="module")
def available_projects(cognite_client) -> ProjectURLNameList:
if projects := cognite_client.iam.projects.list():
return projects
pytest.skip("Can't test projects without any projects available", allow_module_level=True)


@pytest.mark.skip(reason="Lack access to projects to perform operations")
class TestProjects:
def test_list_projects(self, available_projects: ProjectURLNameList) -> None:
assert len(available_projects) >= 1, "Expected at least one project"
assert isinstance(available_projects, ProjectURLNameList)
assert isinstance(available_projects[0], ProjectURLName)

0 comments on commit f76ce95

Please sign in to comment.