permisapi-client 0.7.0__tar.gz → 0.7.2__tar.gz
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.
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/PKG-INFO +1 -1
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/permisapi_client/__init__.py +1 -1
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/permisapi_client/client.py +22 -2
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/pyproject.toml +1 -1
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/tests/test_client.py +18 -0
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/.gitignore +0 -0
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/README.md +0 -0
- {permisapi_client-0.7.0 → permisapi_client-0.7.2}/permisapi_client/exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: permisapi-client
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: Client Python officiel pour PermisAPI : permis de construire France en API REST.
|
|
5
5
|
Project-URL: Homepage, https://permisapi.fr
|
|
6
6
|
Project-URL: Documentation, https://permisapi.fr/docs
|
|
@@ -13,7 +13,7 @@ from permisapi_client.exceptions import error_from_response
|
|
|
13
13
|
|
|
14
14
|
DEFAULT_BASE_URL = "https://api.permisapi.fr"
|
|
15
15
|
DEFAULT_TIMEOUT = 15.0
|
|
16
|
-
USER_AGENT = "permisapi-client-python/0.7.
|
|
16
|
+
USER_AGENT = "permisapi-client-python/0.7.2"
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def _raise_for_status(resp: httpx.Response) -> None:
|
|
@@ -52,7 +52,25 @@ class _PermitsResource:
|
|
|
52
52
|
self._c = client
|
|
53
53
|
|
|
54
54
|
def list(self, **params: Any) -> dict[str, Any]:
|
|
55
|
-
"""GET /v1/permits avec filtres. Retourne {
|
|
55
|
+
"""GET /v1/permits avec filtres. Retourne {data, pagination}.
|
|
56
|
+
|
|
57
|
+
Filtres acceptes : dep_code, comm_code, localite, codpost,
|
|
58
|
+
permit_type, etat_pa, an_depot, date_from, date_to,
|
|
59
|
+
min_superficie, siren, geocoded_only, page, limit.
|
|
60
|
+
|
|
61
|
+
Tri : passer `sort="-date_reelle_autorisation"` (defaut),
|
|
62
|
+
`sort="date_depot"`, `sort="-superficie_terrain"`, etc.
|
|
63
|
+
Champs autorises : date_reelle_autorisation, date_depot,
|
|
64
|
+
an_depot, superficie_terrain. Prefixe `-` pour descendant.
|
|
65
|
+
Tout autre champ retourne 422 (et non ignore silencieusement).
|
|
66
|
+
|
|
67
|
+
Filtre `min_score` (Pro+ uniquement) : retourne uniquement les
|
|
68
|
+
permits avec un Score Opportunite MDB >= N (0-100). Use case
|
|
69
|
+
marchand de biens : shortliste les top opportunites en 1 call
|
|
70
|
+
au lieu de fetch + filter cote client. Cout quota special :
|
|
71
|
+
`limit` unites au lieu de 1 (anti-abus, equivalent a N calls
|
|
72
|
+
/score). Header X-RateLimit-Cost confirme.
|
|
73
|
+
"""
|
|
56
74
|
return self._c._get("/v1/permits", params=params)
|
|
57
75
|
|
|
58
76
|
def iter_all(self, **params: Any) -> Iterator[dict[str, Any]]:
|
|
@@ -462,6 +480,8 @@ class _AsyncPermitsResource:
|
|
|
462
480
|
self._c = client
|
|
463
481
|
|
|
464
482
|
async def list(self, **params: Any) -> dict[str, Any]:
|
|
483
|
+
"""GET /v1/permits avec filtres. Voir _PermitsResource.list pour
|
|
484
|
+
la doc complete (filtres + tri sort=)."""
|
|
465
485
|
return await self._c._get("/v1/permits", params=params)
|
|
466
486
|
|
|
467
487
|
async def iter_all(self, **params: Any) -> AsyncIterator[dict[str, Any]]:
|
|
@@ -337,6 +337,24 @@ async def test_async_permits_export() -> None:
|
|
|
337
337
|
assert b"PC-A,75" in result
|
|
338
338
|
|
|
339
339
|
|
|
340
|
+
@respx.mock
|
|
341
|
+
def test_permits_list_with_sort() -> None:
|
|
342
|
+
"""SDK propagates `sort=` query param transparently to the API."""
|
|
343
|
+
route = respx.get(f"{BASE}/v1/permits").respond(
|
|
344
|
+
json={
|
|
345
|
+
"data": [{"num_pa": "PC-1", "superficie_terrain": 1500}],
|
|
346
|
+
"pagination": {"page": 1, "total": 1, "pages": 1},
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
with PermisAPI(api_key="pk_test_abc") as client:
|
|
350
|
+
client.permits.list(dep_code="33", sort="-superficie_terrain", limit=10)
|
|
351
|
+
assert route.called
|
|
352
|
+
# The sort param must appear in the request URL query string
|
|
353
|
+
url = str(route.calls.last.request.url)
|
|
354
|
+
assert "sort=-superficie_terrain" in url
|
|
355
|
+
assert "dep_code=33" in url
|
|
356
|
+
|
|
357
|
+
|
|
340
358
|
@respx.mock
|
|
341
359
|
def test_permits_full_view_sync() -> None:
|
|
342
360
|
"""Sync : full_view appelle GET /v1/permits/{num_pa}/360 et retourne
|
|
File without changes
|
|
File without changes
|
|
File without changes
|