Skip to content

Commit ca534bd

Browse files
Switch from pk to uuid for entity identifier
1 parent 2a8d61c commit ca534bd

File tree

11 files changed

+223
-188
lines changed

11 files changed

+223
-188
lines changed

aiida_restapi/repository/entity.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class EntityRepository(t.Generic[EntityType, EntityModelType]):
1818
"""
1919

2020
def __init__(self, entity_class: type[EntityType]) -> None:
21-
self.entity_class: type[EntityType] = entity_class
21+
self.entity_class = entity_class
2222

2323
def get_entity_schema(self, which: t.Literal['get', 'post'] | None = None) -> dict:
2424
"""Get JSON schema for the AiiDA entity.
@@ -45,7 +45,7 @@ def get_projectable_properties(self) -> list[str]:
4545
"""
4646
return self.entity_class.fields.keys()
4747

48-
def get_entities(self, queries: QueryParams) -> PaginatedResults:
48+
def get_entities(self, queries: QueryParams) -> PaginatedResults[EntityModelType]:
4949
"""Get AiiDA entities with optional filtering, sorting, and/or pagination.
5050
5151
:param queries: The query parameters, including filters, order_by, page_size, and page.
@@ -65,25 +65,25 @@ def get_entities(self, queries: QueryParams) -> PaginatedResults:
6565
results=[self.to_model(result) for result in results],
6666
)
6767

68-
def get_entity_by_id(self, entity_id: int) -> EntityModelType:
68+
def get_entity_by_id(self, identifier: str | int) -> EntityModelType:
6969
"""Get an AiiDA entity by id.
7070
71-
:param entity_id: The id of the entity to retrieve.
71+
:param identifier: The id of the entity to retrieve.
7272
:return: The AiiDA entity model, e.g. `orm.User.Model`, `orm.Node.Model`, etc.
7373
"""
74-
entity = self.entity_class.collection.get(pk=entity_id)
74+
entity = self.entity_class.collection.get(**{self.entity_class.identity_field: identifier})
7575
return self.to_model(entity)
7676

77-
def get_entity_extras(self, entity_id: int) -> dict[str, t.Any]:
77+
def get_entity_extras(self, identifier: str | int) -> dict[str, t.Any]:
7878
"""Get the extras of an entity.
7979
80-
:param entity_id: The id of the entity to retrieve the extras for.
80+
:param identifier: The id of the entity to retrieve the extras for.
8181
:return: A dictionary with the entity extras.
8282
"""
8383
return t.cast(
8484
dict,
8585
self.entity_class.collection.query(
86-
filters={'pk': entity_id},
86+
filters={self.entity_class.identity_field: identifier},
8787
project=['extras'],
8888
).first()[0],
8989
)

aiida_restapi/repository/node.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ def get_all_download_formats(self, full_type: str | None = None) -> dict:
7474

7575
return all_formats
7676

77-
def get_node_repository_metadata(self, node_id: int) -> dict[str, dict]:
77+
def get_node_repository_metadata(self, uuid: str) -> dict[str, dict]:
7878
"""Get the repository metadata of a node.
7979
80-
:param node_id: The id of the node to retrieve the repository metadata for.
80+
:param uuid: The uuid of the node to retrieve the repository metadata for.
8181
:return: A dictionary with the repository file metadata.
8282
"""
83-
node = self.entity_class.collection.get(pk=node_id)
83+
node = self.entity_class.collection.get(uuid=uuid)
8484
total_size = 0
8585

8686
def get_metadata(objects: list[File], path: str | None = None) -> dict[str, dict]:
@@ -113,7 +113,7 @@ def get_metadata(objects: list[File], path: str | None = None) -> dict[str, dict
113113
'type': 'FILE',
114114
'binary': binary,
115115
'size': size,
116-
'download': f'/nodes/{node_id}/repo/contents?filename={obj_name}',
116+
'download': f'/nodes/{uuid}/repo/contents?filename={obj_name}',
117117
}
118118
total_size += size
119119

@@ -126,39 +126,39 @@ def get_metadata(objects: list[File], path: str | None = None) -> dict[str, dict
126126
'type': 'FILE',
127127
'binary': True,
128128
'size': total_size,
129-
'download': f'/nodes/{node_id}/repo/contents',
129+
'download': f'/nodes/{uuid}/repo/contents',
130130
}
131131

132132
return metadata
133133

134-
def get_node_attributes(self, node_id: int) -> dict[str, t.Any]:
134+
def get_node_attributes(self, uuid: str) -> dict[str, t.Any]:
135135
"""Get the attributes of a node.
136136
137-
:param node_id: The id of the node to retrieve the attributes for.
137+
:param uuid: The uuid of the node to retrieve the attributes for.
138138
:return: A dictionary with the node attributes.
139139
"""
140140
return t.cast(
141141
dict,
142142
self.entity_class.collection.query(
143-
filters={'pk': node_id},
143+
filters={'uuid': uuid},
144144
project=['attributes'],
145145
).first()[0],
146146
)
147147

148148
def get_node_links(
149149
self,
150-
node_id: int,
150+
uuid: str,
151151
queries: QueryParams,
152152
direction: t.Literal['incoming', 'outgoing'],
153153
) -> PaginatedResults[NodeLinks]:
154154
"""Get the incoming links of a node.
155155
156-
:param node_id: The id of the node to retrieve the incoming links for.
156+
:param uuid: The uuid of the node to retrieve the incoming links for.
157157
:param queries: The query parameters, including filters, order_by, page_size, and page.
158158
:param direction: Specify whether to retrieve incoming or outgoing links.
159159
:return: The paginated requested linked nodes.
160160
"""
161-
node = self.entity_class.collection.get(pk=node_id)
161+
node = self.entity_class.collection.get(uuid=uuid)
162162

163163
if direction == 'incoming':
164164
link_collection = node.base.links.get_incoming()

aiida_restapi/routers/computers.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ async def get_computers_schema(
3232
3333
:param which: The type of schema to retrieve: 'get' or 'post'.
3434
:return: A dictionary with 'get' and 'post' keys containing the respective JSON schemas.
35-
:raises HTTPException: 422 if the 'which' parameter is not 'get' or 'post'.
35+
:raises HTTPException: 422 if the 'which' parameter is not 'get' or 'post',
36+
500 for any other failures.
3637
"""
3738
try:
3839
return repository.get_entity_schema(which=which)
39-
except ValueError as err:
40-
raise HTTPException(status_code=422, detail=str(err)) from err
40+
except ValueError as exception:
41+
raise HTTPException(status_code=422, detail=str(exception)) from exception
42+
except Exception as exception:
43+
raise HTTPException(status_code=500, detail=str(exception)) from exception
4144

4245

4346
@read_router.get('/computers/projectable_properties', response_model=list[str])
@@ -68,39 +71,45 @@ async def get_computers(
6871

6972

7073
@read_router.get(
71-
'/computers/{computer_id}',
74+
'/computers/{pk}',
7275
response_model=orm.Computer.Model,
7376
response_model_exclude_none=True,
7477
response_model_exclude_unset=True,
7578
)
7679
@with_dbenv()
77-
async def get_computer(computer_id: int) -> orm.Computer.Model:
78-
"""Get AiiDA computer by id.
80+
async def get_computer(pk: str) -> orm.Computer.Model:
81+
"""Get AiiDA computer by pk.
7982
80-
:param computer_id: The id of the AiiDA computer.
83+
:param pk: The pk of the AiiDA computer.
8184
:return: The computer model.
82-
:raises HTTPException: 404 if the computer with the given id does not exist.
85+
:raises HTTPException: 404 if the computer with the given pk does not exist,
86+
500 for any other failures.
8387
"""
8488
try:
85-
return repository.get_entity_by_id(computer_id)
86-
except NotExistent:
87-
raise HTTPException(status_code=404, detail=f'Could not find a Computer with id {computer_id}')
89+
return repository.get_entity_by_id(pk)
90+
except NotExistent as exception:
91+
raise HTTPException(status_code=404, detail=str(exception)) from exception
92+
except Exception as exception:
93+
raise HTTPException(status_code=500, detail=str(exception)) from exception
8894

8995

90-
@read_router.get('/computers/{computer_id}/metadata', response_model=dict[str, t.Any])
96+
@read_router.get('/computers/{pk}/metadata', response_model=dict[str, t.Any])
9197
@with_dbenv()
92-
async def get_computer_metadata(computer_id: int) -> dict[str, t.Any]:
93-
"""Get metadata of an AiiDA computer by id.
98+
async def get_computer_metadata(pk: str) -> dict[str, t.Any]:
99+
"""Get metadata of an AiiDA computer by pk.
94100
95-
:param computer_id: The id of the AiiDA computer.
101+
:param pk: The pk of the AiiDA computer.
96102
:return: The metadata dictionary of the computer.
97-
:raises HTTPException: 404 if the computer with the given id does not exist.
103+
:raises HTTPException: 404 if the computer with the given pk does not exist,
104+
500 for any other failures.
98105
"""
99106
try:
100-
computer = repository.get_entity_by_id(computer_id)
107+
computer = repository.get_entity_by_id(pk)
101108
return computer.metadata
102-
except NotExistent:
103-
raise HTTPException(status_code=404, detail=f'Could not find a Computer with id {computer_id}')
109+
except NotExistent as exception:
110+
raise HTTPException(status_code=404, detail=str(exception)) from exception
111+
except Exception as exception:
112+
raise HTTPException(status_code=500, detail=str(exception)) from exception
104113

105114

106115
@write_router.post(
@@ -123,5 +132,5 @@ async def create_computer(
123132
"""
124133
try:
125134
return repository.create_entity(computer_model)
126-
except Exception as err:
127-
raise HTTPException(status_code=500, detail=str(err))
135+
except Exception as exception:
136+
raise HTTPException(status_code=500, detail=str(exception))

aiida_restapi/routers/groups.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ async def get_groups_schema(
3232
3333
:param which: The type of schema to retrieve: 'get' or 'post'.
3434
:return: A dictionary with 'get' and 'post' keys containing the respective JSON schemas.
35-
:raises HTTPException: 422 if the 'which' parameter is not 'get' or 'post'.
35+
:raises HTTPException: 422 if the 'which' parameter is not 'get' or 'post',
36+
500 for any other failures.
3637
"""
3738
try:
3839
return repository.get_entity_schema(which=which)
39-
except ValueError as err:
40-
raise HTTPException(status_code=422, detail=str(err)) from err
40+
except ValueError as exception:
41+
raise HTTPException(status_code=422, detail=str(exception)) from exception
42+
except Exception as exception:
43+
raise HTTPException(status_code=500, detail=str(exception)) from exception
4144

4245

4346
@read_router.get('/groups/projectable_properties', response_model=list[str])
@@ -68,47 +71,47 @@ async def get_groups(
6871

6972

7073
@read_router.get(
71-
'/groups/{group_id}',
74+
'/groups/{uuid}',
7275
response_model=orm.Group.Model,
7376
response_model_exclude_none=True,
7477
response_model_exclude_unset=True,
7578
)
7679
@with_dbenv()
77-
async def get_group(group_id: int) -> orm.Group.Model:
78-
"""Get AiiDA group by id.
80+
async def get_group(uuid: str) -> orm.Group.Model:
81+
"""Get AiiDA group by uuid.
7982
80-
:param group_id: The id of the group to retrieve.
83+
:param uuid: The uuid of the group to retrieve.
8184
:return: The AiiDA group model.
82-
:raises HTTPException: 404 if a group with the given id does not exist,
85+
:raises HTTPException: 404 if a group with the given uuid does not exist,
8386
500 for any other server error.
8487
"""
8588
try:
86-
return repository.get_entity_by_id(group_id)
87-
except NotExistent:
88-
raise HTTPException(status_code=404, detail=f'Could not find a Group with id {group_id}')
89-
except Exception as err:
90-
raise HTTPException(status_code=500, detail=str(err))
89+
return repository.get_entity_by_id(uuid)
90+
except NotExistent as exception:
91+
raise HTTPException(status_code=404, detail=str(exception)) from exception
92+
except Exception as exception:
93+
raise HTTPException(status_code=500, detail=str(exception)) from exception
9194

9295

9396
@read_router.get(
94-
'/groups/{group_id}/extras',
97+
'/groups/{uuid}/extras',
9598
response_model=dict[str, t.Any],
9699
)
97100
@with_dbenv()
98-
async def get_group_extras(group_id: int) -> dict[str, t.Any]:
101+
async def get_group_extras(uuid: str) -> dict[str, t.Any]:
99102
"""Get the extras of a group.
100103
101-
:param group_id: The id of the group to retrieve the extras for.
104+
:param uuid: The uuid of the group to retrieve the extras for.
102105
:return: A dictionary with the group extras.
103-
:raises HTTPException: 404 if the group with the given id does not exist,
106+
:raises HTTPException: 404 if the group with the given uuid does not exist,
104107
500 for other failures during retrieval.
105108
"""
106109
try:
107-
return repository.get_entity_extras(group_id)
108-
except NotExistent:
109-
raise HTTPException(status_code=404, detail=f'Could not find any group with id {group_id}')
110-
except Exception as err:
111-
raise HTTPException(status_code=500, detail=str(err)) from err
110+
return repository.get_entity_extras(uuid)
111+
except NotExistent as exception:
112+
raise HTTPException(status_code=404, detail=str(exception)) from exception
113+
except Exception as exception:
114+
raise HTTPException(status_code=500, detail=str(exception)) from exception
112115

113116

114117
@write_router.post(
@@ -131,5 +134,5 @@ async def create_group(
131134
"""
132135
try:
133136
return repository.create_entity(group_model)
134-
except Exception as err:
135-
raise HTTPException(status_code=500, detail=str(err))
137+
except Exception as exception:
138+
raise HTTPException(status_code=500, detail=str(exception)) from exception

0 commit comments

Comments
 (0)