Skip to content

Commit c4dba67

Browse files
committed
added assay, analysis mutations
1 parent fd691b3 commit c4dba67

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed

api/graphql/mutations/__init__.py

+21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import strawberry
22

3+
from api.graphql.mutations.analysis import AnalysisMutations
4+
from api.graphql.mutations.analysis_runner import AnalysisRunnerMutations
5+
from api.graphql.mutations.assay import AssayMutations
36
from api.graphql.mutations.family import FamilyMutations
47
from api.graphql.mutations.participant import ParticipantMutations
58
from api.graphql.mutations.project import ProjectMutations
@@ -40,3 +43,21 @@ def sample(self) -> SampleMutations:
4043
def sequencing_groups(self) -> SequencingGroupsMutations:
4144
"""Sequencing group mutations"""
4245
return SequencingGroupsMutations()
46+
47+
# Analysis
48+
@strawberry.field
49+
def analysis(self) -> AnalysisMutations:
50+
"""Analysis mutations"""
51+
return AnalysisMutations()
52+
53+
# Assay
54+
@strawberry.field
55+
def assay(self) -> AssayMutations:
56+
"""Assay mutations"""
57+
return AssayMutations()
58+
59+
# Analysis Runner
60+
@strawberry.field
61+
def analysis_runner(self) -> AnalysisRunnerMutations:
62+
"""Analysis Runner mutations"""
63+
return AnalysisRunnerMutations()

api/graphql/mutations/analysis.py

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import strawberry
2+
from strawberry.types import Info
3+
4+
from api.graphql.types import AnalysisInput, AnalysisUpdateInput
5+
from db.python.layers.analysis import AnalysisLayer
6+
from models.models.analysis import AnalysisInternal
7+
8+
9+
@strawberry.type
10+
class AnalysisMutations:
11+
"""Analysis mutations"""
12+
13+
@strawberry.mutation
14+
async def create_analysis(
15+
self,
16+
analysis: AnalysisInput,
17+
info: Info,
18+
) -> int:
19+
"""Create a new analysis"""
20+
# TODO: Reconfigure connection permissions as per `routes`
21+
connection = info.context['connection']
22+
atable = AnalysisLayer(connection)
23+
24+
if analysis.author:
25+
# special tracking here, if we can't catch it through the header
26+
connection.on_behalf_of = analysis.author
27+
28+
if not analysis.sequencing_group_ids and not analysis.cohort_ids:
29+
raise ValueError('Must specify "sequencing_group_ids" or "cohort_ids"')
30+
31+
analysis_id = await atable.create_analysis(
32+
AnalysisInternal.from_dict(strawberry.asdict(analysis)),
33+
)
34+
35+
return analysis_id
36+
37+
@strawberry.mutation
38+
async def update_analysis(
39+
self,
40+
analysis_id: int,
41+
analysis: AnalysisUpdateInput,
42+
info: Info,
43+
) -> bool:
44+
"""Update status of analysis"""
45+
# TODO: Reconfigure connection permissions as per `routes`
46+
connection = info.context['connection']
47+
atable = AnalysisLayer(connection)
48+
await atable.update_analysis(
49+
analysis_id,
50+
status=analysis.status,
51+
output=analysis.output,
52+
meta=analysis.meta,
53+
)
54+
return True
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import datetime
2+
3+
import strawberry
4+
from strawberry.types import Info
5+
6+
from db.python.layers.analysis_runner import AnalysisRunnerLayer
7+
from models.models.analysis_runner import AnalysisRunnerInternal
8+
9+
10+
@strawberry.type
11+
class AnalysisRunnerMutations:
12+
"""Analysis Runner mutations"""
13+
14+
@strawberry.mutation
15+
async def create_analysis_runner_log( # pylint: disable=too-many-arguments
16+
self,
17+
ar_guid: str,
18+
access_level: str,
19+
repository: str,
20+
commit: str,
21+
script: str,
22+
description: str,
23+
driver_image: str,
24+
config_path: str,
25+
environment: str,
26+
batch_url: str,
27+
submitting_user: str,
28+
meta: strawberry.scalars.JSON,
29+
output_path: str,
30+
hail_version: str | None,
31+
cwd: str | None,
32+
info: Info,
33+
) -> str:
34+
"""Create a new analysis runner log"""
35+
# TODO Reconfigure connection permissions as per `routes`
36+
connection = info.context['connection']
37+
alayer = AnalysisRunnerLayer(connection)
38+
39+
if not connection.project:
40+
raise ValueError('Project not set')
41+
42+
analysis_id = await alayer.insert_analysis_runner_entry(
43+
AnalysisRunnerInternal(
44+
ar_guid=ar_guid,
45+
timestamp=datetime.datetime.now(),
46+
access_level=access_level,
47+
repository=repository,
48+
commit=commit,
49+
script=script,
50+
description=description,
51+
driver_image=driver_image,
52+
config_path=config_path,
53+
cwd=cwd,
54+
environment=environment,
55+
hail_version=hail_version,
56+
batch_url=batch_url,
57+
submitting_user=submitting_user,
58+
meta=meta,
59+
project=connection.project,
60+
audit_log_id=None,
61+
output_path=output_path,
62+
)
63+
)
64+
65+
return analysis_id

api/graphql/mutations/assay.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import strawberry
2+
from strawberry.types import Info
3+
4+
from api.graphql.types import AssayUpsertInput, AssayUpsertType
5+
from db.python.layers.assay import AssayLayer
6+
from models.models.assay import AssayUpsertInternal
7+
8+
9+
@strawberry.type
10+
class AssayMutations:
11+
"""Assay mutations"""
12+
13+
@strawberry.mutation
14+
async def create_assay(
15+
self, assay: AssayUpsertInput, info: Info
16+
) -> AssayUpsertType:
17+
"""Create new assay, attached to a sample"""
18+
# TODO: Reconfigure connection permissions as per `routes`
19+
connection = info.context['connection']
20+
seq_table = AssayLayer(connection)
21+
return AssayUpsertType.from_upsert_internal(
22+
await seq_table.upsert_assay(
23+
AssayUpsertInternal.from_dict(strawberry.asdict(assay))
24+
)
25+
)
26+
27+
@strawberry.mutation
28+
async def update_assay(
29+
self,
30+
assay: AssayUpsertInput,
31+
info: Info,
32+
) -> int:
33+
"""Update assay for ID"""
34+
# TODO: Reconfigure connection permissions as per `routes`
35+
36+
if not assay.id:
37+
raise ValueError('Assay must have an ID to update')
38+
connection = info.context['connection']
39+
assay_layer = AssayLayer(connection)
40+
await assay_layer.upsert_assay(
41+
AssayUpsertInternal.from_dict(strawberry.asdict(assay))
42+
)
43+
44+
return assay.id

api/graphql/types/__init__.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import strawberry
44

5+
from models.enums.analysis import AnalysisStatus
56
from models.models.assay import AssayUpsert, AssayUpsertInternal
67
from models.models.cohort import NewCohortInternal
78
from models.models.participant import ParticipantUpsertInternal
@@ -24,8 +25,37 @@
2425
parse_value=lambda v: v,
2526
)
2627

28+
AnalysisStatusType = strawberry.enum(AnalysisStatus)
2729

28-
@strawberry.experimental.pydantic.input(model=AssayUpsert) # type: ignore [misc]
30+
31+
@strawberry.input
32+
class AnalysisInput:
33+
"""Analysis input"""
34+
35+
type: str
36+
status: AnalysisStatusType
37+
id: int | None
38+
output: str | None
39+
sequencing_group_ids: list[str] | None
40+
cohort_ids: list[str] | None
41+
author: str | None
42+
timestamp_completed: str | None
43+
project: int | None
44+
active: bool | None
45+
meta: strawberry.scalars.JSON
46+
47+
48+
@strawberry.input
49+
class AnalysisUpdateInput:
50+
"""Analysis update input"""
51+
52+
status: AnalysisStatusType
53+
output: str | None
54+
meta: strawberry.scalars.JSON | None
55+
active: bool | None
56+
57+
58+
@strawberry.input # type: ignore [misc]
2959
class AssayUpsertInput:
3060
"""Assay upsert input"""
3161

0 commit comments

Comments
 (0)