Пример #1
0
    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()
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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()))
Пример #8
0
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()))