def test_partial_update(self): """ Simiulate a partial update process. """ old_recipe = copy.copy(good_recipe) sc = SousChef(**sous_chef) db_session.add(sc) db_session.commit() old_recipe = recipe_schema.validate(old_recipe, sc.to_dict()) old_id = old_recipe['options']['set_content_items'][0]['id'] old_recipe['slug'] += "-{}".format(gen_short_uuid()) r = Recipe(sc, **old_recipe) db_session.add(r) db_session.commit() new_recipe = { 'owner_screen_name': 'johnoliver', 'last_job': { 'foo': 'bar' }, 'status': 'stable', "set_content_items": [{ 'id': 2, 'title': 'foobar' }] } new_recipe = recipe_schema.update(r, new_recipe, sc.to_dict()) assert (new_recipe['options']['owner_screen_name'] == 'johnoliver') assert (new_recipe['last_job']['foo'] == 'bar') assert (new_recipe['status'] == 'stable') assert (new_recipe['options']['set_content_items'][0]['id'] != old_id) db_session.delete(r) db_session.delete(sc) db_session.commit()
def test_partial_update(self): """ Simiulate a partial update process. """ old_recipe = copy.copy(good_recipe) sc = SousChef(**sous_chef) db_session.add(sc) db_session.commit() old_recipe = recipe_schema.validate(old_recipe, sc.to_dict()) old_id = old_recipe['options']['set_content_items'][0]['id'] old_recipe['slug'] += "-{}".format(gen_short_uuid()) r = Recipe(sc, **old_recipe) db_session.add(r) db_session.commit() new_recipe = { 'owner_screen_name': 'johnoliver', 'last_job': {'foo': 'bar'}, 'status': 'stable', "set_content_items": [{'id': 2, 'title': 'foobar'}] } new_recipe = recipe_schema.update( r, new_recipe, sc.to_dict()) assert(new_recipe['options']['owner_screen_name'] == 'johnoliver') assert(new_recipe['last_job']['foo'] == 'bar') assert(new_recipe['status'] == 'stable') assert(new_recipe['options']['set_content_items'][0]['id'] != old_id) db_session.delete(r) db_session.delete(sc) db_session.commit()
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) db.session.add(r) db.session.commit() return jsonify(r)
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError('Recipe with id/slug {} does not exist.' .format(recipe_id)) # keep track of current coptions hash. current_option_hash = copy.copy(r.options_hash) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) # if the new options hash is different than the old one, we should # override the last_job column to be null if current_option_hash != r.options_hash: r.last_job = {} db.session.add(r) # now install metrics + reports if new_recipe.get('status', 'uninitialized') and r.status == 'stable': for name, params in r.sous_chef.metrics.items(): m = Metric.query\ .filter_by(org_id=org.id, recipe_id=r.id, name=name, type=params['type'])\ .first() if not m: m = Metric( name=name, recipe_id=r.id, org_id=org.id, **params) else: for k, v in params.items(): setattr(m, k, v) db.session.add(m) db.session.commit() return jsonify(r)
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) # keep track of current coptions hash. current_option_hash = copy.copy(r.options_hash) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) # if the new options hash is different than the old one, we should # override the last_job column to be null if current_option_hash != r.options_hash: r.last_job = {} db.session.add(r) # now install metrics + reports if new_recipe.get('status', 'uninitialized') and r.status == 'stable': for name, params in r.sous_chef.metrics.items(): m = Metric.query\ .filter_by(org_id=org.id, recipe_id=r.id, name=name, type=params['type'])\ .first() if not m: m = Metric(name=name, recipe_id=r.id, org_id=org.id, **params) else: for k, v in params.items(): setattr(m, k, v) db.session.add(m) db.session.commit() return jsonify(r)
def update_recipe(user, org, recipe_id): r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise RequestError('Recipe with id/slug {} does not exist.' .format(recipe_id)) # keep track of current coptions hash. current_option_hash = copy.copy(r.options_hash) # fetch request date and update / validate. req_data = request_data() new_recipe = recipe_schema.update(r, req_data, r.sous_chef.to_dict()) # if the requesting user hasn't initializied this recipe, # do it for them: status = new_recipe.get('status', 'uninitialized') if r.status == 'uninitialized' and status == 'uninitialized': new_recipe['status'] = 'stable' # update pickled options new_opts = new_recipe.pop('options') r.set_options(new_opts) # update all other fields for col, val in new_recipe.items(): setattr(r, col, val) # if the new options hash is different than the old one, we should # override the last_job column to be null if current_option_hash != r.options_hash: r.last_job = {} db.session.add(r) db.session.commit() return jsonify(r)
def cook_a_recipe(user, org, recipe_id): """ Run recipes via the API. """ r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError( 'Recipe with id/slug {} does not exist.' .format(recipe_id)) if r.status == 'uninitialized': raise RequestError( 'Recipes must be initialized before cooking.') # determine passthrough from req method passthrough = False if request.method == 'POST': passthrough = True # setup kwargs for merlynne kw = dict( org=org.to_dict( incl_auths=True, auths_as_dict=True, settings_as_dict=True, incl_domains=True, incl_users=True), apikey=user.apikey, recipe=r.to_dict(), recipe_obj=r, passthrough=arg_bool('passthrough'), sous_chef_path=r.sous_chef.runs ) # check for runtme args for passthrough options. if kw['passthrough']: # parse runtime options from params + body. options = { k: v for k, v in dict(request.args.items()).items() if k not in ['apikey', 'org', 'localize', 'passthrough'] } # parse the runtime options. options.update(request_data()) # update the recipe if len(options.keys()): try: recipe = recipe_schema.update( r, options, r.sous_chef.to_dict()) except Exception as e: raise RequestError( 'Error trying to attempt to pass {} to recipe {} at runtime:\n{}' .format(options, recipes.slug, e.message)) kw['recipe']['options'].update(recipe.get('options', {})) # execute merlynne merlynne = Merlynne(**kw) resp = merlynne.cook_recipe() # queued job if not kw['passthrough']: # set its status as 'queued' r.status = 'queued' db.session.add(r) db.session.commit() # # return job status url ret = url_for_job_status(apikey=user.apikey, job_id=resp, queue='recipe') return jsonify(ret, status=202) # format non-iterables. if isinstance(resp, dict): resp = [resp] # stream results def generate(): for item in resp: yield obj_to_json(item) + "\n" return Response(stream_with_context(generate()))
def cook_a_recipe(user, org, recipe_id): """ Run recipes via the API. """ r = fetch_by_id_or_field(Recipe, 'slug', recipe_id, org_id=org.id) if not r: raise NotFoundError( 'Recipe with id/slug {} does not exist.'.format(recipe_id)) if r.status == 'uninitialized': raise RequestError('Recipes must be initialized before cooking.') # determine passthrough from req method passthrough = False if request.method == 'POST': passthrough = True # setup kwargs for merlynne kw = dict(org=org.to_dict(incl_auths=True, auths_as_dict=True, settings_as_dict=True, incl_domains=True, incl_users=True), apikey=user.apikey, recipe=r.to_dict(), recipe_obj=r, passthrough=arg_bool('passthrough'), sous_chef_path=r.sous_chef.runs) # check for runtme args for passthrough options. if kw['passthrough']: # parse runtime options from params + body. options = { k: v for k, v in dict(request.args.items()).items() if k not in ['apikey', 'org', 'localize', 'passthrough'] } # parse the runtime options. options.update(request_data()) # update the recipe if len(options.keys()): try: recipe = recipe_schema.update(r, options, r.sous_chef.to_dict()) except Exception as e: raise RequestError( 'Error trying to attempt to pass {} to recipe {} at runtime:\n{}' .format(options, recipes.slug, e.message)) kw['recipe']['options'].update(recipe.get('options', {})) # execute merlynne merlynne = Merlynne(**kw) resp = merlynne.cook_recipe() # queued job if not kw['passthrough']: # set its status as 'queued' r.status = 'queued' db.session.add(r) db.session.commit() # # return job status url ret = url_for_job_status(apikey=user.apikey, job_id=resp, queue='recipe') return jsonify(ret, status=202) # format non-iterables. if isinstance(resp, dict): resp = [resp] # stream results def generate(): for item in resp: yield obj_to_json(item) + "\n" return Response(stream_with_context(generate()))