mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
flask restful
trailing slashes
This commit is contained in:
parent
d2399b5367
commit
8b55f24998
@ -3,15 +3,16 @@
|
|||||||
For more information please refer to the documentation on ReadTheDocs:
|
For more information please refer to the documentation on ReadTheDocs:
|
||||||
- https://bigchaindb.readthedocs.io/en/latest/drivers-clients/http-client-server-api.html
|
- https://bigchaindb.readthedocs.io/en/latest/drivers-clients/http-client-server-api.html
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import flask
|
|
||||||
from flask import current_app, request, Blueprint
|
from flask import current_app, request, Blueprint
|
||||||
|
from flask_restful import Resource, Api
|
||||||
|
|
||||||
import bigchaindb
|
import bigchaindb
|
||||||
from bigchaindb import util
|
from bigchaindb import util
|
||||||
from bigchaindb.web.views.base import make_error
|
from bigchaindb.web.views.base import make_error
|
||||||
|
|
||||||
|
|
||||||
transaction_views = Blueprint('transaction_views', __name__)
|
transaction_views = Blueprint('transaction_views', __name__)
|
||||||
|
transaction_api = Api(transaction_views)
|
||||||
|
|
||||||
|
|
||||||
# Unfortunately I cannot find a reference to this decorator.
|
# Unfortunately I cannot find a reference to this decorator.
|
||||||
@ -35,74 +36,83 @@ def record(state):
|
|||||||
'performance.')
|
'performance.')
|
||||||
|
|
||||||
|
|
||||||
@transaction_views.route('/transactions/<tx_id>')
|
class TransactionApi(Resource):
|
||||||
def get_transaction(tx_id):
|
def get(self, tx_id):
|
||||||
"""API endpoint to get details about a transaction.
|
"""API endpoint to get details about a transaction.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tx_id (str): the id of the transaction.
|
tx_id (str): the id of the transaction.
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
A JSON string containing the data about the transaction.
|
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:
|
if not tx:
|
||||||
tx = bigchain.get_transaction(tx_id)
|
return make_error(404)
|
||||||
|
|
||||||
if not tx:
|
return tx
|
||||||
return make_error(404)
|
|
||||||
|
|
||||||
return flask.jsonify(**tx)
|
|
||||||
|
|
||||||
|
|
||||||
@transaction_views.route('/transactions/', methods=['POST'])
|
class TransactionStatusApi(Resource):
|
||||||
def create_transaction():
|
def get(self, tx_id):
|
||||||
"""API endpoint to push transactions to the Federation.
|
"""API endpoint to get details about the status of a transaction.
|
||||||
|
|
||||||
Return:
|
Args:
|
||||||
A JSON string containing the data about the transaction.
|
tx_id (str): the id of the transaction.
|
||||||
"""
|
|
||||||
pool = current_app.config['bigchain_pool']
|
|
||||||
monitor = current_app.config['monitor']
|
|
||||||
|
|
||||||
# `force` will try to format the body of the POST request even if the `content-type` header is not
|
Return:
|
||||||
# set to `application/json`
|
A JSON string containing the status of the transaction.
|
||||||
tx = request.get_json(force=True)
|
Possible values: "valid", "invalid", "undecided", "backlog"
|
||||||
|
"""
|
||||||
|
|
||||||
with pool() as bigchain:
|
pool = current_app.config['bigchain_pool']
|
||||||
if tx['transaction']['operation'] == 'CREATE':
|
|
||||||
tx = util.transform_create(tx)
|
|
||||||
tx = bigchain.consensus.sign_transaction(tx, private_key=bigchain.me_private)
|
|
||||||
|
|
||||||
if not bigchain.is_valid_transaction(tx):
|
with pool() as bigchain:
|
||||||
return make_error(400, 'Invalid transaction')
|
status = bigchain.get_status(tx_id)
|
||||||
|
|
||||||
with monitor.timer('write_transaction', rate=bigchaindb.config['statsd']['rate']):
|
if not status:
|
||||||
bigchain.write_transaction(tx)
|
return make_error(404)
|
||||||
|
|
||||||
return flask.jsonify(**tx)
|
return {'status': status}
|
||||||
|
|
||||||
|
|
||||||
@transaction_views.route('/transactions/<tx_id>/status')
|
class TransactionListApi(Resource):
|
||||||
def get_transaction_status(tx_id):
|
def post(self):
|
||||||
"""API endpoint to get details about the status of a transaction.
|
"""API endpoint to push transactions to the Federation.
|
||||||
|
|
||||||
Args:
|
Return:
|
||||||
tx_id (str): the id of the transaction.
|
A JSON string containing the data about the transaction.
|
||||||
|
"""
|
||||||
|
pool = current_app.config['bigchain_pool']
|
||||||
|
monitor = current_app.config['monitor']
|
||||||
|
|
||||||
Return:
|
# `force` will try to format the body of the POST request even if the `content-type` header is not
|
||||||
A JSON string containing the status of the transaction.
|
# set to `application/json`
|
||||||
Possible values: "valid", "invalid", "undecided", "backlog", None
|
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:
|
if not bigchain.is_valid_transaction(tx):
|
||||||
status = bigchain.get_status(tx_id)
|
return make_error(400, 'Invalid transaction')
|
||||||
|
|
||||||
if not status:
|
with monitor.timer('write_transaction', rate=bigchaindb.config['statsd']['rate']):
|
||||||
return make_error(404)
|
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)
|
||||||
|
1
setup.py
1
setup.py
@ -102,6 +102,7 @@ setup(
|
|||||||
'logstats==0.2.1',
|
'logstats==0.2.1',
|
||||||
'base58==0.2.2',
|
'base58==0.2.2',
|
||||||
'flask==0.10.1',
|
'flask==0.10.1',
|
||||||
|
'flask-restful==0.3.5',
|
||||||
'requests~=2.9',
|
'requests~=2.9',
|
||||||
'gunicorn~=19.0',
|
'gunicorn~=19.0',
|
||||||
'multipipes~=0.1.0',
|
'multipipes~=0.1.0',
|
||||||
|
@ -13,8 +13,12 @@ def test_get_transaction_endpoint(b, client, user_vk):
|
|||||||
input_tx = b.get_owned_ids(user_vk).pop()
|
input_tx = b.get_owned_ids(user_vk).pop()
|
||||||
tx = b.get_transaction(input_tx['txid'])
|
tx = b.get_transaction(input_tx['txid'])
|
||||||
res = client.get(TX_ENDPOINT + input_tx['txid'])
|
res = client.get(TX_ENDPOINT + input_tx['txid'])
|
||||||
assert tx == res.json
|
|
||||||
assert res.status_code == 200
|
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')
|
@pytest.mark.usefixtures('inputs')
|
||||||
@ -22,6 +26,9 @@ def test_get_transaction_returns_404_if_not_found(client):
|
|||||||
res = client.get(TX_ENDPOINT + '123')
|
res = client.get(TX_ENDPOINT + '123')
|
||||||
assert res.status_code == 404
|
assert res.status_code == 404
|
||||||
|
|
||||||
|
res = client.get(TX_ENDPOINT + '123/')
|
||||||
|
assert res.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
def test_api_endpoint_shows_basic_info(client):
|
def test_api_endpoint_shows_basic_info(client):
|
||||||
from bigchaindb import version
|
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
|
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')
|
@pytest.mark.usefixtures('inputs')
|
||||||
def test_post_transfer_transaction_endpoint(b, client, user_vk, user_sk):
|
def test_post_transfer_transaction_endpoint(b, client, user_vk, user_sk):
|
||||||
sk, vk = crypto.generate_key_pair()
|
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 status == res.json['status']
|
||||||
assert res.status_code == 200
|
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')
|
@pytest.mark.usefixtures('inputs')
|
||||||
def test_get_transaction_status_returns_404_if_not_found(client):
|
def test_get_transaction_status_returns_404_if_not_found(client):
|
||||||
res = client.get(TX_ENDPOINT + '123' + "/status")
|
res = client.get(TX_ENDPOINT + '123' + "/status")
|
||||||
assert res.status_code == 404
|
assert res.status_code == 404
|
||||||
|
|
||||||
|
res = client.get(TX_ENDPOINT + '123' + "/status/")
|
||||||
|
assert res.status_code == 404
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user