-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of background processing via RQ. Closes #4.
- Loading branch information
Showing
15 changed files
with
241 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,13 +5,89 @@ | |
:license: Apache, see LICENSE for more details. | ||
.. moduleauthor:: Kevin Glisson <[email protected]> | ||
""" | ||
from marshmallow import fields, Schema, post_load | ||
|
||
from inflection import underscore, camelize | ||
from marshmallow import fields, Schema, post_load, pre_load, post_dump | ||
from marshmallow.exceptions import ValidationError | ||
|
||
from diffy.config import CONFIG | ||
from diffy.plugins.base import plugins | ||
|
||
|
||
class DiffySchema(Schema): | ||
""" | ||
Base schema from which all diffy schema's inherit | ||
""" | ||
__envelope__ = True | ||
|
||
def under(self, data, many=None): | ||
items = [] | ||
if many: | ||
for i in data: | ||
items.append( | ||
{underscore(key): value for key, value in i.items()} | ||
) | ||
return items | ||
return { | ||
underscore(key): value | ||
for key, value in data.items() | ||
} | ||
|
||
def camel(self, data, many=None): | ||
items = [] | ||
if many: | ||
for i in data: | ||
items.append( | ||
{camelize(key, uppercase_first_letter=False): value for key, value in i.items()} | ||
) | ||
return items | ||
return { | ||
camelize(key, uppercase_first_letter=False): value | ||
for key, value in data.items() | ||
} | ||
|
||
def wrap_with_envelope(self, data, many): | ||
if many: | ||
if 'total' in self.context.keys(): | ||
return dict(total=self.context['total'], items=data) | ||
return data | ||
|
||
|
||
class DiffyInputSchema(DiffySchema): | ||
@pre_load(pass_many=True) | ||
def preprocess(self, data, many): | ||
return self.under(data, many=many) | ||
|
||
|
||
class DiffyOutputSchema(DiffySchema): | ||
@pre_load(pass_many=True) | ||
def preprocess(self, data, many): | ||
if many: | ||
data = self.unwrap_envelope(data, many) | ||
return self.under(data, many=many) | ||
|
||
def unwrap_envelope(self, data, many): | ||
if many: | ||
if data['items']: | ||
self.context['total'] = data['total'] | ||
else: | ||
self.context['total'] = 0 | ||
data = {'items': []} | ||
|
||
return data['items'] | ||
|
||
return data | ||
|
||
@post_dump(pass_many=True) | ||
def post_process(self, data, many): | ||
if data: | ||
data = self.camel(data, many=many) | ||
if self.__envelope__: | ||
return self.wrap_with_envelope(data, many=many) | ||
else: | ||
return data | ||
|
||
|
||
def resolve_plugin_slug(slug): | ||
"""Attempts to resolve plugin to slug.""" | ||
plugin = plugins.get(slug) | ||
|
@@ -26,7 +102,7 @@ class PluginOptionSchema(Schema): | |
options = fields.Dict(missing={}) | ||
|
||
|
||
class PluginSchema(Schema): | ||
class PluginSchema(DiffyInputSchema): | ||
options = fields.Dict(missing={}) | ||
|
||
@post_load | ||
|
@@ -54,3 +130,5 @@ class PayloadPluginSchema(PluginSchema): | |
|
||
class AnalysisPluginSchema(PluginSchema): | ||
slug = fields.String(missing=CONFIG['DIFFY_ANALYSIS_PLUGIN'], default=CONFIG['DIFFY_ANALYSIS_PLUGIN'], required=True) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,17 +5,17 @@ | |
:license: Apache, see LICENSE for more details. | ||
.. moduleauthor:: Kevin Glisson <[email protected]> | ||
""" | ||
from flask import Blueprint, current_app | ||
from flask import Blueprint, current_app, request | ||
from flask_restful import reqparse, Api, Resource | ||
|
||
from diffy.core import analysis | ||
from diffy.plugins.base import plugins | ||
from diffy.exceptions import TargetNotFound | ||
|
||
from diffy_api.common.schema import validate_schema | ||
from diffy_api.core import async_analysis | ||
from diffy_api.common.util import validate_schema | ||
from diffy_api.schemas import ( | ||
analysis_input_schema, | ||
analysis_output_schema, | ||
task_output_schema, | ||
) | ||
|
||
mod = Blueprint('analysis', __name__) | ||
|
@@ -54,7 +54,7 @@ def get(self): | |
data = plugins.get(current_app.config['DIFFY_PERSISTENCE_PLUGIN']).get_all('analysis') | ||
return data, 200 | ||
|
||
@validate_schema(analysis_input_schema, None) | ||
@validate_schema(analysis_input_schema, task_output_schema) | ||
def post(self, data=None): | ||
""" | ||
.. http:post:: /analysis | ||
|
@@ -78,7 +78,7 @@ def post(self, data=None): | |
:statuscode 403: unauthenticated | ||
""" | ||
try: | ||
return analysis(**data) | ||
return async_analysis.queue(**request.json) | ||
except TargetNotFound as ex: | ||
return {'message': ex.message}, 404 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,16 +5,17 @@ | |
:license: Apache, see LICENSE for more details. | ||
.. moduleauthor:: Kevin Glisson <[email protected]> | ||
""" | ||
from flask import Blueprint, current_app | ||
from flask import Blueprint, current_app, request | ||
from flask_restful import Api, Resource | ||
|
||
from diffy.core import baseline | ||
from diffy.plugins.base import plugins | ||
from diffy.exceptions import TargetNotFound | ||
from diffy_api.common.schema import validate_schema | ||
from diffy_api.core import async_baseline | ||
from diffy_api.common.util import validate_schema | ||
from diffy_api.schemas import ( | ||
baseline_input_schema, | ||
baseline_output_schema, | ||
task_output_schema, | ||
) | ||
|
||
|
||
|
@@ -54,7 +55,7 @@ def get(self): | |
data = plugins.get(current_app.config['DIFFY_PERSISTENCE_PLUGIN']).get_all('baseline') | ||
return data, 200 | ||
|
||
@validate_schema(baseline_input_schema, None) | ||
@validate_schema(baseline_input_schema, task_output_schema) | ||
def post(self, data=None): | ||
""" | ||
.. http:post:: /baselines | ||
|
@@ -78,7 +79,7 @@ def post(self, data=None): | |
:statuscode 403: unauthenticated | ||
""" | ||
try: | ||
return baseline(**data) | ||
return async_baseline.queue(**request.json) | ||
except TargetNotFound as ex: | ||
return {'message': ex.message}, 404 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,12 @@ | ||
""" | ||
.. module: diffy.common.schema | ||
:platform: unix | ||
:copyright: (c) 2018 by Netflix Inc., see AUTHORS for more | ||
:license: Apache, see LICENSE for more details. | ||
.. moduleauthor:: Kevin Glisson <[email protected]> | ||
""" | ||
from functools import wraps | ||
from typing import List | ||
from flask import request, current_app | ||
|
||
from inflection import camelize, underscore | ||
from marshmallow import Schema, post_dump, pre_load | ||
from flask import request, current_app | ||
from functools import wraps | ||
from inflection import camelize | ||
|
||
from diffy_api.extensions import sentry | ||
|
||
|
||
class DiffySchema(Schema): | ||
""" | ||
Base schema from which all grouper schema's inherit | ||
""" | ||
__envelope__ = True | ||
|
||
def under(self, data, many=None): | ||
items = [] | ||
if many: | ||
for i in data: | ||
items.append( | ||
{underscore(key): value for key, value in i.items()} | ||
) | ||
return items | ||
return { | ||
underscore(key): value | ||
for key, value in data.items() | ||
} | ||
|
||
def camel(self, data, many=None): | ||
items = [] | ||
if many: | ||
for i in data: | ||
items.append( | ||
{camelize(key, uppercase_first_letter=False): value for key, value in i.items()} | ||
) | ||
return items | ||
return { | ||
camelize(key, uppercase_first_letter=False): value | ||
for key, value in data.items() | ||
} | ||
|
||
def wrap_with_envelope(self, data, many): | ||
if many: | ||
if 'total' in self.context.keys(): | ||
return dict(total=self.context['total'], items=data) | ||
return data | ||
|
||
|
||
class DiffyInputSchema(DiffySchema): | ||
@pre_load(pass_many=True) | ||
def preprocess(self, data, many): | ||
return self.under(data, many=many) | ||
|
||
|
||
class DiffyOutputSchema(DiffySchema): | ||
@pre_load(pass_many=True) | ||
def preprocess(self, data, many): | ||
if many: | ||
data = self.unwrap_envelope(data, many) | ||
return self.under(data, many=many) | ||
|
||
def unwrap_envelope(self, data, many): | ||
if many: | ||
if data['items']: | ||
self.context['total'] = data['total'] | ||
else: | ||
self.context['total'] = 0 | ||
data = {'items': []} | ||
|
||
return data['items'] | ||
|
||
return data | ||
|
||
@post_dump(pass_many=True) | ||
def post_process(self, data, many): | ||
if data: | ||
data = self.camel(data, many=many) | ||
if self.__envelope__: | ||
return self.wrap_with_envelope(data, many=many) | ||
else: | ||
return data | ||
|
||
|
||
def format_errors(messages: List[str]) -> dict: | ||
errors = {} | ||
for k, v in messages.items(): | ||
|
@@ -170,4 +86,4 @@ def decorated_function(*args, **kwargs): | |
return unwrap_pagination(resp, output_schema), 200 | ||
|
||
return decorated_function | ||
return decorator | ||
return decorator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from diffy.core import baseline, analysis | ||
from diffy_api.extensions import rq | ||
from diffy_api.schemas import baseline_input_schema, analysis_input_schema | ||
|
||
|
||
@rq.job() | ||
def async_baseline(kwargs): | ||
"""Wrapper job around our standard baseline task.""" | ||
# we can't pickle our objects for remote works so we pickle the raw request and then load it here. | ||
data = baseline_input_schema.load(kwargs) | ||
return baseline(**data) | ||
|
||
|
||
@rq.job() | ||
def async_analysis(kwargs): | ||
"""Wrapper job around our standard analysis task.""" | ||
# we can't pickle our objects for remote works so we pickle the raw request and then load it here. | ||
data = analysis_input_schema.load(kwargs) | ||
return analysis(**data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,6 @@ | |
""" | ||
from raven.contrib.flask import Sentry | ||
sentry = Sentry() | ||
|
||
from flask_rq2 import RQ | ||
rq = RQ() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.