flask restful

trailing slashes
This commit is contained in:
diminator 2016-08-23 17:43:08 +02:00
parent d2399b5367
commit 8b55f24998
No known key found for this signature in database
GPG Key ID: C3D8590E6D0D439A
3 changed files with 88 additions and 53 deletions

View File

@ -3,15 +3,16 @@
For more information please refer to the documentation on ReadTheDocs:
- https://bigchaindb.readthedocs.io/en/latest/drivers-clients/http-client-server-api.html
"""
import flask
from flask import current_app, request, Blueprint
from flask_restful import Resource, Api
import bigchaindb
from bigchaindb import util
from bigchaindb.web.views.base import make_error
transaction_views = Blueprint('transaction_views', __name__)
transaction_api = Api(transaction_views)
# Unfortunately I cannot find a reference to this decorator.
@ -35,74 +36,83 @@ def record(state):
'performance.')
@transaction_views.route('/transactions/<tx_id>')
def get_transaction(tx_id):
"""API endpoint to get details about a transaction.
class TransactionApi(Resource):
def get(self, tx_id):
"""API endpoint to get details about a transaction.
Args:
tx_id (str): the id of the transaction.
Args:
tx_id (str): the id of the transaction.
Return:
A JSON string containing the data about the transaction.
"""
Return:
A JSON string containing the data about the transaction.
"""
pool = current_app.config['bigchain_pool']
pool = current_app.config['bigchain_pool']
with pool() as bigchain:
tx = bigchain.get_transaction(tx_id)
with pool() as bigchain:
tx = bigchain.get_transaction(tx_id)
if not tx:
return make_error(404)
if not tx:
return make_error(404)
return flask.jsonify(**tx)
return tx
@transaction_views.route('/transactions/', methods=['POST'])
def create_transaction():
"""API endpoint to push transactions to the Federation.
class TransactionStatusApi(Resource):
def get(self, tx_id):
"""API endpoint to get details about the status of a transaction.
Return:
A JSON string containing the data about the transaction.
"""
pool = current_app.config['bigchain_pool']
monitor = current_app.config['monitor']
Args:
tx_id (str): the id of the transaction.
# `force` will try to format the body of the POST request even if the `content-type` header is not
# set to `application/json`
tx = request.get_json(force=True)
Return:
A JSON string containing the status of the transaction.
Possible values: "valid", "invalid", "undecided", "backlog"
"""
with pool() as bigchain:
if tx['transaction']['operation'] == 'CREATE':
tx = util.transform_create(tx)
tx = bigchain.consensus.sign_transaction(tx, private_key=bigchain.me_private)
pool = current_app.config['bigchain_pool']
if not bigchain.is_valid_transaction(tx):
return make_error(400, 'Invalid transaction')
with pool() as bigchain:
status = bigchain.get_status(tx_id)
with monitor.timer('write_transaction', rate=bigchaindb.config['statsd']['rate']):
bigchain.write_transaction(tx)
if not status:
return make_error(404)
return flask.jsonify(**tx)
return {'status': status}
@transaction_views.route('/transactions/<tx_id>/status')
def get_transaction_status(tx_id):
"""API endpoint to get details about the status of a transaction.
class TransactionListApi(Resource):
def post(self):
"""API endpoint to push transactions to the Federation.
Args:
tx_id (str): the id of the transaction.
Return:
A JSON string containing the data about the transaction.
"""
pool = current_app.config['bigchain_pool']
monitor = current_app.config['monitor']
Return:
A JSON string containing the status of the transaction.
Possible values: "valid", "invalid", "undecided", "backlog", None
"""
# `force` will try to format the body of the POST request even if the `content-type` header is not
# set to `application/json`
tx = request.get_json(force=True)
pool = current_app.config['bigchain_pool']
with pool() as bigchain:
if tx['transaction']['operation'] == 'CREATE':
tx = util.transform_create(tx)
tx = bigchain.consensus.sign_transaction(tx, private_key=bigchain.me_private)
with pool() as bigchain:
status = bigchain.get_status(tx_id)
if not bigchain.is_valid_transaction(tx):
return make_error(400, 'Invalid transaction')
if not status:
return make_error(404)
with monitor.timer('write_transaction', rate=bigchaindb.config['statsd']['rate']):
bigchain.write_transaction(tx)
return flask.jsonify({'status': status})
return tx
transaction_api.add_resource(TransactionApi,
'/transactions/<string:tx_id>',
strict_slashes=False)
transaction_api.add_resource(TransactionStatusApi,
'/transactions/<string:tx_id>/status',
strict_slashes=False)
transaction_api.add_resource(TransactionListApi,
'/transactions',
strict_slashes=False)

View File

@ -102,6 +102,7 @@ setup(
'logstats==0.2.1',
'base58==0.2.2',
'flask==0.10.1',
'flask-restful==0.3.5',
'requests~=2.9',
'gunicorn~=19.0',
'multipipes~=0.1.0',

View File

@ -13,8 +13,12 @@ def test_get_transaction_endpoint(b, client, user_vk):
input_tx = b.get_owned_ids(user_vk).pop()
tx = b.get_transaction(input_tx['txid'])
res = client.get(TX_ENDPOINT + input_tx['txid'])
assert tx == res.json
assert res.status_code == 200
assert tx == res.json
res = client.get(TX_ENDPOINT + input_tx['txid'] + '/')
assert res.status_code == 200
assert tx == res.json
@pytest.mark.usefixtures('inputs')
@ -22,6 +26,9 @@ def test_get_transaction_returns_404_if_not_found(client):
res = client.get(TX_ENDPOINT + '123')
assert res.status_code == 404
res = client.get(TX_ENDPOINT + '123/')
assert res.status_code == 404
def test_api_endpoint_shows_basic_info(client):
from bigchaindb import version
@ -40,6 +47,16 @@ def test_post_create_transaction_endpoint(b, client):
assert res.json['transaction']['conditions'][0]['owners_after'][0] == vk
def test_post_create_transaction_endpoint_without_trailing_slash(b, client):
sk, vk = crypto.generate_key_pair()
tx = util.create_and_sign_tx(sk, vk, vk, None, 'CREATE')
res = client.post(TX_ENDPOINT[:-1], data=json.dumps(tx))
assert res.json['transaction']['fulfillments'][0]['owners_before'][0] == b.me
assert res.json['transaction']['conditions'][0]['owners_after'][0] == vk
@pytest.mark.usefixtures('inputs')
def test_post_transfer_transaction_endpoint(b, client, user_vk, user_sk):
sk, vk = crypto.generate_key_pair()
@ -71,9 +88,16 @@ def test_get_transaction_status_endpoint(b, client, user_vk):
assert status == res.json['status']
assert res.status_code == 200
res = client.get(TX_ENDPOINT + input_tx['txid'] + "/status/")
assert status == res.json['status']
assert res.status_code == 200
@pytest.mark.usefixtures('inputs')
def test_get_transaction_status_returns_404_if_not_found(client):
res = client.get(TX_ENDPOINT + '123' + "/status")
assert res.status_code == 404
res = client.get(TX_ENDPOINT + '123' + "/status/")
assert res.status_code == 404