From 80f3bb38098865804f97fe6301131a89c1fbc349 Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Fri, 6 Jan 2017 14:18:10 +0100 Subject: [PATCH 1/2] /api/v1/ informational endpoint --- bigchaindb/web/routes.py | 3 ++- bigchaindb/web/views/base.py | 12 ++++++++++-- bigchaindb/web/views/info.py | 21 ++++++++++++++++++++- tests/web/test_info.py | 20 ++++++++++++++++++++ 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/bigchaindb/web/routes.py b/bigchaindb/web/routes.py index d2b5649a..cf60fe35 100644 --- a/bigchaindb/web/routes.py +++ b/bigchaindb/web/routes.py @@ -17,6 +17,7 @@ def r(*args, **kwargs): ROUTES_API_V1 = [ + r('/', info.ApiV1Index), r('transactions/', tx.TransactionApi), r('transactions//status', tx.TransactionStatusApi), r('transactions', tx.TransactionListApi), @@ -25,6 +26,6 @@ ROUTES_API_V1 = [ API_SECTIONS = [ - (None, [r('/', info.IndexApi)]), + (None, [r('/', info.RootIndex)]), ('/api/v1/', ROUTES_API_V1), ] diff --git a/bigchaindb/web/views/base.py b/bigchaindb/web/views/base.py index 9282b5b9..f0e5dc69 100644 --- a/bigchaindb/web/views/base.py +++ b/bigchaindb/web/views/base.py @@ -1,8 +1,11 @@ -from flask import jsonify +""" +Common classes and methods for API handlers +""" + +from flask import jsonify, request def make_error(status_code, message=None): - if status_code == 404 and message is None: message = 'Not found' @@ -12,3 +15,8 @@ def make_error(status_code, message=None): }) response.status_code = status_code return response + + +def base_url(): + return '%s://%s/' % (request.environ['wsgi.url_scheme'], + request.environ['HTTP_HOST']) diff --git a/bigchaindb/web/views/info.py b/bigchaindb/web/views/info.py index 1a8f1715..4b0b3f0b 100644 --- a/bigchaindb/web/views/info.py +++ b/bigchaindb/web/views/info.py @@ -4,10 +4,11 @@ import flask from flask_restful import Resource import bigchaindb +from bigchaindb.web.views.base import base_url from bigchaindb import version -class IndexApi(Resource): +class RootIndex(Resource): def get(self): return flask.jsonify({ 'software': 'BigchainDB', @@ -15,3 +16,21 @@ class IndexApi(Resource): 'public_key': bigchaindb.config['keypair']['public'], 'keyring': bigchaindb.config['keyring'] }) + + +class ApiV1Index(Resource): + def get(self): + api_root = base_url() + 'api/v1/' + docs_url = ['https://docs.bigchaindb.com/projects/server/en/', + version.__short_version__, + '/drivers-clients/http-client-server-api.html', + ] + + return { + "_links": { + "docs": {"href": ''.join(docs_url)}, + "self": {"href": api_root}, + "statuses": {"href": api_root + "statuses/"}, + "transactions": {"href": api_root + "transactions/"}, + }, + } diff --git a/tests/web/test_info.py b/tests/web/test_info.py index 4956bd29..be753ed0 100644 --- a/tests/web/test_info.py +++ b/tests/web/test_info.py @@ -1,5 +1,25 @@ +from unittest import mock + + def test_api_root_url_shows_basic_info(client): from bigchaindb import version res = client.get('/') assert res.json['software'] == 'BigchainDB' assert res.json['version'] == version.__version__ + + +def test_api_v1_endpoint(client): + with mock.patch('bigchaindb.version.__short_version__', 'tst'): + res = client.get('/api/v1') + docs_url = ['https://docs.bigchaindb.com/projects/server/en/', + 'tst', + '/drivers-clients/http-client-server-api.html', + ] + assert res.json == { + '_links': { + 'docs': {'href': ''.join(docs_url)}, + 'self': {'href': 'http://localhost/api/v1/'}, + 'statuses': {'href': 'http://localhost/api/v1/statuses/'}, + 'transactions': {'href': 'http://localhost/api/v1/transactions/'} + } + } From 990d863dc7ca2d79ccce5092efa0fd127b98f876 Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Fri, 6 Jan 2017 14:45:38 +0100 Subject: [PATCH 2/2] tests for informational endpoints --- bigchaindb/web/views/info.py | 27 ++++++++++++++++++--------- tests/web/test_info.py | 30 ++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/bigchaindb/web/views/info.py b/bigchaindb/web/views/info.py index 4b0b3f0b..98e061b6 100644 --- a/bigchaindb/web/views/info.py +++ b/bigchaindb/web/views/info.py @@ -10,7 +10,16 @@ from bigchaindb import version class RootIndex(Resource): def get(self): + docs_url = [ + 'https://docs.bigchaindb.com/projects/server/en/', + version.__short_version__ + '/' + ] + api_v1_url = base_url() + 'api/v1/' return flask.jsonify({ + '_links': { + 'docs': ''.join(docs_url), + 'api_v1': api_v1_url, + }, 'software': 'BigchainDB', 'version': version.__version__, 'public_key': bigchaindb.config['keypair']['public'], @@ -21,16 +30,16 @@ class RootIndex(Resource): class ApiV1Index(Resource): def get(self): api_root = base_url() + 'api/v1/' - docs_url = ['https://docs.bigchaindb.com/projects/server/en/', - version.__short_version__, - '/drivers-clients/http-client-server-api.html', - ] - + docs_url = [ + 'https://docs.bigchaindb.com/projects/server/en/', + version.__short_version__, + '/drivers-clients/http-client-server-api.html', + ] return { "_links": { - "docs": {"href": ''.join(docs_url)}, - "self": {"href": api_root}, - "statuses": {"href": api_root + "statuses/"}, - "transactions": {"href": api_root + "transactions/"}, + "docs": ''.join(docs_url), + "self": api_root, + "statuses": api_root + "statuses/", + "transactions": api_root + "transactions/", }, } diff --git a/tests/web/test_info.py b/tests/web/test_info.py index be753ed0..93b39390 100644 --- a/tests/web/test_info.py +++ b/tests/web/test_info.py @@ -1,25 +1,35 @@ from unittest import mock -def test_api_root_url_shows_basic_info(client): - from bigchaindb import version +@mock.patch('bigchaindb.version.__short_version__', 'tst') +@mock.patch('bigchaindb.version.__version__', 'tsttst') +@mock.patch('bigchaindb.config', {'keyring': ['abc'], 'keypair': {'public': 'def'}}) +def test_api_root_endpoint(client): res = client.get('/') - assert res.json['software'] == 'BigchainDB' - assert res.json['version'] == version.__version__ + assert res.json == { + '_links': { + 'docs': 'https://docs.bigchaindb.com/projects/server/en/tst/', + 'api_v1': 'http://localhost/api/v1/', + }, + 'version': 'tsttst', + 'keyring': ['abc'], + 'public_key': 'def', + 'software': 'BigchainDB', + } +@mock.patch('bigchaindb.version.__short_version__', 'tst') def test_api_v1_endpoint(client): - with mock.patch('bigchaindb.version.__short_version__', 'tst'): - res = client.get('/api/v1') + res = client.get('/api/v1') docs_url = ['https://docs.bigchaindb.com/projects/server/en/', 'tst', '/drivers-clients/http-client-server-api.html', ] assert res.json == { '_links': { - 'docs': {'href': ''.join(docs_url)}, - 'self': {'href': 'http://localhost/api/v1/'}, - 'statuses': {'href': 'http://localhost/api/v1/statuses/'}, - 'transactions': {'href': 'http://localhost/api/v1/transactions/'} + 'docs': ''.join(docs_url), + 'self': 'http://localhost/api/v1/', + 'statuses': 'http://localhost/api/v1/statuses/', + 'transactions': 'http://localhost/api/v1/transactions/', } }