[英]Flask-Restful Endpoint Throwing werkzeug.routing.BuildError
[英]Random 'werkzeug.routing.BuildError' when testing Flask-Restful application
因此,我遇到了flask-restful
和fields.Url
怪異錯誤fields.Url
我真的無法弄清楚為什么會出現錯誤,因為它是隨機發生的。 當正常運行我的應用程序時,它似乎沒有發生,它只是在測試中隨機失敗。
值得注意的是,它僅在POST請求中發生,並且可以與GET請求一起使用。
作為參考,所有代碼都位於https://github.com/Tehnix/cred-server (已應用臨時修復程序)。
似乎在封送我的數據對象時,URL字段的創建失敗。 完整的錯誤位於問題的結尾。
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/werkzeug/routing.py", line 1678, in build
raise BuildError(endpoint, values, method)
werkzeug.routing.BuildError: ('events_item', {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x102df6d68>}, None)
端點定義為
# FILE: cred/routes.py
api.add_resource(EventsItem, '/events/<int:event_id>', endpoint='events_item')
我正在使用以下命令來封送我的SQLAlchemy對象,
# FILE: cred/resources/events.py
simple_event_fields = {
'id': flask.ext.restful.fields.Integer(attribute='event_id'),
'uri': flask.ext.restful.fields.Url('events_item', absolute=True),
}
在fields.Url
似乎由於某種原因而失敗。 最后是處理POST請求的資源,
# FILE: cred/resources/events.py
class Events(flask.ext.restful.Resource):
"""Methods going to the /events route."""
def post(self):
"""Create a new event and return the id and uri of the event."""
# Parse the POST args using the parser from flask-restful into event_args
# ...
# Create the event in the database
event = EventModel(
self.client,
event_args['name'],
event_args['location'],
event_args['action'],
event_args['value']
)
# Save the event in the database
db.session.add(event)
db.session.commit()
# Finally, convert the event object into our format by marshalling it,
# and returning the JSON object
return {
'status': 201,
'message': 'Created Event',
'event': marshal(event, simple_event_fields)
}, 201
如開始時所說,它僅在運行測試時發生(並且有時僅在某些情況下發生),因此它本身並不重要 ,但是不必多次重新運行測試只是為了看看它是否消失並仍然會很不錯。所有其他人都通過了。
我正在使用Flask-Testing,但它實際上是許多單元測試,
# FILE: cred/test/test_events.py
test_event = {
'event': {
'name': 'Temperature',
'location': 'Living Room',
'action': 'Temperature Above Setting',
'value': '5'
}
}
class BaseTestCase(flask.ext.testing.TestCase):
SQLALCHEMY_DATABASE_URI = "sqlite://"
TESTING = True
def create_app(self):
return app
def setUp(self):
"""Create a SQLite database for quick testing."""
cred.database.init_db(cred.database.db)
self.session_key = None
def tearDown(self):
"""Close the database file and unlink it."""
cred.database.db.session.remove()
cred.database.db.drop_all()
@testutil.authenticate('write')
def test_posting_a_complete_event(self):
"""Create a valid new event."""
# Post the request to the test server
response = self.client.post(
'/events',
data=json.dumps(test_event),
content_type='application/json'
)
resp = json.loads(response.data.decode('utf-8'))
# Run self.assertEqual on all items in a dict
testutil.assertEqual(self, {
response.status_code: 201,
resp['status']: 201,
resp['message']: 'Created Event',
'id' in resp['event']: True,
'uri' in resp['event']: True
})
在上面,由於uri
項目, test_posting_a_complete_event
將隨機失敗。
======================================================================
ERROR: Create a valid new event.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/tehnix/Dropbox/github/Tehnix/cred/cred/test/util.py", line 34, in wrapped
fun(self, *args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/cred/test/test_events.py", line 37, in test_posting_a_complete_event
resp = json.loads(response.data.decode('utf-8'))
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/__init__.py", line 318, in loads
return _default_decoder.decode(s)
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/decoder.py", line 343, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/decoder.py", line 361, in raw_decode
raise ValueError(errmsg("Expecting value", s, err.value)) from None
nose.proxy.ValueError: Expecting value: line 1 column 1 (char 0)
-------------------- >> begin captured logging << --------------------
cred-server: ERROR: Exception on /events [POST]
Traceback (most recent call last):
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 265, in error_router
return original_handler(e)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 446, in wrapper
resp = resource(*args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 550, in dispatch_request
resp = meth(*args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/cred/resources/events.py", line 88, in post
'event': marshal(event, simple_event_fields)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 603, in marshal
return OrderedDict([(envelope, OrderedDict(items))]) if envelope else OrderedDict(items)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/collections/__init__.py", line 56, in __init__
self.__update(*args, **kwds)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/bin/../lib/python3.4/_collections_abc.py", line 602, in update
for key, value in other:
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 602, in <genexpr>
for k, v in fields.items())
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/fields.py", line 294, in output
o = urlparse(url_for(endpoint, _external=self.absolute, **data))
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/helpers.py", line 312, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1641, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/helpers.py", line 305, in url_for
force_external=external)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/werkzeug/routing.py", line 1678, in build
raise BuildError(endpoint, values, method)
werkzeug.routing.BuildError: ('events_item', {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x102df6d68>}, None)
返回之前,您需要在“ events_items
內部分配events_items
。
此鏈接如何為燒瓶靜態中的嵌套輸出字段添加字段url解釋了更多
但是,如果你使用的是藍圖,添加“在” .
fields.Url
例如'uri': fields.Url('.events_items')
編號https://github.com/flask-restful/flask-restful/issues/266#issuecomment-46678118
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.