udata-hydra-csvapi 0.3.2.dev4__py3-none-any.whl → 0.3.2.dev8__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/__init__.py CHANGED
@@ -1,12 +1,13 @@
1
1
  import os
2
2
  import tomllib
3
3
  from pathlib import Path
4
+ from typing import Any
4
5
 
5
6
 
6
7
  class Configurator:
7
8
  """Loads a dict of config from TOML file(s) and behaves like an object, ie config.VALUE"""
8
9
 
9
- configuration = None
10
+ configuration: dict[str, Any] | None = None
10
11
 
11
12
  def __init__(self):
12
13
  if not self.configuration:
@@ -27,6 +28,8 @@ class Configurator:
27
28
  for config_key in configuration:
28
29
  if config_key in os.environ:
29
30
  value = os.getenv(config_key)
31
+ if value is None:
32
+ continue
30
33
  # Casting env value
31
34
  if isinstance(configuration[config_key], list):
32
35
  value = value.split(",")
@@ -46,6 +49,7 @@ class Configurator:
46
49
  self.check()
47
50
 
48
51
  def override(self, **kwargs):
52
+ assert self.configuration is not None
49
53
  self.configuration.update(kwargs)
50
54
  self.check()
51
55
 
@@ -54,10 +58,12 @@ class Configurator:
54
58
  pass
55
59
 
56
60
  def __getattr__(self, __name):
61
+ assert self.configuration is not None
57
62
  return self.configuration.get(__name)
58
63
 
59
64
  @property
60
65
  def __dict__(self):
66
+ assert self.configuration is not None
61
67
  return self.configuration
62
68
 
63
69
 
api_tabular/core/data.py CHANGED
@@ -1,6 +1,5 @@
1
- from typing import AsyncGenerator
2
-
3
1
  from aiohttp import ClientSession, web
2
+ from aiohttp.web import StreamResponse
4
3
  from aiohttp.web_request import Request
5
4
 
6
5
  from api_tabular import config
@@ -14,7 +13,7 @@ async def stream_data(
14
13
  url: str,
15
14
  accept_format: str,
16
15
  response_headers: dict,
17
- ) -> AsyncGenerator[bytes, None]:
16
+ ) -> StreamResponse:
18
17
  res = await session.head(f"{url}&limit=1&", headers={"Prefer": "count=exact"})
19
18
  if not res.ok:
20
19
  handle_exception(res.status, "Database error", await res.json(), None)
@@ -1,3 +1,5 @@
1
+ from typing import cast
2
+
1
3
  import yaml
2
4
 
3
5
  from api_tabular.core.utils import is_aggregation_allowed
@@ -196,14 +198,16 @@ def swagger_parameters(resource_columns: dict, resource_id: str) -> list:
196
198
  ):
197
199
  continue
198
200
  if op in TYPE_POSSIBILITIES[value["python_type"]]:
201
+ op_name = cast(str, OPERATORS_DESCRIPTIONS[op]["name"])
202
+ op_description = cast(str, OPERATORS_DESCRIPTIONS[op]["description"])
199
203
  parameters_list.extend(
200
204
  [
201
205
  {
202
- "name": OPERATORS_DESCRIPTIONS[op]["name"].format(key),
206
+ "name": op_name.format(key),
203
207
  "in": "query",
204
208
  "description": (
205
- (s := OPERATORS_DESCRIPTIONS[op]["description"]).format(
206
- *[key for _ in range(s.count("{}"))]
209
+ op_description.format(
210
+ *[key for _ in range(op_description.count("{}"))]
207
211
  )
208
212
  ),
209
213
  "required": False,
api_tabular/core/url.py CHANGED
@@ -20,4 +20,4 @@ def url_for(request: Request, route: str, *args, **kwargs) -> str:
20
20
  router = request.app.router
21
21
  if kwargs.pop("_external", None):
22
22
  return external_url(router[route].url_for(**kwargs))
23
- return router[route].url_for(**kwargs)
23
+ return str(router[route].url_for(**kwargs))
api_tabular/core/utils.py CHANGED
@@ -1,3 +1,4 @@
1
+ from aiohttp.client import ClientResponse
1
2
  from aiohttp.web_response import Response
2
3
 
3
4
  from api_tabular import config
@@ -8,10 +9,12 @@ def is_aggregation_allowed(resource_id: str) -> bool:
8
9
  return resource_id in config.ALLOW_AGGREGATION
9
10
 
10
11
 
11
- def process_total(res: Response) -> int:
12
+ def process_total(res: Response | ClientResponse) -> int:
12
13
  # the Content-Range looks like this: '0-49/21777'
13
14
  # see https://docs.postgrest.org/en/stable/references/api/pagination_count.html
14
15
  raw_total = res.headers.get("Content-Range")
16
+ if raw_total is None:
17
+ raise ValueError("Missing Content-Range header")
15
18
  _, str_total = raw_total.split("/")
16
19
  return int(str_total)
17
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: udata-hydra-csvapi
3
- Version: 0.3.2.dev4
3
+ Version: 0.3.2.dev8
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
@@ -538,15 +538,20 @@ Tests are automatically run in CI/CD. See [`.circleci/config.yml`](.circleci/con
538
538
 
539
539
  ## 🤝 Contributing
540
540
 
541
- ### 🧹 Code Linting and Formatting
541
+ ### 🧹 Code Linting, Formatting and Type Checking
542
542
 
543
- This project follows PEP 8 style guidelines using [Ruff](https://astral.sh/ruff/) for linting and formatting. **Either running these commands manually or installing the pre-commit hook is required before submitting contributions.**
543
+ This project follows PEP 8 style guidelines using [Ruff](https://astral.sh/ruff/) for linting and formatting, and [ty](https://docs.astral.sh/ty/) for type checking. **Either running these commands manually or installing the pre-commit hook is required before submitting contributions.**
544
544
 
545
545
  ```shell
546
546
  # Lint (including import sorting) and format code
547
547
  uv run ruff check --fix && uv run ruff format
548
+
549
+ # Type check (ty)
550
+ uv run ty check
548
551
  ```
549
552
 
553
+ By default `ty check` checks the project root; pass paths to check specific files or directories. See the [ty CLI reference](https://docs.astral.sh/ty/reference/cli/) for options.
554
+
550
555
  ### 🔗 Pre-commit Hooks
551
556
 
552
557
  This repository uses a [pre-commit](https://pre-commit.com/) hook which lint and format code before each commit. **Installing the pre-commit hook is required for contributions.**
@@ -1,22 +1,22 @@
1
- api_tabular/__init__.py,sha256=QgIzdXI5gOJ1NDR8yX5KEuorArg79D3HujIOXrgjzgo,2078
1
+ api_tabular/__init__.py,sha256=Qso9RRp2-D3hxKwsx4jjBG0LRxHOP699ZuI4v188Om4,2325
2
2
  api_tabular/config_default.toml,sha256=3zQMpzr87qwd23dG_scGUptj0T3IUOjaHecI4ppJBqY,384
3
3
  api_tabular/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- api_tabular/core/data.py,sha256=VYzrrKg40TSmdTVYV2t85sUnJItcvV2iAS4DpSFefaE,1469
4
+ api_tabular/core/data.py,sha256=5j-3d_el7LMoHpn6V__UdhYHD6GiJbwdH67jrnOYWZQ,1459
5
5
  api_tabular/core/error.py,sha256=xRt6fkQfsiupv0tWWzdX0DJjAKbw1n0tRxFyt15VBLA,1062
6
6
  api_tabular/core/health.py,sha256=5VAgsu2t1Ave9n3YduzM3E7aUflBJ3pY1LUrrjT-d6w,775
7
7
  api_tabular/core/query.py,sha256=m98cO16mVkz0cSNICesgjC8MNVEfDW_645sz-DTd2Pw,5576
8
8
  api_tabular/core/sentry.py,sha256=fN5MrDZszLnzLXF3b_nUymPVB0ffNn4PI7xS1GtJNyE,948
9
- api_tabular/core/swagger.py,sha256=cehCCC6K8n5qELG-b5QsQObNGj6DOBMPkROhssYVLyY,14049
10
- api_tabular/core/url.py,sha256=heMenA-0kx2GNcCPF2ViDBZMDFkdT03Jzunm4WadAc8,756
11
- api_tabular/core/utils.py,sha256=06dBcGgP7Zrhy1nnS2AHhILqLy_wNsuQcWyJp01fRVY,887
9
+ api_tabular/core/swagger.py,sha256=0RZFu941CD3qWt2R6e3nnlcrkYjjAHU5eOFl4jH2liA,14188
10
+ api_tabular/core/url.py,sha256=af7VKfrMtKMzlHrGgtLDLuRBim4qFv7xlt2PYxAyW2g,761
11
+ api_tabular/core/utils.py,sha256=SWU1gVkOq728-eZHmZzlyA3pQg6kelEf3SMlL-uEbns,1032
12
12
  api_tabular/core/version.py,sha256=OKLg0l1CpDRHV2hsqVgtSihoo3tg0aMG6kzMILtQ-bY,250
13
13
  api_tabular/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  api_tabular/metrics/app.py,sha256=5kZXzAiFh1tSNYO5GEz67m4zTsTVyoIkgcelDGyT1zE,4637
15
15
  api_tabular/tabular/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  api_tabular/tabular/app.py,sha256=JgqL1svglQ_fD5ndhft_Cm7HmTh5FuyoxYUPGS1_l-o,6771
17
17
  api_tabular/tabular/utils.py,sha256=BL2nl04-3imBQG-RZiYvVMjxoBORi4lwrKq8NiWecLY,4487
18
- udata_hydra_csvapi-0.3.2.dev4.dist-info/licenses/LICENSE,sha256=fb-HAYw94ffh--z1cZrWbpk6YKM0p9WFG7kdd0K7uGQ,1062
19
- udata_hydra_csvapi-0.3.2.dev4.dist-info/METADATA,sha256=k5cWClk8rVaOfftCDrNX-6dRYP3NKCQcvcgAYwDf9DI,18869
20
- udata_hydra_csvapi-0.3.2.dev4.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
21
- udata_hydra_csvapi-0.3.2.dev4.dist-info/top_level.txt,sha256=MAaK09hxwPhIBBC0i1TdEBAgdu3W_gXnAZqk767gVak,12
22
- udata_hydra_csvapi-0.3.2.dev4.dist-info/RECORD,,
18
+ udata_hydra_csvapi-0.3.2.dev8.dist-info/licenses/LICENSE,sha256=fb-HAYw94ffh--z1cZrWbpk6YKM0p9WFG7kdd0K7uGQ,1062
19
+ udata_hydra_csvapi-0.3.2.dev8.dist-info/METADATA,sha256=wlHNzh9fQQSuy3lvGCpHb26fiw2mghgr7gyBPVxFzig,19156
20
+ udata_hydra_csvapi-0.3.2.dev8.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
21
+ udata_hydra_csvapi-0.3.2.dev8.dist-info/top_level.txt,sha256=MAaK09hxwPhIBBC0i1TdEBAgdu3W_gXnAZqk767gVak,12
22
+ udata_hydra_csvapi-0.3.2.dev8.dist-info/RECORD,,