Skip to content

Commit c8de76f

Browse files
committed
feat(apiclient): add CRUD methods for instantiated entities
1 parent 4a53c29 commit c8de76f

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

cellengine/utils/api_client/APIClient.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
import json
44
import pandas
55
from getpass import getpass
6-
from typing import Any, Dict, List, Union, Optional
6+
from typing import (
7+
Any,
8+
Dict,
9+
List,
10+
TypeVar,
11+
Union,
12+
Optional,
13+
)
714
from functools import lru_cache
815
from requests_toolbelt.multipart.encoder import MultipartEncoder
916

@@ -20,6 +27,8 @@
2027
from ...resources.scaleset import ScaleSet
2128

2229

30+
CE = TypeVar("CE", bound=Union[Attachment, Compensation, Experiment, FcsFile, Gate, Plot, Population, ScaleSet])
31+
2332
class APIClient(BaseAPIClient, metaclass=Singleton):
2433
_API_NAME = "CellEngine Python Toolkit"
2534

@@ -119,6 +128,53 @@ def update_entity(self, experiment_id, _id, entity_type, body) -> dict:
119128
json=body,
120129
)
121130

131+
def _get_path(self, entity: CE) -> str:
132+
fullpath = f"{self.base_url}/{entity.path}"
133+
return fullpath
134+
135+
def create(self, entity: CE, **kwargs) -> CE:
136+
"""Create a local entity on CellEngine."""
137+
if type(entity) is list:
138+
return self.create_multiple(entity, **kwargs) # type: ignore
139+
path = self._get_path(entity)
140+
structure_class = entity.__class__
141+
if structure_class.__bases__[0] is not object:
142+
structure_class = structure_class.__bases__[0]
143+
body = converter.unstructure(entity)
144+
145+
if body["_id"] == "None" or body["_id"] is None:
146+
del body["_id"] # https://github.com/primitybio/cellengine/issues/5800
147+
148+
res = self._post(path, json=body, params=kwargs)
149+
return converter.structure(res, structure_class) # type: ignore
150+
151+
# TODO: add type annotation for entities
152+
def create_multiple(self, entities: List[CE], **kwargs) -> List[CE]:
153+
path = self._get_path(entities[0])
154+
structure_class = entities[0].__class__
155+
if structure_class.__bases__[0] is not object:
156+
structure_class = structure_class.__bases__[0]
157+
structure_class = List[structure_class]
158+
159+
body = converter.unstructure(entities)
160+
161+
for item in body:
162+
if item["_id"] == "None" or item["_id"] is None:
163+
del item["_id"]
164+
res = self._post(path, json=body, params=kwargs)
165+
return converter.structure(res, structure_class)
166+
167+
def update(self, entity):
168+
# TODO: entity.path property
169+
path = self._get_path(entity)
170+
data = converter.unstructure(entity)
171+
res = self._patch(path, json=data,)
172+
return converter.structure(res, entity.__class__)
173+
174+
def delete(self, entity) -> None:
175+
path = self._get_path(entity)
176+
self._delete(path)
177+
122178
def delete_entity(self, experiment_id, entity_type, _id):
123179
url = f"{self.base_url}/experiments/{experiment_id}/{entity_type}/{_id}"
124180
self._delete(url)

0 commit comments

Comments
 (0)