Skip to content

Commit

Permalink
Merge pull request #272 from UW-GAC/deploy/stage
Browse files Browse the repository at this point in the history
Deploy to prod
  • Loading branch information
amstilp authored Jul 10, 2023
2 parents e18d46a + d2483a7 commit b2a03e5
Show file tree
Hide file tree
Showing 25 changed files with 1,066 additions and 15 deletions.
2 changes: 2 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@
"gregor_django.gregor_anvil.adapters.UploadWorkspaceAdapter",
"gregor_django.gregor_anvil.adapters.CombinedConsortiumDataWorkspaceAdapter",
"gregor_django.gregor_anvil.adapters.ReleaseWorkspaceAdapter",
"gregor_django.gregor_anvil.adapters.DCCProcessingWorkspaceAdapter",
"gregor_django.gregor_anvil.adapters.DCCProcessedDataWorkspaceAdapter",
]
ANVIL_ACCOUNT_ADAPTER = "gregor_django.gregor_anvil.adapters.AccountAdapter"

Expand Down
26 changes: 26 additions & 0 deletions gregor_django/gregor_anvil/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,29 @@ class ReleaseWorkspaceAdapter(BaseWorkspaceAdapter):
workspace_data_model = models.ReleaseWorkspace
workspace_data_form_class = forms.ReleaseWorkspaceForm
workspace_detail_template_name = "gregor_anvil/releaseworkspace_detail.html"


class DCCProcessingWorkspaceAdapter(BaseWorkspaceAdapter):
"""Adapter for DCCProcessingWorkspace."""

type = "dcc_processing"
name = "DCC processing workspace"
description = "Workspaces used for DCC processing of data."
list_table_class = tables.DCCProcessingWorkspaceTable
workspace_data_model = models.DCCProcessingWorkspace
workspace_data_form_class = forms.DCCProcessingWorkspaceForm
workspace_detail_template_name = "gregor_anvil/dccprocessingworkspace_detail.html"


class DCCProcessedDataWorkspaceAdapter(BaseWorkspaceAdapter):
"""Adapter for DCCProcessedDataWorkspace."""

type = "dcc_processed_data"
name = "DCC processed data workspace"
description = "Workspaces containing data processed by the DCC and hosted by AnVIL."
list_table_class = tables.DCCProcessedDataWorkspaceTable
workspace_data_model = models.DCCProcessedDataWorkspace
workspace_data_form_class = forms.DCCProcessedDataWorkspaceForm
workspace_detail_template_name = (
"gregor_anvil/dccprocesseddataworkspace_detail.html"
)
86 changes: 77 additions & 9 deletions gregor_django/gregor_anvil/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ class PartnerGroupAdmin(SimpleHistoryAdmin):
)


@admin.register(models.UploadCycle)
class UploadCycleAdmin(SimpleHistoryAdmin):
"""Admin class for the UploadCycle model."""

list_display = (
"cycle",
"start_date",
"end_date",
)
sortable_by = (
"cycle",
"start_date",
"end_date",
)


@admin.register(models.UploadWorkspace)
class UploadWorkspaceAdmin(SimpleHistoryAdmin):
"""Admin class for the UploadWorkspace model."""
Expand All @@ -73,6 +89,7 @@ class UploadWorkspaceAdmin(SimpleHistoryAdmin):
list_filter = (
"research_center",
"consent_group",
"upload_cycle",
)
sortable_by = (
"id",
Expand All @@ -81,17 +98,68 @@ class UploadWorkspaceAdmin(SimpleHistoryAdmin):
)


@admin.register(models.UploadCycle)
class UploadCycleAdmin(SimpleHistoryAdmin):
"""Admin class for the UploadCycle model."""
@admin.register(models.ExampleWorkspace)
class ExampleWorkspaceAdmin(SimpleHistoryAdmin):
"""Admin class for the ExampleWorkspace model."""

list_display = (
"cycle",
"start_date",
"end_date",
"id",
"workspace",
)
sortable_by = (
"cycle",
"start_date",
"end_date",
"id",
"workspace",
)


@admin.register(models.TemplateWorkspace)
class TemplateWorkspaceAdmin(SimpleHistoryAdmin):
"""Admin class for the TemplateWorkspace model."""

list_display = (
"id",
"workspace",
)
sortable_by = (
"id",
"workspace",
)


@admin.register(models.CombinedConsortiumDataWorkspace)
class CombinedConsortiumDataWorkspaceAdmin(SimpleHistoryAdmin):
"""Admin class for the CombinedConsortiumDataWorkspace model."""

list_display = (
"id",
"workspace",
"upload_cycle",
)
list_filter = ("upload_cycle",)
sortable_by = (
"id",
"workspace",
"upload_cycle",
)


@admin.register(models.ReleaseWorkspace)
class ReleaseWorkspaceAdmin(SimpleHistoryAdmin):
"""Admin class for the ReleaseWorkspace model."""

list_display = (
"id",
"workspace",
"upload_cycle",
"consent_group",
)
list_filter = (
"upload_cycle",
"consent_group",
)
sortable_by = (
"id",
"workspace",
"upload_cycle",
"consent_group",
)
30 changes: 30 additions & 0 deletions gregor_django/gregor_anvil/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,33 @@ def clean(self):
# that all upload_workspaces have the same upload_cycle.
if upload_cycle != upload_workspaces[0].upload_cycle:
raise ValidationError(self.ERROR_UPLOAD_CYCLE)

return cleaned_data


class DCCProcessingWorkspaceForm(Bootstrap5MediaFormMixin, forms.ModelForm):
"""Form for a DCCProcessingWorkspace object."""

ERROR_UPLOAD_CYCLE = (
"upload_cycle must match upload_cycle of all upload_workspaces."
)

class Meta:
model = models.DCCProcessingWorkspace
fields = (
"upload_cycle",
"purpose",
"workspace",
)


class DCCProcessedDataWorkspaceForm(Bootstrap5MediaFormMixin, forms.ModelForm):
"""Form for a DCCProcessedDataWorkspace object."""

class Meta:
model = models.DCCProcessedDataWorkspace
fields = (
"upload_cycle",
"consent_group",
"workspace",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.2.19 on 2023-06-20 23:37

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('gregor_anvil', '0013_remove_version_fields'),
]

operations = [
migrations.AlterModelOptions(
name='uploadcycle',
options={'ordering': ['cycle']},
),
]
95 changes: 95 additions & 0 deletions gregor_django/gregor_anvil/migrations/0015_dccworkspaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Generated by Django 3.2.19 on 2023-07-10 22:20

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_extensions.db.fields
import simple_history.models


class Migration(migrations.Migration):

dependencies = [
('anvil_consortium_manager', '0012_managedgroup_email_unique'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gregor_anvil', '0014_alter_uploadcycle_options'),
]

operations = [
migrations.CreateModel(
name='HistoricalDCCProcessingWorkspace',
fields=[
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('purpose', models.TextField(help_text='The type of processing that is done in this workspace.')),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('upload_cycle', models.ForeignKey(blank=True, db_constraint=False, help_text='Upload cycle associated with this workspace.', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gregor_anvil.uploadcycle')),
('workspace', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='anvil_consortium_manager.workspace')),
],
options={
'verbose_name': 'historical dcc processing workspace',
'verbose_name_plural': 'historical dcc processing workspaces',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalDCCProcessedDataWorkspace',
fields=[
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('consent_group', models.ForeignKey(blank=True, db_constraint=False, help_text='Consent group associated with this data.', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gregor_anvil.consentgroup')),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('upload_cycle', models.ForeignKey(blank=True, db_constraint=False, help_text='Upload cycle associated with this workspace.', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gregor_anvil.uploadcycle')),
('workspace', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='anvil_consortium_manager.workspace')),
],
options={
'verbose_name': 'historical dcc processed data workspace',
'verbose_name_plural': 'historical dcc processed data workspaces',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='DCCProcessingWorkspace',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('purpose', models.TextField(help_text='The type of processing that is done in this workspace.')),
('upload_cycle', models.ForeignKey(help_text='Upload cycle associated with this workspace.', on_delete=django.db.models.deletion.PROTECT, to='gregor_anvil.uploadcycle')),
('workspace', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='anvil_consortium_manager.workspace')),
],
options={
'get_latest_by': 'modified',
'abstract': False,
},
),
migrations.CreateModel(
name='DCCProcessedDataWorkspace',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('consent_group', models.ForeignKey(help_text='Consent group associated with this data.', on_delete=django.db.models.deletion.PROTECT, to='gregor_anvil.consentgroup')),
('upload_cycle', models.ForeignKey(help_text='Upload cycle associated with this workspace.', on_delete=django.db.models.deletion.PROTECT, to='gregor_anvil.uploadcycle')),
('workspace', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='anvil_consortium_manager.workspace')),
],
),
migrations.AddConstraint(
model_name='dccprocesseddataworkspace',
constraint=models.UniqueConstraint(fields=('upload_cycle', 'consent_group'), name='unique_dcc_processed_data_workspace'),
),
]
41 changes: 41 additions & 0 deletions gregor_django/gregor_anvil/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ class UploadCycle(TimeStampedModel, models.Model):
# Django simple history.
history = HistoricalRecords()

class Meta:
ordering = [
"cycle",
]

def __str__(self):
return "U{cycle:02d}".format(cycle=self.cycle)

Expand Down Expand Up @@ -199,3 +204,39 @@ def get_dbgap_accession(self):
return "phs{phs:06d}.v{v}.p{p}".format(
phs=self.phs, v=self.dbgap_version, p=self.dbgap_participant_set
)


class DCCProcessingWorkspace(TimeStampedModel, BaseWorkspaceData):

upload_cycle = models.ForeignKey(
UploadCycle,
on_delete=models.PROTECT,
help_text="Upload cycle associated with this workspace.",
)
purpose = models.TextField(
help_text="The type of processing that is done in this workspace."
)


class DCCProcessedDataWorkspace(TimeStampedModel, BaseWorkspaceData):
"""A workspace to store DCC processed data, split by consent (e.g., re-aligned CRAMs and gVCFs)."""

upload_cycle = models.ForeignKey(
UploadCycle,
on_delete=models.PROTECT,
help_text="Upload cycle associated with this workspace.",
)
consent_group = models.ForeignKey(
ConsentGroup,
help_text="Consent group associated with this data.",
on_delete=models.PROTECT,
)

class Meta:
constraints = [
# Model uniqueness.
models.UniqueConstraint(
name="unique_dcc_processed_data_workspace",
fields=["upload_cycle", "consent_group"],
),
]
30 changes: 30 additions & 0 deletions gregor_django/gregor_anvil/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,33 @@ class Meta:

def render_number_workspaces(self, record):
return record.releaseworkspace.upload_workspaces.count()


class DCCProcessingWorkspaceTable(tables.Table):
"""A table for Workspaces that includes fields from DCCProcessingWorkspace."""

name = tables.columns.Column(linkify=True)

class Meta:
model = Workspace
fields = (
"name",
"dccprocessingworkspace__upload_cycle",
"dccprocessingworkspace__purpose",
)


class DCCProcessedDataWorkspaceTable(WorkspaceSharedWithConsortiumTable, tables.Table):
"""A table for Workspaces that includes fields from DCCProcessedDataWorkspace."""

name = tables.columns.Column(linkify=True)
dccprocesseddataworkspace__consent_group = tables.columns.Column(linkify=True)

class Meta:
model = Workspace
fields = (
"name",
"dccprocesseddataworkspace__upload_cycle",
"dccprocesseddataworkspace__consent_group",
"is_shared",
)
Loading

0 comments on commit b2a03e5

Please sign in to comment.