Skip to content

Commit

Permalink
Merge pull request #331 from hms-dbmi-cellenics/apiv2-processingSettings
Browse files Browse the repository at this point in the history
[BIOMAGE-1804] Implement load & save processing settings for api v2
  • Loading branch information
StefanBabukov authored Apr 21, 2022
2 parents 3f0090c + 743aa0c commit c002b90
Show file tree
Hide file tree
Showing 13 changed files with 1,057 additions and 184 deletions.
352 changes: 173 additions & 179 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions src/api.v2/controllers/experimentController.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ const updateSamplePosition = async (req, res) => {
res.json(OK());
};

const getProcessingConfig = async (req, res) => {
const { params: { experimentId } } = req;
logger.log('Getting processing config for experiment ', experimentId);

const result = await new Experiment().getProcessingConfig(experimentId);
res.json(result);
};

const updateProcessingConfig = async (req, res) => {
const { params: { experimentId }, body } = req;
logger.log('Updating processing config for experiment ', experimentId);

await new Experiment().updateProcessingConfig(experimentId, body);
res.json(OK());
};

const getBackendStatus = async (req, res) => {
const { experimentId } = req.params;

Expand Down Expand Up @@ -114,7 +130,9 @@ module.exports = {
getAllExperiments,
getExperiment,
createExperiment,
updateProcessingConfig,
patchExperiment,
updateSamplePosition,
getProcessingConfig,
getBackendStatus,
};
19 changes: 19 additions & 0 deletions src/api.v2/model/Experiment.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,25 @@ class Experiment extends BasicModel {
}
}

async getProcessingConfig(experimentId) {
const result = await this.findOne({ id: experimentId });
if (_.isEmpty(result)) {
throw new NotFoundError('Experiment not found');
}

return result.processingConfig;
}

async updateProcessingConfig(experimentId, body) {
const { name: stepName, body: change } = body[0];
const updateString = JSON.stringify({ [stepName]: change });

await this.sql(tableNames.EXPERIMENT)
.update({
processing_config: this.sql.raw(`processing_config || '${updateString}'::jsonb`),
}).where('id', experimentId);
}

async addSample(experimentId, sampleId) {
await this.sql(tableNames.EXPERIMENT)
.update({
Expand Down
2 changes: 2 additions & 0 deletions src/api.v2/model/__mocks__/Experiment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const stub = {
getAllExperiments: jest.fn(),
getExperimentData: jest.fn(),
updateSamplePosition: jest.fn(),
updateProcessingConfig: jest.fn(),
getProcessingConfig: jest.fn(),
addSample: jest.fn(),
deleteSample: jest.fn(),
...BasicModel,
Expand Down
12 changes: 10 additions & 2 deletions src/api.v2/routes/experiment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const {
createExperiment, getExperiment, patchExperiment, getAllExperiments,
updateSamplePosition, getBackendStatus,
createExperiment, getExperiment, patchExperiment, updateSamplePosition,
getAllExperiments, getProcessingConfig, updateProcessingConfig, getBackendStatus,
} = require('../controllers/experimentController');

const { expressAuthenticationOnlyMiddleware, expressAuthorizationMiddleware } = require('../middlewares/authMiddlewares');
Expand All @@ -26,6 +26,14 @@ module.exports = {
expressAuthorizationMiddleware,
(req, res, next) => updateSamplePosition(req, res).catch(next),
],
'experiment#getProcessingConfig': [
expressAuthorizationMiddleware,
(req, res, next) => getProcessingConfig(req, res).catch(next),
],
'experiment#updateProcessingConfig': [
expressAuthorizationMiddleware,
(req, res, next) => updateProcessingConfig(req, res).catch(next),
],
'experiment#getBackendStatus': [
expressAuthorizationMiddleware,
(req, res, next) => getBackendStatus(req, res).catch(next),
Expand Down
68 changes: 68 additions & 0 deletions src/specs/api.v2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,71 @@ paths:
- env
- clusterEnv
description: Returns a status on the health of the API.
'/experiments/{experimentId}/processingConfig':
get:
summary: Get processing configuration for an experiment
description: Get processing configuration for an experiment
operationId: getProcessingConfig
x-eov-operation-id: experiment#getProcessingConfig
x-eov-operation-handler: routes/experiment
responses:
'200':
description: get processing configuration for an experiment
content:
application/json:
schema:
$ref: '#/components/schemas/ProcessingConfig'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
'401':
description: The request lacks authentication credentials.
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
'404':
description: Not found error.
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'

put:
summary: Update processing configuration for an experiment
description: Update processing configuration for an experiment
operationId: updateProcessingConfig
x-eov-operation-id: experiment#updateProcessingConfig
x-eov-operation-handler: routes/experiment
responses:
'200':
description: Processing configuration for an experiment
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPSuccess'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
'401':
description: The request lacks authentication credentials.
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
'404':
description: Not found error.
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'

'/experiments':
get:
summary: Get all experiments
Expand Down Expand Up @@ -417,6 +482,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'

components:
schemas:
CreateExperiment:
Expand All @@ -425,6 +491,8 @@ components:
$ref: './models/experiment-bodies/ExperimentInfo.v2.yaml'
PatchExperiment:
$ref: './models/experiment-bodies/PatchExperiment.v2.yaml'
ProcessingConfig:
$ref: './models/experiment-bodies/ProcessingConfig.v2.yaml'
GetAllExperiments:
$ref: './models/experiment-bodies/GetAllExperiments.v2.yaml'
CreateSample:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ required:
- numGenesVsNumUmis
- doubletScores
- dataIntegration
- configureEmbedding
- configureEmbedding
32 changes: 32 additions & 0 deletions tests/api.v2/controllers/experimentController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,38 @@ describe('experimentController', () => {
expect(experimentInstance.updateSamplePosition).not.toHaveBeenCalled();
});

it('getProcessingConfig works', async () => {
const mockReq = {
params: {
experimentId: mockExperiment.id,
},
};
experimentInstance.getProcessingConfig.mockImplementationOnce(() => Promise.resolve());

await experimentController.getProcessingConfig(mockReq, mockRes);
expect(experimentInstance.getProcessingConfig).toHaveBeenCalledWith(mockExperiment.id);
});

it('updateProcessingConfig works', async () => {
const mockReq = {
params: {
experimentId: mockExperiment.id,
},
body: [{
name: 'classifier',
body: {
someChangedField: 'a value',
},
}],
};
experimentInstance.updateProcessingConfig.mockImplementationOnce(() => Promise.resolve());

await experimentController.updateProcessingConfig(mockReq, mockRes);
expect(experimentInstance.updateProcessingConfig).toHaveBeenCalledWith(
mockExperiment.id, mockReq.body,
);
});

it('getBackendStatus works correctly', async () => {
getPipelineStatus
.mockImplementationOnce(() => Promise.resolve('gem2sStatus'))
Expand Down
Loading

0 comments on commit c002b90

Please sign in to comment.