Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BIOMAGE-1804] Implement load & save processing settings for api v2 #331

Merged
merged 23 commits into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -82,10 +82,28 @@ 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());
};

module.exports = {
getAllExperiments,
getExperiment,
createExperiment,
updateProcessingConfig,
patchExperiment,
updateSamplePosition,
getProcessingConfig,
};
18 changes: 18 additions & 0 deletions src/api.v2/model/Experiment.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,24 @@ class Experiment extends BasicModel {
}
}

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

return result[0].processingConfig;
StefanBabukov marked this conversation as resolved.
Show resolved Hide resolved
}

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

const processingConfig = await this.getProcessingConfig(experimentId);
processingConfig[stepName] = change;

await this.update(experimentId, { processing_config: processingConfig });
StefanBabukov marked this conversation as resolved.
Show resolved Hide resolved
}

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
11 changes: 10 additions & 1 deletion src/api.v2/routes/experiment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const {
createExperiment, getExperiment, patchExperiment, updateSamplePosition, getAllExperiments,
createExperiment, getExperiment, patchExperiment, updateSamplePosition,
getAllExperiments, getProcessingConfig, updateProcessingConfig,
} = require('../controllers/experimentController');

const { expressAuthenticationOnlyMiddleware, expressAuthorizationMiddleware } = require('../middlewares/authMiddlewares');
Expand All @@ -25,4 +26,12 @@ 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,
StefanBabukov marked this conversation as resolved.
Show resolved Hide resolved
(req, res, next) => updateProcessingConfig(req, res).catch(next),
],
};
66 changes: 66 additions & 0 deletions src/specs/api.v2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,69 @@ 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'
'404':
StefanBabukov marked this conversation as resolved.
Show resolved Hide resolved
description: Not found error.
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
'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'
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'
'404':
StefanBabukov marked this conversation as resolved.
Show resolved Hide resolved
description: Not found error.
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'
'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'
'/experiments':
get:
summary: Get all experiments
Expand Down Expand Up @@ -330,6 +393,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/HTTPError'

components:
schemas:
CreateExperiment:
Expand All @@ -338,6 +402,8 @@ components:
$ref: './models/experiment-bodies/ExperimentInfo.v2.yaml'
ExperimentPatch:
$ref: './models/experiment-bodies/ExperimentPatch.v2.yaml'
ProcessingConfig:
$ref: './models/experiment-bodies/ProcessingConfig.v2.yaml'
GetAllExperiments:
$ref: './models/experiment-bodies/GetAllExperiments.v2.yaml'
CreateSample:
Expand Down
48 changes: 24 additions & 24 deletions src/specs/models/api-body-schemas/ProcessingConfig.v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ title: Processing Config schema
description: Processing Config schema
type: object
properties:
cellSizeDistribution:
$ref: '../processing-config-bodies/ProcessingConfigCellSizeDistribution.v1.yaml'
mitochondrialContent:
$ref: '../processing-config-bodies/ProcessingConfigMitochondrialContent.v1.yaml'
readAlignment:
$ref: '../processing-config-bodies/ProcessingConfigReadAlignment.v1.yaml'
classifier:
$ref: '../processing-config-bodies/ProcessingConfigClassifier.v1.yaml'
numGenesVsNumUmis:
$ref: '../processing-config-bodies/ProcessingConfigNumGenesVsNumUMIs.v1.yaml'
doubletScores:
$ref: '../processing-config-bodies/ProcessingConfigDoubletScores.v1.yaml'
dataIntegration:
$ref: '../processing-config-bodies/ProcessingConfigDataIntegration.v1.yaml'
configureEmbedding:
$ref: '../processing-config-bodies/ProcessingConfigConfigureEmbedding.v1.yaml'
processingConfig:
type: object
properties:
cellSizeDistribution:
StefanBabukov marked this conversation as resolved.
Show resolved Hide resolved
$ref: '../processing-config-bodies/ProcessingConfigCellSizeDistribution.v1.yaml'
mitochondrialContent:
$ref: '../processing-config-bodies/ProcessingConfigMitochondrialContent.v1.yaml'
readAlignment:
$ref: '../processing-config-bodies/ProcessingConfigReadAlignment.v1.yaml'
classifier:
$ref: '../processing-config-bodies/ProcessingConfigClassifier.v1.yaml'
numGenesVsNumUmis:
$ref: '../processing-config-bodies/ProcessingConfigNumGenesVsNumUMIs.v1.yaml'
doubletScores:
$ref: '../processing-config-bodies/ProcessingConfigDoubletScores.v1.yaml'
dataIntegration:
$ref: '../processing-config-bodies/ProcessingConfigDataIntegration.v1.yaml'
configureEmbedding:
$ref: '../processing-config-bodies/ProcessingConfigConfigureEmbedding.v1.yaml'

required:
- cellSizeDistribution
- mitochondrialContent
- readAlignment
- classifier
- numGenesVsNumUmis
- doubletScores
- dataIntegration
- configureEmbedding
- processingConfig: [
'cellSizeDistribution', 'mitochondrialContent', 'readAlignment',
'classifier', 'numGenesVsNumUmis', 'doubletScores', 'dataIntegration', 'configureEmbedding']
additionalProperties: false
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 @@ -172,4 +172,36 @@ 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,
);
});
});
Loading