Search code examples
pythoneve

Python Eve: 412 Precondition Failed on PATCH


I have a Python Eve application with the following relevant code:

def handle_user_update(request, lookup):
if request and request.data:
    data = json.loads(request.data)
    users = app.data.driver.db['users']
    user = users.find_one(ObjectId(lookup['_id']))
    if user and user['activation_code'] == data['activation_code']:
        app.data.update('users', ObjectId(lookup['_id']), {'active':True})
    else:
        abort(403)

app = Eve()

if __name__ == '__main__':
    app.on_pre_PATCH_users += handle_user_update
    app.run(host='0.0.0.0')

Field is defined:

'active': {
    'type': 'boolean',
    'readonly': True,
    'default': False
},
'activation_code': {
    'type': 'string',
    'readonly': True
}

I am sending a PATCH request:

If-Match:       c8f9351a7527f8aa1db191fe85017df1dbca961f
{"activation_code": "8f775627d1144dbd8367778e8680ed58"}

I got the If-Match from the ETag of a GET request sent immediately prior to this PATCH. The app.data.update method executes and the data is updated as expected, however I get response 412 PRECONDITION FAILED. Why? What should I do in order to get 200 OK?


Solution

  • The reason your users document is being updated is that you are hooking your callback function to a Pre-Request Event. Those are raised every time a request is received and before it is processed. In your case you probably want to hook your callback to a Database Event. Database events are only raised if a request has been validated and accepted, immediately before a document is sent to the database. In your case I would hook my function to on_update which is fired on validated PATCH request. Doing that would prevent your code from acting on the database if the original request is going be rejected, something you probably don't want to happen.

    On the reason why 412 PRECONDITION FAILED is raised well... on PATCH requests that's only returned if ETag don't match so make sure you are providing the right one. Also on which Eve version are you?

    UPDATE On v0.4, if you users is also the target of request, then the ETag changes as soon as you perform your custom write (document representation changes) so that would explain while you get a 412 later on.