pyeve / eve

REST API framework designed for human beings

Home Page:https://python-eve.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pass var to a pipeline aggregation via url and regex

zaterio opened this issue · comments

commented

Hi,
I need to perform data aggregation, but variables must be passed in the url and not via arguments ( ?aggregate={}).

I have the following hook enabled:

def on_aggregate(endpoint, pipeline):
    print(f'endpoint: {endpoint}')
    print(f'pipeline: {pipeline}')
  1. My standard config is:
media_por_user_id = {
    'url': 'views/userid/media',
    'datasource':{
        'source': 'media',
        'aggregation': {
            'pipeline':
                [
                    {
                        '$match': {
                            "user": "$user_id"
                        }
                    }, {
                        '$group': {
                            '_id': '$user',
                            'medias': {
                                '$push': {
                                    'media_filename': '$media_filename',
                                    'media_status': '$media_status'    
                                }
                            }
                        }
                    }
                ]
            }
    },
    'schema': schema_media,
}

Request: http://127.0.0.1/views/userid/media?aggregate={"$user_id":"639b51720ac10cbf4b0a3d43"}

Response:

{"_items": [{"_id": "639b51720ac10cbf4b0a3d43", "medias": [{"media_filename": "r", "media_status": "available"}, {"media_filename": "r1", "media_status": "available"}, {"media_filename": "r2", "media_status": "available"}]}], "_meta": {"page": 1, "max_results": 25, "total": 1}, "_links": {"parent": {"title": "home", "href": "/"}, "self": {"title": "views/userid/media", "href": "views/userid/media?aggregate={\"$user_id\":\"639b51720ac10cbf4b0a3d43\"}"}}}

Hook Output:

endpoint: media_por_user_id pipeline: [{'$match': {'user': '639b51720ac10cbf4b0a3d43'}}, {'$group': {'_id': '$user', 'medias': {'$push': {'media_filename': '$media_filename', 'media_status': '$media_status'}}}}]

Note how $user_id is captured correctly

2-. Trying to pass $user_id through the url:

media_por_user_id = {
    'url': 'views/<regex("[a-f0-9]{24}"):user_id>/media',
    'datasource':{
        'source': 'media',
        'aggregation': {
            'pipeline':
                [
                    {
                        '$match': {
                            "user": "$user_id"
                        }
                    }, {
                        '$group': {
                            '_id': '$user',
                            'medias': {
                                '$push': {
                                    'media_filename': '$media_filename',
                                    'media_status': '$media_status'    
                                }
                            }
                        }
                    }
                ]
            }
    },
    'schema': schema_media,
}

Request: http:/127.0.0.1/views/639b51720ac10cbf4b0a3d43/media

Response:

{"_items": [], "_meta": {"page": 1, "max_results": 25, "total": 0}, "_links": {"parent": {"title": "home", "href": "/"}, "self": {"title": "views/<regex(\"[a-f0-9]{24}\"):user_id>/media", "href": "views/639b51720ac10cbf4b0a3d43/media"}}}

Hook Output:

endpoint: media_por_user_id, pipeline: [{'$match': {'user': '$user_id'}}, {'$group': {'_id': '$user', 'medias': {'$push': {'media_filename': '$media_filename', 'media_status': '$media_status'}}}}]

in this case the value of $user_id is not captured.

I have tried many modifications, but without success. information available in this regard is scarce.
So I'm evaluating sending an empty pipeline to the aggregation hook. and handle it at that level, using the following approach:

from flask import request

def on_aggregate(endpoint, pipeline):
    print(f'endpoint: {endpoint}')
    print(f'pipeline: {pipeline}')
    url = request.url
    # extract $user_id from url
    # contruct pipeline
    return True

But before going to that stage I would like to have clarification if it is a configuration error or Eve does not support this feature.

Thanks

Hi, on top of my head I don't think this is supported out of the box. Your workaround sounds reasonable though.