Python-Eve: Use Pre-Request Event Hooks to modify data before inserting to DB

Related searches

I am adding new data into my Database by doing a POST-request on my eve-API. Since there need to be added some data from the Python side I thought I could add these data by using a pre-request event hook.

So is there a way to modify the data contained in the POST-request using a pre-request hook before inserting the data into the database? I already understood how to implement such a hook but do not have any clue about how to modify data before inserting to DB.

You probably want to look at database hooks, specifically at insert hooks:

When a POST requests hits the API and new items are about to be stored in the database, these vents are fired:

on_insert for every resource endpoint.

on_insert_<resource_name> for the specific resource endpoint.

Callback functions could hook into these events to arbitrarily add new fields or edit existing ones.

In the code below:

def before_insert(resource_name, documents):
    if resource_name == 'myresource':
        for document in documents:
            document['field'] = 'value'

app = Eve()
app.on_insert += before_insert

app.run()

Every time a POST hits the API the before_insert function is invoked. The function updates field1 for every document. Since this callback is invoked before the payload is sent to the database, changes will be persisted to the database.

An interesting alternative would be:

def before_insert(resource_name, documents):
    for document in documents:
        document['field'] = 'value'

app = Eve()
app.on_insert_myresource += before_insert

app.run()

In the callback we are not testing the endpoint name anymore. This is because we hooked our callback to the on_insert_myresoure event so the function will only be called when POST request are performed on the myresource endpoint. Better separation of concerns, code is simpler and also, improved performance since the callback is not going to be hit an all API inserts. Side note, eventually you can hook multiple callbacks to the same event (hence the use of the addition operator +=).

Features — Eve 1.1.2 documentation, Python-Eve: Use Pre-Request Event Hooks to modify data before inserting to DB - python. Using Eve Event Hooks from your Blueprint¶ by Pau Freixes. The use of Flask Blueprints helps us to extend our Eve applications with new endpoints that do not fit as a typical Eve resource. Pulling these endpoints out of the Eve scope allows us to write specific code in order to handle specific situations.

In my case I wanted to duplicate documents if a given property is in data.

I have to use pre_POST event hook to do that.

def pre_notifications(request):
    data = json.loads(request.get_data())
    if 'payload' in data and 'condition' in data:
        notification = data['payload']
        documents = []
        users = app.data.pymongo().db.users.find()
        for user in users:
            copy_notification = copy(notification)
            copy_notification['user_email'] = user['user_email']
            documents.append(copy_notification)
        request._cached_data = json.dumps(documents).encode('utf-8')

First, I tried to replace request.data but it does not work. Doing some search on code I figured out the _cached_data property. Then it works.

A good example of using event hooks to modify Eve data. Taken , PATCH header. The API would then perform a PATCH , overriding the original request method. Database event hooks work like request event hooks. [change] For better consistency with new pre_<method> hooks, on_<method> event hooks have been renamed to on_post_<method>. [change] Custom authentication classes can now be set at endpoint level. When set, an endpoint-level auth class will override the eventual global level auth class.

Just to complement the answer of @Gustavo (I cannot leave a comment in his answer). You can update the request._cached_json property without serializing your data.

Using his example:

def pre_notifications(request):
    data = json.loads(request.get_data())
    if 'payload' in data and 'condition' in data:
        notification = data['payload']
        documents = []
        users = app.data.pymongo().db.users.find()
        for user in users:
            copy_notification = copy(notification)
            copy_notification['user_email'] = user['user_email']
            documents.append(copy_notification)
        request._cached_json = documents

Can EVE do more than CRUD? � Issue #472 � pyeve/eve � GitHub, A good example of using event hooks to modify Eve data. Taken from: https:// github.com/nicolaiarocci/eve/issues/270 import requests. Event Hooks (NEW) Python Eve supports pre-request, post-request and database event hooks. When a particular request is received, an event is raised. You can subscribe to these events with multiple callback functions. Database event hooks work like request event hooks. These events are fired before and after a database action.

[PDF] Eve Documentation, What if I want to handle the insert/update part myself? I like to modify the actual DB call to be able to filter and reorder the returned documents on the backend side. For instance, I'm using Eve's on_insert event hook to detect they are designed to let you manipulate the request data before it's inserted. Configuration¶. Generally Eve configuration is best done with configuration files. The configuration files themselves are actual Python files. However, Eve will give precedence to dictionary-based settings first, then it will try to locate a file passed in EVE_SETTINGS environmental variable (if set) and finally it will try to locate settings.py or a file with filename passed to settings flag

Eve is an open source Python REST API framework designed for human beings. Inbound documents (for inserts and edits) are in JSON format. Database event hooks work like request event hooks. When a DELETE request hits an item endpoint and before the item is deleted, these events are fired:. Soft delete is enforced in the data layer, meaning queries made by application code using the app.data.find_one and app.data.find methods will automatically filter out soft deleted items. Passing a request object with req.show_deleted == True or a lookup dictionary that explicitly filters on the _deleted field will override the default filtering.

Invoked just after receiving the MessageEvent from the WebSocket server and before calling the WebSocket's onmessage Event Handler. This method must return event whose properties can be modified as well. You might be interested in modiying, event.data or event.origin usually. The wsObject refers to the corresponding WebSocket object used. You

Comments
  • It looks like this hook is invoked after the validation progress. So is there a way to combine this with the validation since required fields are still raising required_field errors?
  • If the fields are required and they are missing validation kicks in and document is rejected. The hook fire before insertion and after validation. Can't you simply make the fields not-required? Or, you could customise the validator to process the required rule differently or, better, add support for a different rule (look at "Custom Validation" in the docs).
  • DB hooks on_fetch_item does not work with WSGI. When I run the server with python server.py Hooks work but when run the app with WSGI hooks dont work and no errors show in console.