Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,7 @@ coverage.xml
Procfile

# PyCharm
.idea
.idea

# Config
config.toml
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@

- Add endpoint to stream a CSV response [#5](https://github.com/etalab/api-tabular/pull/5)
- Make URL in links absolute [#7](https://github.com/etalab/api-tabular/pull/7)
- Add health route [#16](https://github.com/etalab/api-tabular/pull/16)
- Add SERVER NAME and SCHEME config [#17](https://github.com/etalab/api-tabular/pull/17)
2 changes: 2 additions & 0 deletions api_tabular/config_default.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
PG_RST_URL = "http://localhost:8080"
SERVER_NAME = 'localhost:8005'
SCHEME = 'http'
SENTRY_DSN = ""
PAGE_SIZE_DEFAULT = 20
PAGE_SIZE_MAX = 50
Expand Down
10 changes: 8 additions & 2 deletions api_tabular/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from aiohttp.web_request import Request

from api_tabular import config


def build_sql_query_string(
request_arg: list, page_size: int = None, offset: int = 0
Expand Down Expand Up @@ -41,15 +43,19 @@ def process_total(raw_total: str) -> int:
return int(str_total)


def external_url(url):
return f"{config.SCHEME}://{config.SERVER_NAME}{url}"


def build_link_with_page(request: Request, query_string: str, page: int, page_size: int):
q = [string for string in query_string if not string.startswith("page")]
q.extend([f"page={page}", f"page_size={page_size}"])
rebuilt_q = "&".join(q)
return f"{request.scheme}://{request.host}{request.path}?{rebuilt_q}"
return external_url(f"{request.path}?{rebuilt_q}")


def url_for(request: Request, route: str, *args, **kwargs):
router = request.app.router
if kwargs.pop("_external", None):
return f"{request.scheme}://{request.host}{router[route].url_for(**kwargs)}"
return external_url(router[route].url_for(**kwargs))
return router[route].url_for(**kwargs)
28 changes: 15 additions & 13 deletions tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest

from api_tabular.utils import external_url

from .conftest import RESOURCE_ID, DATE, PG_RST_URL, TABLES_INDEX_PATTERN

pytestmark = pytest.mark.asyncio
Expand All @@ -22,12 +24,12 @@ async def test_api_resource_meta(client, rmock):
"url": "https://example.com",
"links": [
{
"href": f"http://127.0.0.1:{client.port}/api/resources/{RESOURCE_ID}/profile/",
"href": external_url(f"/api/resources/{RESOURCE_ID}/profile/"),
"type": "GET",
"rel": "profile",
},
{
"href": f"http://127.0.0.1:{client.port}/api/resources/{RESOURCE_ID}/data/",
"href": external_url(f"/api/resources/{RESOURCE_ID}/data/"),
"type": "GET",
"rel": "data",
},
Expand Down Expand Up @@ -66,7 +68,7 @@ async def test_api_resource_data(client, rmock):
"links": {
"next": None,
"prev": None,
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 1, "page_size": 20, "total": 10},
}
Expand All @@ -88,7 +90,7 @@ async def test_api_resource_data_with_args(client, rmock):
"links": {
"next": None,
"prev": None,
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 1, "page_size": 20, "total": 10},
}
Expand All @@ -110,7 +112,7 @@ async def test_api_resource_data_with_args_case(client, rmock):
"links": {
"next": None,
"prev": None,
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 1, "page_size": 20, "total": 10},
}
Expand Down Expand Up @@ -183,7 +185,7 @@ async def test_api_percent_encoding_arabic(client, rmock):
"links": {
"next": None,
"prev": None,
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 1, "page_size": 20, "total": 10},
}
Expand All @@ -205,7 +207,7 @@ async def test_api_with_unsupported_args(client, rmock):
"links": {
"next": None,
"prev": None,
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 1, "page_size": 20, "total": 10},
}
Expand All @@ -225,10 +227,10 @@ async def test_api_pagination(client, rmock):
body = {
"data": [{"such": "data"}],
"links": {
"next": f"http://127.0.0.1:{client.port}"
"/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/data/?page=2&page_size=1",
"next": external_url(
"/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/data/?page=2&page_size=1"),
"prev": None,
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 1, "page_size": 1, "total": 2},
}
Expand All @@ -247,9 +249,9 @@ async def test_api_pagination(client, rmock):
"data": [{"such": "data"}],
"links": {
"next": None,
"prev": f"http://127.0.0.1:{client.port}"
"/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/data/?page=1&page_size=1",
"profile": f"http://127.0.0.1:{client.port}/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/",
"prev": external_url(
"/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/data/?page=1&page_size=1"),
"profile": external_url("/api/resources/60963939-6ada-46bc-9a29-b288b16d969b/profile/"),
},
"meta": {"page": 2, "page_size": 1, "total": 2},
}
Expand Down
6 changes: 3 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

from aiohttp.test_utils import make_mocked_request

from api_tabular.utils import build_link_with_page, url_for
from api_tabular.utils import build_link_with_page, url_for, external_url


def test_build_link_with_page():
request = make_mocked_request("GET", "/api/test?foo=bar")
link = build_link_with_page(request, query_string=["foo=1", "bar=3"], page=2, page_size=10)
assert link == f"{request.scheme}://{request.host}/api/test?foo=1&bar=3&page=2&page_size=10"
assert link == external_url("/api/test?foo=1&bar=3&page=2&page_size=10")


def test_url_for(client):
Expand All @@ -21,4 +21,4 @@ def test_url_for_external(client):
request = make_mocked_request("GET", "/api/test?foo=bar")
request.app.router = client.app.router
url = url_for(request, 'profile', rid='rid', _external=True)
assert str(url) == f'{request.scheme}://{request.host}/api/resources/rid/profile/'
assert str(url) == external_url("/api/resources/rid/profile/")