Skip to content

Commit ea0a7ec

Browse files
authored
some improvements (#3445)
* some changes * rm circular import * AMPLICON * AMPLICON tests * reservation * fix errors * fix qiita_db tests * fix trace * addressing @charles-cowart comments
1 parent edd3eed commit ea0a7ec

File tree

16 files changed

+84
-53
lines changed

16 files changed

+84
-53
lines changed

qiita_db/analysis.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,22 @@ def create(cls, owner, name, description, from_default=False,
215215
job.submit()
216216
return instance
217217

218+
@classmethod
219+
def delete_analysis_artifacts(cls, _id):
220+
"""Deletes the artifacts linked to an artifact and then the analysis
221+
222+
Parameters
223+
----------
224+
_id : int
225+
The analysis id
226+
"""
227+
analysis = cls(_id)
228+
aids = [a.id for a in analysis.artifacts if not a.parents]
229+
aids.sort(reverse=True)
230+
for aid in aids:
231+
qdb.artifact.Artifact.delete(aid)
232+
cls.delete(analysis.id)
233+
218234
@classmethod
219235
def delete(cls, _id):
220236
"""Deletes an analysis

qiita_db/handlers/tests/test_processing_job.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,9 @@ def test_post_job_success(self):
233233
self.assertIsNotNone(cj)
234234
# additionally we can test that job.print_trace is correct
235235
self.assertEqual(job.trace, [
236-
f'{job.id} [Not Available]: Validate | '
236+
f'{job.id} [Not Available] (success): Validate | '
237237
'-p qiita -N 1 -n 1 --mem 90gb --time 150:00:00 --nice=10000',
238-
f' {cj.id} [{cj.external_id}] | '
238+
f' {cj.id} [{cj.external_id}] (success)| '
239239
'-p qiita -N 1 -n 1 --mem 16gb --time 10:00:00 --nice=10000'])
240240

241241
def test_post_job_success_with_archive(self):

qiita_db/metadata_template/prep_template.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def create(cls, md_template, study, data_type, investigation_type=None,
135135
# data_type being created - if possible
136136
if investigation_type is None:
137137
if data_type_str in TARGET_GENE_DATA_TYPES:
138-
investigation_type = 'Amplicon'
138+
investigation_type = 'AMPLICON'
139139
elif data_type_str == 'Metagenomic':
140140
investigation_type = 'WGS'
141141
elif data_type_str == 'Metatranscriptomic':
@@ -280,8 +280,22 @@ def delete(cls, id_):
280280
qdb.sql_connection.TRN.add(sql, args)
281281
archived_artifacts = set(
282282
qdb.sql_connection.TRN.execute_fetchflatten())
283+
ANALYSIS = qdb.analysis.Analysis
283284
if archived_artifacts:
284285
for aid in archived_artifacts:
286+
# before we can delete the archived artifact, we need
287+
# to delete the analyses where they were used.
288+
sql = """SELECT analysis_id
289+
FROM qiita.analysis
290+
WHERE analysis_id IN (
291+
SELECT DISTINCT analysis_id
292+
FROM qiita.analysis_sample
293+
WHERE artifact_id IN %s)"""
294+
qdb.sql_connection.TRN.add(sql, [tuple([aid])])
295+
analyses = set(
296+
qdb.sql_connection.TRN.execute_fetchflatten())
297+
for _id in analyses:
298+
ANALYSIS.delete_analysis_artifacts(_id)
285299
qdb.artifact.Artifact.delete(aid)
286300

287301
# Delete the prep template filepaths

qiita_db/metadata_template/test/test_prep_template.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ def _common_creation_checks(self, pt, fp_count, name):
911911
self.assertEqual(pt.data_type(), self.data_type)
912912
self.assertEqual(pt.data_type(ret_id=True), self.data_type_id)
913913
self.assertEqual(pt.artifact, None)
914-
self.assertEqual(pt.investigation_type, 'Amplicon')
914+
self.assertEqual(pt.investigation_type, 'AMPLICON')
915915
self.assertEqual(pt.study_id, self.test_study.id)
916916
self.assertEqual(pt.status, "sandbox")
917917
exp_sample_ids = {'%s.SKB8.640193' % self.test_study.id,
@@ -1076,7 +1076,7 @@ def test_create_warning(self):
10761076
self.assertEqual(pt.data_type(), self.data_type)
10771077
self.assertEqual(pt.data_type(ret_id=True), self.data_type_id)
10781078
self.assertEqual(pt.artifact, None)
1079-
self.assertEqual(pt.investigation_type, 'Amplicon')
1079+
self.assertEqual(pt.investigation_type, 'AMPLICON')
10801080
self.assertEqual(pt.study_id, self.test_study.id)
10811081
self.assertEqual(pt.status, 'sandbox')
10821082
exp_sample_ids = {'%s.SKB8.640193' % self.test_study.id,
@@ -1247,7 +1247,7 @@ def test_investigation_type_setter(self):
12471247
"""Able to update the investigation type"""
12481248
pt = qdb.metadata_template.prep_template.PrepTemplate.create(
12491249
self.metadata, self.test_study, self.data_type_id)
1250-
self.assertEqual(pt.investigation_type, 'Amplicon')
1250+
self.assertEqual(pt.investigation_type, 'AMPLICON')
12511251
pt.investigation_type = "Other"
12521252
self.assertEqual(pt.investigation_type, 'Other')
12531253
with self.assertRaises(qdb.exceptions.QiitaDBColumnError):

qiita_db/processing_job.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,23 +2053,25 @@ def complete_processing_job(self):
20532053
def trace(self):
20542054
""" Returns as a text array the full trace of the job, from itself
20552055
to validators and complete jobs"""
2056-
lines = [f'{self.id} [{self.external_id}]: '
2056+
lines = [f'{self.id} [{self.external_id}] ({self.status}): '
20572057
f'{self.command.name} | {self.resource_allocation_info}']
20582058
cjob = self.complete_processing_job
20592059
if cjob is not None:
2060-
lines.append(f' {cjob.id} [{cjob.external_id}] | '
2060+
lines.append(f' {cjob.id} [{cjob.external_id}] ({cjob.status})| '
20612061
f'{cjob.resource_allocation_info}')
20622062
vjob = self.release_validator_job
20632063
if vjob is not None:
20642064
lines.append(f' {vjob.id} [{vjob.external_id}] '
2065-
f'| {vjob.resource_allocation_info}')
2065+
f' ({vjob.status}) | '
2066+
f'{vjob.resource_allocation_info}')
20662067
for v in self.validator_jobs:
2067-
lines.append(f' {v.id} [{v.external_id}]: '
2068+
lines.append(f' {v.id} [{v.external_id}] ({v.status}): '
20682069
f'{v.command.name} | {v.resource_allocation_info}')
20692070
cjob = v.complete_processing_job
20702071
if cjob is not None:
20712072
lines.append(f' {cjob.id} [{cjob.external_id}] '
2072-
f'| {cjob.resource_allocation_info}')
2073+
f'({cjob.status}) | '
2074+
f'{cjob.resource_allocation_info}')
20732075
return lines
20742076

20752077

qiita_db/support_files/patches/93.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,10 @@ CREATE INDEX IF NOT EXISTS processing_job_command_parameters_payload ON qiita.pr
5555

5656
-- After the changes
5757
-- 18710.404 ms
58+
59+
--
60+
61+
-- Nov 5, 2024
62+
-- Addding contraints for the slurm_reservation column
63+
ALTER TABLE qiita.analysis DROP CONSTRAINT IF EXISTS analysis_slurm_reservation_valid_chars;
64+
ALTER TABLE qiita.analysis ADD CONSTRAINT analysis_slurm_reservation_valid_chars CHECK ( slurm_reservation ~ '^[a-zA-Z0-9_]*$' );

qiita_db/support_files/populate_test_db.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,7 @@ INSERT INTO qiita.study_users VALUES (1, 'shared@foo.bar');
13361336

13371337
INSERT INTO qiita.term VALUES (2052508974, 999999999, NULL, 'WGS', 'ENA:0000059', NULL, NULL, NULL, NULL, NULL, false);
13381338
INSERT INTO qiita.term VALUES (2052508975, 999999999, NULL, 'Metagenomics', 'ENA:0000060', NULL, NULL, NULL, NULL, NULL, false);
1339-
INSERT INTO qiita.term VALUES (2052508976, 999999999, NULL, 'Amplicon', 'ENA:0000061', NULL, NULL, NULL, NULL, NULL, false);
1339+
INSERT INTO qiita.term VALUES (2052508976, 999999999, NULL, 'AMPLICON', 'ENA:0000061', NULL, NULL, NULL, NULL, NULL, false);
13401340
INSERT INTO qiita.term VALUES (2052508984, 999999999, NULL, 'RNA-Seq', 'ENA:0000070', NULL, NULL, NULL, NULL, NULL, false);
13411341
INSERT INTO qiita.term VALUES (2052508987, 999999999, NULL, 'Other', 'ENA:0000069', NULL, NULL, NULL, NULL, NULL, false);
13421342

qiita_db/test/test_analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ def test_is_public_make_public(self):
688688
def test_slurm_reservation(self):
689689
analysis = qdb.analysis.Analysis(1)
690690
self.assertIsNone(analysis.slurm_reservation)
691-
text = 'this is a test!'
691+
text = 'thisisatest'
692692
analysis.slurm_reservation = text
693693
self.assertEqual(analysis._slurm_reservation(), [text])
694694
self.assertIsNone(analysis.slurm_reservation)

qiita_db/test/test_artifact.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from qiita_core.util import qiita_test_checker
2424
from qiita_core.testing import wait_for_processing_job
2525
import qiita_db as qdb
26-
from qiita_ware.private_plugin import _delete_analysis_artifacts
2726

2827

2928
class ArtifactTestsReadOnly(TestCase):
@@ -1559,9 +1558,9 @@ def test_archive(self):
15591558
qdb.sql_connection.perform_as_transaction(sql)
15601559
sql = "UPDATE qiita.artifact SET visibility_id = 1"
15611560
qdb.sql_connection.perform_as_transaction(sql)
1562-
_delete_analysis_artifacts(qdb.analysis.Analysis(1))
1563-
_delete_analysis_artifacts(qdb.analysis.Analysis(2))
1564-
_delete_analysis_artifacts(qdb.analysis.Analysis(3))
1561+
qdb.analysis.Analysis.delete_analysis_artifacts(1)
1562+
qdb.analysis.Analysis.delete_analysis_artifacts(2)
1563+
qdb.analysis.Analysis.delete_analysis_artifacts(3)
15651564
for aid in [3, 2, 1]:
15661565
A.delete(aid)
15671566

qiita_db/test/test_ontology.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def testShortNameProperty(self):
3535
def testTerms(self):
3636
obs = self.ontology.terms
3737
self.assertEqual(
38-
obs, ['WGS', 'Metagenomics', 'Amplicon', 'RNA-Seq', 'Other'])
38+
obs, ['WGS', 'Metagenomics', 'AMPLICON', 'RNA-Seq', 'Other'])
3939

4040
def test_user_defined_terms(self):
4141
obs = self.ontology.user_defined_terms

qiita_db/util.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,7 +2334,7 @@ def send_email(to, subject, body):
23342334
msg = MIMEMultipart()
23352335
msg['From'] = qiita_config.smtp_email
23362336
msg['To'] = to
2337-
msg['Subject'] = subject
2337+
msg['Subject'] = subject.strip()
23382338
msg.attach(MIMEText(body, 'plain'))
23392339

23402340
# connect to smtp server, using ssl if needed
@@ -2496,9 +2496,9 @@ def _resource_allocation_plot_helper(
24962496
ax.set_ylabel(curr)
24972497
ax.set_xlabel(col_name)
24982498

2499-
# 100 - number of maximum iterations, 3 - number of failures we tolerate
2499+
# 50 - number of maximum iterations, 3 - number of failures we tolerate
25002500
best_model, options = _resource_allocation_calculate(
2501-
df, x_data, y_data, models, curr, col_name, 100, 3)
2501+
df, x_data, y_data, models, curr, col_name, 50, 3)
25022502
k, a, b = options.x
25032503
x_plot = np.array(sorted(df[col_name].unique()))
25042504
y_plot = best_model(x_plot, k, a, b)
@@ -2593,6 +2593,8 @@ def _resource_allocation_calculate(
25932593
failures_df = _resource_allocation_failures(
25942594
df, k, a, b, model, col_name, type_)
25952595
y_plot = model(x, k, a, b)
2596+
if not any(y_plot):
2597+
continue
25962598
cmax = max(y_plot)
25972599
cmin = min(y_plot)
25982600
failures = failures_df.shape[0]
@@ -2834,13 +2836,17 @@ def merge_rows(rows):
28342836
wait_time = (
28352837
datetime.strptime(rows.iloc[0]['Start'], date_fmt)
28362838
- datetime.strptime(rows.iloc[0]['Submit'], date_fmt))
2837-
tmp = rows.iloc[1].copy()
2839+
if rows.shape[0] >= 2:
2840+
tmp = rows.iloc[1].copy()
2841+
else:
2842+
tmp = rows.iloc[0].copy()
28382843
tmp['WaitTime'] = wait_time
28392844
return tmp
28402845

28412846
slurm_data['external_id'] = slurm_data['JobID'].apply(
28422847
lambda x: int(x.split('.')[0]))
28432848
slurm_data['external_id'] = slurm_data['external_id'].ffill()
2849+
28442850
slurm_data = slurm_data.groupby(
28452851
'external_id').apply(merge_rows).reset_index(drop=True)
28462852

qiita_pet/handlers/analysis_handlers/tests/test_base_handlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def test_patch(self):
207207
self.assertEqual(analysis._slurm_reservation(), [''])
208208

209209
# now, let's change it to something different
210-
reservation = 'my-reservation'
210+
reservation = 'myreservation'
211211
arguments = {
212212
'op': 'replace', 'path': 'reservation', 'value': reservation}
213213
self.patch(f'/analysis/description/{analysis.id}/', data=arguments)

qiita_pet/handlers/api_proxy/tests/test_prep_template.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class TestPrepAPIReadOnly(TestCase):
3838
def test_get_ENA_ontology(self):
3939
obs = _get_ENA_ontology()
4040
exp = {
41-
'ENA': ['Amplicon', 'Metagenomics', 'RNA-Seq', 'WGS', 'Other'],
41+
'ENA': ['AMPLICON', 'Metagenomics', 'RNA-Seq', 'WGS', 'Other'],
4242
'User': []}
4343
self.assertEqual(obs, exp)
4444

@@ -53,7 +53,7 @@ def test_new_prep_template_get_req(self):
5353
'Multiomic', 'Proteomic', 'Transcriptomics',
5454
'Viromics'],
5555
'ontology': {
56-
'ENA': ['Amplicon', 'Metagenomics', 'RNA-Seq', 'WGS', 'Other'],
56+
'ENA': ['AMPLICON', 'Metagenomics', 'RNA-Seq', 'WGS', 'Other'],
5757
'User': []}}
5858

5959
self.assertEqual(obs, exp)
@@ -73,7 +73,7 @@ def test_prep_template_ajax_get_req(self):
7373
'num_columns': 22,
7474
'investigation_type': 'Metagenomics',
7575
'ontology': {
76-
'ENA': ['Amplicon', 'Metagenomics', 'RNA-Seq', 'WGS',
76+
'ENA': ['AMPLICON', 'Metagenomics', 'RNA-Seq', 'WGS',
7777
'Other'],
7878
'User': []},
7979
'artifact_attached': True,

qiita_pet/templates/resources.html

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ <h3>Please choose software, version, and command to view the data.</h3>
2121
<option value="">Select Software</option>
2222
</select>
2323
</div>
24-
24+
2525
<div class="form-group">
2626
<label for="version">Version:</label>
2727
<select id="version" name="version" class="form-control">
2828
<option value="">Select Version</option>
2929
</select>
3030
</div>
31-
31+
3232
<div class="form-group">
3333
<label for="command">Command:</label>
3434
<select id="command" name="command" class="form-control">
@@ -89,15 +89,15 @@ <h3>Generated on: {{time}} </h3>
8989
</tr>
9090
</table>
9191
</div>
92-
92+
9393
</div>
9494

9595
<script>
9696

9797
function toggleDataVisibility(showData) {
9898
const defaultMessage = document.getElementById('default-message');
9999
const dataContainer = document.getElementById('data-container');
100-
100+
101101
if (showData) {
102102
defaultMessage.style.display = 'none';
103103
dataContainer.style.display = 'block';
@@ -106,17 +106,15 @@ <h3>Generated on: {{time}} </h3>
106106
dataContainer.style.display = 'none';
107107
}
108108
}
109-
109+
110110
// Call this function on initial load
111111
{% if initial_load %}
112112
toggleDataVisibility(false);
113113
{% else %}
114114
toggleDataVisibility(true);
115115
{% end %}
116116

117-
const commandsConst = JSON.parse('{% raw commands %}');
118-
console.log(commandsConst);
119-
117+
const commandsConst = JSON.parse(`{% raw commands %}`);
120118
const softwareSelect = document.getElementById('software');
121119
const versionSelect = document.getElementById('version');
122120
const commandSelect = document.getElementById('command');
@@ -133,7 +131,7 @@ <h3>Generated on: {{time}} </h3>
133131
function populateVersions(software) {
134132
versionSelect.innerHTML = '<option value="">Select Version</option>';
135133
commandSelect.innerHTML = '<option value="">Select Command</option>';
136-
134+
137135
if (software && commandsConst[software]) {
138136
for (const version in commandsConst[software]) {
139137
const option = document.createElement('option');
@@ -147,7 +145,7 @@ <h3>Generated on: {{time}} </h3>
147145

148146
function populateCommands(software, version) {
149147
commandSelect.innerHTML = '<option value="">Select Command</option>';
150-
148+
151149
if (software && version && commandsConst[software][version]) {
152150
commandsConst[software][version].forEach(command => {
153151
const option = document.createElement('option');
@@ -167,7 +165,6 @@ <h3>Generated on: {{time}} </h3>
167165

168166
$.post(window.location.href, JSON.stringify(data), function(response, textStatus, jqXHR) {
169167
if (response.status === "success") {
170-
console.log(response.time)
171168
// Toggle visibility based on the response
172169
toggleDataVisibility(true);
173170

@@ -227,7 +224,7 @@ <h3>Generated on: {{time}} </h3>
227224
}
228225

229226
bootstrapAlert("Data updated successfully", "success", 2200);
230-
}
227+
}
231228
else if (response.status === "no_data") {
232229
toggleDataVisibility(false);
233230
$('#default-message').html('<h3>No data available for the selected options.</h3>');
@@ -238,7 +235,6 @@ <h3>Generated on: {{time}} </h3>
238235
}
239236
}, 'json')
240237
.fail(function(jqXHR, textStatus, errorThrown) {
241-
console.error('Error:', errorThrown);
242238
toggleDataVisibility(false);
243239
bootstrapAlert("An error occurred while processing your request", "danger", 2200);
244240
});
@@ -269,4 +265,4 @@ <h3>Generated on: {{time}} </h3>
269265
}
270266
});
271267
</script>
272-
{% end %}
268+
{% end %}

0 commit comments

Comments
 (0)