udata-hydra-csvapi 0.4.3.dev1__py3-none-any.whl → 0.4.3.dev3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- api_tabular/core/query.py +1 -1
- api_tabular/core/swagger.py +4 -3
- api_tabular/core/utils.py +21 -2
- api_tabular/metrics/app.py +2 -5
- api_tabular/tabular/app.py +2 -5
- {udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/METADATA +3 -3
- {udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/RECORD +10 -10
- {udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/WHEEL +0 -0
- {udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/licenses/LICENSE +0 -0
- {udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/top_level.txt +0 -0
api_tabular/core/query.py
CHANGED
|
@@ -56,7 +56,7 @@ def build_sql_query_string(
|
|
|
56
56
|
agg_query += f'"{column[1:-1]}__{operator}":{column}.{operator}(),'
|
|
57
57
|
# we pop the trailing comma (it's always there, by construction)
|
|
58
58
|
sql_query.append(agg_query[:-1])
|
|
59
|
-
if page_size:
|
|
59
|
+
if page_size is not None:
|
|
60
60
|
sql_query.append(f"limit={page_size}")
|
|
61
61
|
if offset >= 1:
|
|
62
62
|
sql_query.append(f"offset={offset}")
|
api_tabular/core/swagger.py
CHANGED
|
@@ -2,6 +2,7 @@ from typing import cast
|
|
|
2
2
|
|
|
3
3
|
import yaml
|
|
4
4
|
|
|
5
|
+
from api_tabular import config
|
|
5
6
|
from api_tabular.core.utils import is_aggregation_allowed
|
|
6
7
|
|
|
7
8
|
TYPE_POSSIBILITIES = {
|
|
@@ -165,9 +166,9 @@ def swagger_parameters(resource_columns: dict, resource_id: str) -> list:
|
|
|
165
166
|
{
|
|
166
167
|
"name": "page",
|
|
167
168
|
"in": "query",
|
|
168
|
-
"description": "Specific page (page=value)",
|
|
169
|
+
"description": "Specific page, starting at 1 (page=value)",
|
|
169
170
|
"required": False,
|
|
170
|
-
"schema": {"type": "integer"},
|
|
171
|
+
"schema": {"type": "integer", "minimum": 1},
|
|
171
172
|
"example": 1,
|
|
172
173
|
},
|
|
173
174
|
{
|
|
@@ -175,7 +176,7 @@ def swagger_parameters(resource_columns: dict, resource_id: str) -> list:
|
|
|
175
176
|
"in": "query",
|
|
176
177
|
"description": "Number of results per page (page_size=value)",
|
|
177
178
|
"required": False,
|
|
178
|
-
"schema": {"type": "integer"},
|
|
179
|
+
"schema": {"type": "integer", "minimum": 1, "maximum": config.PAGE_SIZE_MAX},
|
|
179
180
|
"example": 20,
|
|
180
181
|
},
|
|
181
182
|
{
|
api_tabular/core/utils.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from collections.abc import Mapping
|
|
2
|
+
|
|
1
3
|
from aiohttp.client import ClientResponse
|
|
2
4
|
from aiohttp.web_response import Response
|
|
3
5
|
|
|
@@ -19,7 +21,24 @@ def process_total(res: Response | ClientResponse) -> int:
|
|
|
19
21
|
return int(str_total)
|
|
20
22
|
|
|
21
23
|
|
|
22
|
-
def
|
|
24
|
+
def _parse_int_param(query: Mapping[str, str], name: str, label: str, default: int) -> int:
|
|
25
|
+
raw = query.get(name)
|
|
26
|
+
if raw is None:
|
|
27
|
+
return default
|
|
28
|
+
try:
|
|
29
|
+
return int(raw)
|
|
30
|
+
except ValueError:
|
|
31
|
+
raise QueryException(400, None, "Invalid query string", f"{label} must be an integer")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def parse_pagination(query: Mapping[str, str]) -> tuple[int, int, int]:
|
|
35
|
+
"""Return (page, page_size, offset) from the query, raising a 400 on invalid values"""
|
|
36
|
+
page = _parse_int_param(query, "page", "Page", 1)
|
|
37
|
+
page_size = _parse_int_param(query, "page_size", "Page size", config.PAGE_SIZE_DEFAULT)
|
|
38
|
+
if page < 1:
|
|
39
|
+
raise QueryException(400, None, "Invalid query string", "Page must be at least 1")
|
|
40
|
+
if page_size < 1:
|
|
41
|
+
raise QueryException(400, None, "Invalid query string", "Page size must be at least 1")
|
|
23
42
|
if page_size > config.PAGE_SIZE_MAX:
|
|
24
43
|
raise QueryException(
|
|
25
44
|
400,
|
|
@@ -27,4 +46,4 @@ def build_offset(page: int, page_size: int) -> int:
|
|
|
27
46
|
"Invalid query string",
|
|
28
47
|
f"Page size exceeds allowed maximum: {config.PAGE_SIZE_MAX}",
|
|
29
48
|
)
|
|
30
|
-
return page_size * (page - 1)
|
|
49
|
+
return page, page_size, page_size * (page - 1)
|
api_tabular/metrics/app.py
CHANGED
|
@@ -14,7 +14,7 @@ from api_tabular.core.health import check_health
|
|
|
14
14
|
from api_tabular.core.query import build_sql_query_string
|
|
15
15
|
from api_tabular.core.sentry import get_sentry_kwargs
|
|
16
16
|
from api_tabular.core.url import build_link_with_page
|
|
17
|
-
from api_tabular.core.utils import
|
|
17
|
+
from api_tabular.core.utils import parse_pagination, process_total
|
|
18
18
|
from api_tabular.core.version import get_app_version
|
|
19
19
|
|
|
20
20
|
routes = web.RouteTableDef()
|
|
@@ -40,10 +40,7 @@ async def metrics_data(request):
|
|
|
40
40
|
"""
|
|
41
41
|
model = request.match_info["model"]
|
|
42
42
|
query_string = request.query_string.split("&") if request.query_string else []
|
|
43
|
-
page =
|
|
44
|
-
page_size = int(request.query.get("page_size", config.PAGE_SIZE_DEFAULT))
|
|
45
|
-
|
|
46
|
-
offset = build_offset(page, page_size)
|
|
43
|
+
page, page_size, offset = parse_pagination(request.query)
|
|
47
44
|
try:
|
|
48
45
|
sql_query = build_sql_query_string(query_string, page_size=page_size, offset=offset)
|
|
49
46
|
except ValueError as e:
|
api_tabular/tabular/app.py
CHANGED
|
@@ -12,7 +12,7 @@ from api_tabular.core.health import check_health
|
|
|
12
12
|
from api_tabular.core.sentry import get_sentry_kwargs
|
|
13
13
|
from api_tabular.core.swagger import build_swagger_file
|
|
14
14
|
from api_tabular.core.url import build_link_with_page, url_for
|
|
15
|
-
from api_tabular.core.utils import
|
|
15
|
+
from api_tabular.core.utils import parse_pagination
|
|
16
16
|
from api_tabular.core.version import get_app_version
|
|
17
17
|
from api_tabular.tabular.utils import (
|
|
18
18
|
get_potential_indexes,
|
|
@@ -97,10 +97,7 @@ def build_next_page(
|
|
|
97
97
|
async def resource_data(request):
|
|
98
98
|
resource_id = request.match_info["rid"]
|
|
99
99
|
query_string = request.query_string.split("&") if request.query_string else []
|
|
100
|
-
page =
|
|
101
|
-
page_size = int(request.query.get("page_size", config.PAGE_SIZE_DEFAULT))
|
|
102
|
-
|
|
103
|
-
offset = build_offset(page, page_size)
|
|
100
|
+
page, page_size, offset = parse_pagination(request.query)
|
|
104
101
|
|
|
105
102
|
sql_query = await try_build_query(request, query_string, resource_id, page_size, offset)
|
|
106
103
|
resource = await get_resource(request.app["csession"], resource_id, ["parsing_table"])
|
{udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: udata-hydra-csvapi
|
|
3
|
-
Version: 0.4.3.
|
|
3
|
+
Version: 0.4.3.dev3
|
|
4
4
|
Summary: API for CSV converted by udata-hydra
|
|
5
5
|
Author-email: "data.gouv.fr" <opendatateam@data.gouv.fr>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -365,8 +365,8 @@ column_name__sum
|
|
|
365
365
|
|
|
366
366
|
#### Pagination
|
|
367
367
|
```
|
|
368
|
-
page=1 # Page number (default: 1)
|
|
369
|
-
page_size=20 # Items per page (default: 20, max: 50)
|
|
368
|
+
page=1 # Page number (default: 1, min: 1)
|
|
369
|
+
page_size=20 # Items per page (default: 20, min: 1, max: 50)
|
|
370
370
|
```
|
|
371
371
|
|
|
372
372
|
#### Column Selection
|
|
@@ -5,19 +5,19 @@ api_tabular/core/cors.py,sha256=QY006pAnR1fMBMJJTAeRGcopL_4LkY7YoA3y8KYk4dI,825
|
|
|
5
5
|
api_tabular/core/data.py,sha256=5j-3d_el7LMoHpn6V__UdhYHD6GiJbwdH67jrnOYWZQ,1459
|
|
6
6
|
api_tabular/core/error.py,sha256=xRt6fkQfsiupv0tWWzdX0DJjAKbw1n0tRxFyt15VBLA,1062
|
|
7
7
|
api_tabular/core/health.py,sha256=NeFT1C00onvm3CbgesFAcN1N8bmelbQdEYFbmmftICQ,647
|
|
8
|
-
api_tabular/core/query.py,sha256=
|
|
8
|
+
api_tabular/core/query.py,sha256=J7woFLDzA8RpMBXJKpKm8olDdZsp2_TQEROJtIaeokM,10238
|
|
9
9
|
api_tabular/core/sentry.py,sha256=fN5MrDZszLnzLXF3b_nUymPVB0ffNn4PI7xS1GtJNyE,948
|
|
10
|
-
api_tabular/core/swagger.py,sha256=
|
|
10
|
+
api_tabular/core/swagger.py,sha256=mMEESM4UlgK-voyRTKrddVuUrlUMfTDOQtK1VrVp7Ak,14748
|
|
11
11
|
api_tabular/core/url.py,sha256=af7VKfrMtKMzlHrGgtLDLuRBim4qFv7xlt2PYxAyW2g,761
|
|
12
|
-
api_tabular/core/utils.py,sha256=
|
|
12
|
+
api_tabular/core/utils.py,sha256=Ghd9Un0HugFg4oEcEb5yB5FEop7tDSoX4OCzR8mcM-Y,1922
|
|
13
13
|
api_tabular/core/version.py,sha256=OKLg0l1CpDRHV2hsqVgtSihoo3tg0aMG6kzMILtQ-bY,250
|
|
14
14
|
api_tabular/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
api_tabular/metrics/app.py,sha256=
|
|
15
|
+
api_tabular/metrics/app.py,sha256=m2H4qOvzvi8oDjCg1R23JAK6VaqDcrqYCz6ScIk9iAc,4305
|
|
16
16
|
api_tabular/tabular/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
api_tabular/tabular/app.py,sha256=
|
|
17
|
+
api_tabular/tabular/app.py,sha256=fBnbIR2H3jm0suVVEfNuVdSccOwZeMKH__iekwmDVa8,6542
|
|
18
18
|
api_tabular/tabular/utils.py,sha256=BL2nl04-3imBQG-RZiYvVMjxoBORi4lwrKq8NiWecLY,4487
|
|
19
|
-
udata_hydra_csvapi-0.4.3.
|
|
20
|
-
udata_hydra_csvapi-0.4.3.
|
|
21
|
-
udata_hydra_csvapi-0.4.3.
|
|
22
|
-
udata_hydra_csvapi-0.4.3.
|
|
23
|
-
udata_hydra_csvapi-0.4.3.
|
|
19
|
+
udata_hydra_csvapi-0.4.3.dev3.dist-info/licenses/LICENSE,sha256=fb-HAYw94ffh--z1cZrWbpk6YKM0p9WFG7kdd0K7uGQ,1062
|
|
20
|
+
udata_hydra_csvapi-0.4.3.dev3.dist-info/METADATA,sha256=mBjWOUsIDJAxQWABC7L49YdknGyNsX2tKDG3Sh7spTk,21835
|
|
21
|
+
udata_hydra_csvapi-0.4.3.dev3.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
22
|
+
udata_hydra_csvapi-0.4.3.dev3.dist-info/top_level.txt,sha256=MAaK09hxwPhIBBC0i1TdEBAgdu3W_gXnAZqk767gVak,12
|
|
23
|
+
udata_hydra_csvapi-0.4.3.dev3.dist-info/RECORD,,
|
|
File without changes
|
{udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{udata_hydra_csvapi-0.4.3.dev1.dist-info → udata_hydra_csvapi-0.4.3.dev3.dist-info}/top_level.txt
RENAMED
|
File without changes
|