def get(self): """API endpoint to get details about the status of a transaction or a block. Return: A ``dict`` in the format ``{'status': <status>}``, where ``<status>`` is one of "valid", "invalid", "undecided", "backlog". """ parser = reqparse.RequestParser() parser.add_argument('transaction_id', type=str) parser.add_argument('block_id', type=str) args = parser.parse_args(strict=True) tx_id = args['transaction_id'] block_id = args['block_id'] # logical xor - exactly one query argument required if bool(tx_id) == bool(block_id): return make_error(400, 'Provide exactly one query parameter. Choices are: block_id, transaction_id') pool = current_app.config['bigchain_pool'] status = None with pool() as bigchain: if tx_id: status = bigchain.get_status(tx_id) elif block_id: _, status = bigchain.get_block(block_id=block_id, include_status=True) if not status: return make_error(404) return { 'status': status }
def post(self): """API endpoint to aggregate. Args: pipeline (str): Request of aggregate in body. Return: A list of aggregate the query. """ table = request.args.get('table') if not table: table = 'transactions' # return make_error(400, 'table cannot be empty') try: pipeline = request.get_json(force=True) except Exception as e: return make_error(400, 'Json required') pool = current_app.config['bigchain_pool'] with pool() as bigchain: def aggregate(obj, pipeline, table): return query.aggregate(obj.connection, pipeline, table) bigchain.aggregate = types.MethodType(aggregate, bigchain) data = bigchain.aggregate(pipeline, table) try: return json.loads(json_util.dumps(data)) except OperationError as e: return make_error(400, '({}): {}'.format(type(e).__name__, e))
def get(self): """API endpoint to perform a text search on the assets. Args: search (str): Text search json object to query the assets table limit (int, optional): Limit the number of returned documents. Return: A list of assets that match the query. """ parser = reqparse.RequestParser() parser.add_argument('search', type=str, required=True) parser.add_argument('limit', type=int) args = parser.parse_args() if not args['search']: return make_error(400, 'text_search cannot be empty') if not args['limit']: # if the limit is not specified do not pass None to `text_search_object` del args['limit'] args['search'] = json.loads(args['search']) pool = current_app.config['bigchain_pool'] with pool() as bigchain: assets = bigchain.text_search_object(**args) try: # This only works with MongoDB as the backend return list(assets) except OperationError as e: return make_error(400, '({}): {}'.format(type(e).__name__, e))
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about the transaction. """ pool = current_app.config['bigchain_pool'] # `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) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error(400, message='Invalid transaction schema: {}'.format( e.__cause__.message)) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e)) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e)) else: bigchain.write_transaction(tx_obj) return tx, 202
def get(self): """API endpoint to perform a text search on transaction metadata. Args: search (str): Text search string to query the text index limit (int, optional): Limit the number of returned documents. Return: A list of metadata that match the query. """ parser = reqparse.RequestParser() parser.add_argument('search', type=str, required=True) parser.add_argument('limit', type=int) args = parser.parse_args() if not args['search']: return make_error(400, 'text_search cannot be empty') if not args['limit']: del args['limit'] pool = current_app.config['bigchain_pool'] with pool() as bigchain: args['table'] = 'metadata' metadata = bigchain.text_search(**args) try: # This only works with MongoDB as the backend return list(metadata) except OperationError as e: return make_error( 400, '({}): {}'.format(type(e).__name__, e) )
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about 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 # set to `application/json` tx = request.get_json(force=True) try: tx_obj = Transaction.from_dict(tx) except (ValidationError, InvalidSignature): return make_error(400, 'Invalid transaction') with pool() as bigchain: if bigchain.is_valid_transaction(tx_obj): rate = bigchaindb.config['statsd']['rate'] with monitor.timer('write_transaction', rate=rate): bigchain.write_transaction(tx_obj) else: return make_error(400, 'Invalid transaction') return tx
def get(self): """API endpoint to perform a text search on transaction metadata. Args: search (str): Text search string to query the text index limit (int, optional): Limit the number of returned documents. Return: A list of metadata that match the query. """ parser = reqparse.RequestParser() parser.add_argument('search', type=str, required=True) parser.add_argument('limit', type=int) args = parser.parse_args() if not args['search']: return make_error(400, 'text_search cannot be empty') if not args['limit']: del args['limit'] pool = current_app.config['bigchain_pool'] with pool() as bigchain: args['table'] = 'metadata' metadata = bigchain.text_search(**args) try: # This only works with MongoDB as the backend return list(metadata) except OperationError as e: return make_error(400, '({}): {}'.format(type(e).__name__, e))
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about 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 # set to `application/json` tx = request.get_json(force=True) try: tx_obj = Transaction.from_dict(tx) except (InvalidHash, InvalidSignature): return make_error(400, 'Invalid transaction') with pool() as bigchain: if bigchain.is_valid_transaction(tx_obj): rate = bigchaindb.config['statsd']['rate'] with monitor.timer('write_transaction', rate=rate): bigchain.write_transaction(tx_obj) else: return make_error(400, 'Invalid transaction') return tx
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about the transaction. """ pool = current_app.config['bigchain_pool'] # `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) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error( 400, message='Invalid transaction schema: {}'.format( e.__cause__.message) ) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) with pool() as bigchain: bigchain.statsd.incr('web.tx.post') try: bigchain.validate_transaction(tx_obj) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) else: bigchain.write_transaction(tx_obj) response = jsonify(tx) response.status_code = 202 # NOTE: According to W3C, sending a relative URI is not allowed in the # Location Header: # - https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html # # Flask is autocorrecting relative URIs. With the following command, # we're able to prevent this. response.autocorrect_location_header = False status_monitor = '../statuses?transaction_id={}'.format(tx_obj.id) response.headers['Location'] = status_monitor return response
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about the transaction. """ pool = current_app.config['bigchain_pool'] # `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) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error( 400, message='Invalid transaction schema: {}'.format( e.__cause__.message) ) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) else: bigchain.write_transaction(tx_obj) response = jsonify(tx) response.status_code = 202 # NOTE: According to W3C, sending a relative URI is not allowed in the # Location Header: # - https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html # # Flask is autocorrecting relative URIs. With the following command, # we're able to prevent this. response.autocorrect_location_header = False status_monitor = '../statuses?transaction_id={}'.format(tx_obj.id) response.headers['Location'] = status_monitor return response
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about the transaction. """ parser = reqparse.RequestParser() parser.add_argument('mode', type=parameters.valid_mode, default='broadcast_tx_async') args = parser.parse_args() mode = str(args['mode']) pool = current_app.config['bigchain_pool'] # `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) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error( 400, message='Invalid transaction schema: {}'.format( e.__cause__.message) ) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) else: status_code, message = bigchain.write_transaction(tx_obj, mode) if status_code == 202: response = jsonify(tx) response.status_code = 202 return response else: return make_error(status_code, message)
def get(self): """API endpoint to get details about the status of a transaction or a block. Return: A ``dict`` in the format ``{'status': <status>}``, where ``<status>`` is one of "valid", "invalid", "undecided", "backlog". """ parser = reqparse.RequestParser() parser.add_argument('tx_id', type=str) parser.add_argument('block_id', type=str) args = parser.parse_args(strict=True) tx_id = args['tx_id'] block_id = args['block_id'] # logical xor - exactly one query argument required if bool(tx_id) == bool(block_id): return make_error(400, 'Provide exactly one query parameter. Choices are: block_id, tx_id') pool = current_app.config['bigchain_pool'] status, links = None, None with pool() as bigchain: if tx_id: status = bigchain.get_status(tx_id) links = { 'tx': '/transactions/{}'.format(tx_id) } elif block_id: _, status = bigchain.get_block(block_id=block_id, include_status=True) # TODO: enable once blocks endpoint is available # links = { # "block": "/blocks/{}".format(args['block_id']) # } if not status: return make_error(404) response = { 'status': status } if links: response.update({ '_links': links }) return response
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about 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 set to `application/json` tx = request.get_json(force=True) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error( 400, message='Invalid transaction schema: {}'.format( e.__cause__.message) ) except (ValidationError, InvalidSignature) as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except (ValueError, OperationError, TransactionDoesNotExist, TransactionOwnerError, DoubleSpend, InvalidHash, InvalidSignature, TransactionNotInValidBlock, AmountError) as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) else: rate = bigchaindb.config['statsd']['rate'] with monitor.timer('write_transaction', rate=rate): bigchain.write_transaction(tx_obj) return tx
def get(self): """API endpoint to get details about the status of a transaction or a block. Return: A ``dict`` in the format ``{'status': <status>}``, where ``<status>`` is one of "valid", "invalid", "undecided", "backlog". """ parser = reqparse.RequestParser() parser.add_argument('tx_id', type=str) parser.add_argument('block_id', type=str) args = parser.parse_args(strict=True) tx_id = args['tx_id'] block_id = args['block_id'] # logical xor - exactly one query argument required if bool(tx_id) == bool(block_id): return make_error( 400, 'Provide exactly one query parameter. Choices are: block_id, tx_id' ) pool = current_app.config['bigchain_pool'] status, links = None, None with pool() as bigchain: if tx_id: status = bigchain.get_status(tx_id) links = {'tx': '/transactions/{}'.format(tx_id)} elif block_id: _, status = bigchain.get_block(block_id=block_id, include_status=True) # TODO: enable once blocks endpoint is available # links = { # "block": "/blocks/{}".format(args['block_id']) # } if not status: return make_error(404) response = {'status': status} if links: response.update({'_links': links}) return response
def get(self): pool = current_app.config['bigchain_pool'] with pool() as bigchain: block = bigchain.get_latest_block() if not block: return make_error(404) return block
def get(self): logger.info("Retrieving latest block") pool = current_app.config['bigchain_pool'] with pool() as bigchain: block = bigchain.get_latest_block() if not block: return make_error(404) return block
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about 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 set to `application/json` tx = request.get_json(force=True) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error(400, message='Invalid transaction schema: {}'.format( e.__cause__.message)) except (ValidationError, InvalidSignature) as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e)) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except (ValueError, OperationError, TransactionDoesNotExist, TransactionOwnerError, DoubleSpend, InvalidHash, InvalidSignature, TransactionNotInValidBlock, AmountError) as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e)) else: rate = bigchaindb.config['statsd']['rate'] with monitor.timer('write_transaction', rate=rate): bigchain.write_transaction(tx_obj) return tx
def post(self): """API endpoint to push transactions to the Federation. Return: A ``dict`` containing the data about the transaction. """ pool = current_app.config['bigchain_pool'] # `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) try: tx_obj = Transaction.from_dict(tx) except SchemaValidationError as e: return make_error( 400, message='Invalid transaction schema: {}'.format( e.__cause__.message) ) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except ValidationError as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e) ) else: bigchain.write_transaction(tx_obj) return tx, 202
def get(self): """API endpoint to get details about the status of a transaction or a block. Return: A ``dict`` in the format ``{'status': <status>}``, where ``<status>`` is one of "valid", "invalid", "undecided", "backlog". """ parser = reqparse.RequestParser() parser.add_argument('transaction_id', type=str) parser.add_argument('block_id', type=str) args = parser.parse_args(strict=True) tx_id = args['transaction_id'] block_id = args['block_id'] # logical xor - exactly one query argument required if bool(tx_id) == bool(block_id): return make_error( 400, 'Provide exactly one query parameter. Choices are: block_id, transaction_id' ) pool = current_app.config['bigchain_pool'] status = None with pool() as bigchain: if tx_id: status = bigchain.get_status(tx_id) elif block_id: _, status = bigchain.get_block(block_id=block_id, include_status=True) if not status: return make_error(404) return {'status': status}
def get(self, tx_id): """API endpoint to get details about a transaction. 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'] with pool() as bigchain: tx = bigchain.get_transaction(tx_id) if not tx: return make_error(404) return tx.to_dict()
def post(self): pool = current_app.config['bigchain_pool'] tx = request.get_json(force=True) tx_obj = Transaction.from_dict(tx) with pool() as bigchain: try: bigchain.validate_transaction(tx_obj) except (ValueError, OperationError, TransactionDoesNotExist, TransactionOwnerError, FulfillmentNotInValidBlock, DoubleSpend, InvalidHash, InvalidSignature, AmountError) as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e)) else: bigchain.write_transaction(tx_obj) return tx, 202
def get(self, block_id): """API endpoint to get details about a block. Args: block_id (str): the id of the block. Return: A JSON string containing the data about the block. """ pool = current_app.config['bigchain_pool'] with pool() as bigchain: block = bigchain.get_block(block_id=block_id) if not block: return make_error(404) return block
def post(self): pool = current_app.config['bigchain_pool'] msg = request.get_json()['msg'] amount = request.get_json()['amount'] target = request.get_json()['target'] with pool() as bigchain: try: tx = bigchain.recharge(target, amount, msg) bigchain.validate_transaction(tx) except (ValueError, OperationError, TransactionDoesNotExist, TransactionOwnerError, FulfillmentNotInValidBlock, DoubleSpend, InvalidHash, InvalidSignature, AmountError) as e: return make_error( 400, 'Invalid transaction ({}): {}'.format(type(e).__name__, e)) else: bigchain.write_transaction(tx) return rapidjson.dumps(tx.to_dict()), 202
def get(self, tx_id): """API endpoint to get details about the status of a transaction. Args: tx_id (str): the id of the transaction. Return: A ``dict`` in the format ``{'status': <status>}``, where ``<status>`` is one of "valid", "invalid", "undecided", "backlog". """ pool = current_app.config['bigchain_pool'] with pool() as bigchain: status = bigchain.get_status(tx_id) if not status: return make_error(404) return {'status': status}