permisapi-client 0.8.0__tar.gz → 0.8.1__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.8.0 → permisapi_client-0.8.1}/.gitignore +6 -0
- permisapi_client-0.8.1/PKG-INFO +207 -0
- permisapi_client-0.8.1/README.md +179 -0
- {permisapi_client-0.8.0 → permisapi_client-0.8.1}/permisapi_client/__init__.py +4 -3
- {permisapi_client-0.8.0 → permisapi_client-0.8.1}/permisapi_client/client.py +254 -101
- {permisapi_client-0.8.0 → permisapi_client-0.8.1}/permisapi_client/exceptions.py +2 -1
- {permisapi_client-0.8.0 → permisapi_client-0.8.1}/pyproject.toml +2 -2
- {permisapi_client-0.8.0 → permisapi_client-0.8.1}/tests/test_client.py +124 -21
- permisapi_client-0.8.0/PKG-INFO +0 -188
- permisapi_client-0.8.0/README.md +0 -160
|
@@ -36,6 +36,8 @@ SECRETS_INVENTORY.md
|
|
|
36
36
|
data/raw/*.csv
|
|
37
37
|
data/raw/*.zip
|
|
38
38
|
data/processed/*.parquet
|
|
39
|
+
data/cerema_dvfplus/
|
|
40
|
+
data/cadastre_geojson/
|
|
39
41
|
|
|
40
42
|
# Database
|
|
41
43
|
*.sqlite
|
|
@@ -66,3 +68,7 @@ scrape-downloads/
|
|
|
66
68
|
|
|
67
69
|
# Local handoff bundle (assembled then zipped, not committed)
|
|
68
70
|
handoff-bundle/
|
|
71
|
+
|
|
72
|
+
# Exports prospects locaux (donnees derivees, regenerables via scripts/export_prospects.py)
|
|
73
|
+
prospects_export.csv
|
|
74
|
+
prospects_*.csv
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: permisapi-client
|
|
3
|
+
Version: 0.8.1
|
|
4
|
+
Summary: Client Python officiel pour PermisAPI : permis de construire de France en API REST.
|
|
5
|
+
Project-URL: Homepage, https://permisapi.fr
|
|
6
|
+
Project-URL: Documentation, https://permisapi.fr/docs
|
|
7
|
+
Project-URL: Changelog, https://permisapi.fr/changelog
|
|
8
|
+
Author-email: Evan Caroux <evan@permisapi.fr>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: api,construire,france,geocoding,permis,proptech,real-estate,sitadel
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Natural Language :: French
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Requires-Dist: httpx>=0.24.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
26
|
+
Requires-Dist: respx>=0.20; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# permisapi-client
|
|
30
|
+
|
|
31
|
+
Client Python officiel de [PermisAPI](https://permisapi.fr) : 1,3 million de permis de
|
|
32
|
+
construire en France (base Sitadel, permis autorisés depuis 2013, 101 départements) dans
|
|
33
|
+
une API REST.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install permisapi-client
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Démarrage rapide
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from permisapi_client import PermisAPI
|
|
45
|
+
|
|
46
|
+
client = PermisAPI(api_key="pk_live_...") # clé obtenue sur https://permisapi.fr/#pricing
|
|
47
|
+
|
|
48
|
+
# Liste paginée : {"data": [...], "pagination": {page, limit, total, has_next, next_url}}
|
|
49
|
+
page = client.permits.list(dep_code="75", limit=10)
|
|
50
|
+
for permit in page["data"]:
|
|
51
|
+
print(permit["num_pa"], permit["full_address"])
|
|
52
|
+
print(page["pagination"]["total"], "permis au total")
|
|
53
|
+
|
|
54
|
+
# Recherche géographique (PostGIS) : liste de permis, chacun avec distance_m
|
|
55
|
+
nearby = client.permits.near(lat=48.8599, lng=2.3423, radius_m=300)
|
|
56
|
+
|
|
57
|
+
# Détail d'un permis
|
|
58
|
+
permit = client.permits.get("07510125V0025")
|
|
59
|
+
|
|
60
|
+
# Statistiques d'une commune (Paris entier est rangé sous le code 75056 dans Sitadel)
|
|
61
|
+
stats = client.stats.commune("75056")
|
|
62
|
+
print(stats["total_permits"], stats["granted"], stats["trend_yoy_pct"])
|
|
63
|
+
|
|
64
|
+
# Toutes les pages, jusqu'à pagination.has_next == False
|
|
65
|
+
for p in client.permits.iter_all(dep_code="75", permit_type="PC_LOGEMENT"):
|
|
66
|
+
print(p["num_pa"])
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Coût : une recherche (`list`, `iter_all`, `near`, `search`) décompte 1 requête par permis
|
|
70
|
+
renvoyé. `iter_all` sur un département entier peut donc épuiser le quota mensuel de la
|
|
71
|
+
formule Gratuit (500 requêtes) ou Explorer (5 000).
|
|
72
|
+
|
|
73
|
+
Formules : **Gratuit** (1 département, 6 mois d'historique), **Explorer** (5 départements,
|
|
74
|
+
6 mois), **Régional** (5 départements, historique complet et données avancées), **Pro**
|
|
75
|
+
(les mêmes données avancées sur la France entière), **Business** et **Enterprise**. Les
|
|
76
|
+
exemples de cette page portent sur Paris (75).
|
|
77
|
+
|
|
78
|
+
## Données avancées (formules Régional, Pro, Business et Enterprise)
|
|
79
|
+
|
|
80
|
+
Les formules Gratuit et Explorer reçoivent une erreur 402 sur ces routes.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
num_pa = "07510125V0025"
|
|
84
|
+
|
|
85
|
+
# Ventes immobilières DVF voisines (ventes de 2021 à 2025)
|
|
86
|
+
dvf = client.permits.dvf(num_pa, limit=5)
|
|
87
|
+
for m in dvf["matches"]:
|
|
88
|
+
print(m["date_mutation"], m["valeur_fonciere"], "EUR à", m["distance_m"], "m")
|
|
89
|
+
print("Prix médian au m² :", dvf["dvf_median_price_per_m2"])
|
|
90
|
+
|
|
91
|
+
# Score d'opportunité marchand de biens v0.3 (note 0-100 et palier)
|
|
92
|
+
score = client.permits.score_mdb(num_pa)
|
|
93
|
+
print(f"Score : {score['score']}/100 ({score['tier']})")
|
|
94
|
+
# Score déjà pré-calculé : components vaut None ; le détail des 11 signaux
|
|
95
|
+
# est donné par la route /v1/permits/{num_pa}/score/explain.
|
|
96
|
+
|
|
97
|
+
# Zonage PLU (constructible, à urbaniser, agricole, naturel)
|
|
98
|
+
plu = client.permits.plu(num_pa)
|
|
99
|
+
if plu["has_plu"]:
|
|
100
|
+
z = plu["zonage"]
|
|
101
|
+
print(f"Zone {z['code']}, constructible : {z['constructible']}")
|
|
102
|
+
|
|
103
|
+
# Risques Géorisques (inondation, séisme, sites Seveso proches...)
|
|
104
|
+
risks = client.permits.risks(num_pa)
|
|
105
|
+
print(f"Risque : {risks['risk_score']}/100 ({risks['risk_tier']})")
|
|
106
|
+
for risk in risks["risks"]:
|
|
107
|
+
print(f"- {risk['label']} (PPR : {risk['has_ppr']})")
|
|
108
|
+
|
|
109
|
+
# Votre avis sur un score
|
|
110
|
+
client.permits.score_feedback(
|
|
111
|
+
num_pa=num_pa,
|
|
112
|
+
score_received=72,
|
|
113
|
+
tier_received="high",
|
|
114
|
+
useful=True,
|
|
115
|
+
accuracy="correct",
|
|
116
|
+
comment="Score cohérent avec notre analyse du quartier.",
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Export CSV (Business et Enterprise)
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
# Plafond : 100 000 lignes en Business, 1 000 000 en Enterprise
|
|
124
|
+
csv_bytes = client.permits.export(
|
|
125
|
+
dep_code="75",
|
|
126
|
+
permit_type="PC_LOGEMENT",
|
|
127
|
+
date_from="2024-01-01",
|
|
128
|
+
max_rows=5000,
|
|
129
|
+
)
|
|
130
|
+
with open("paris.csv", "wb") as f:
|
|
131
|
+
f.write(csv_bytes)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Serveur MCP (Claude, ChatGPT, Cursor)
|
|
135
|
+
|
|
136
|
+
Le serveur MCP officiel (paquet séparé `permisapi-mcp`) permet à Claude, ChatGPT, Claude
|
|
137
|
+
Desktop, Cursor et Windsurf d'interroger PermisAPI en langage naturel :
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
pip install permisapi-mcp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Configurez votre clé dans le client MCP, puis demandez directement :
|
|
144
|
+
> *« Liste les permis de logement autorisés à Paris ce mois-ci »*
|
|
145
|
+
|
|
146
|
+
Mise en place complète : [permisapi.fr/mcp](https://permisapi.fr/mcp).
|
|
147
|
+
|
|
148
|
+
## Async
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
import asyncio
|
|
152
|
+
from permisapi_client import AsyncPermisAPI
|
|
153
|
+
|
|
154
|
+
async def main():
|
|
155
|
+
async with AsyncPermisAPI(api_key="pk_live_...") as client:
|
|
156
|
+
page = await client.permits.list(dep_code="75")
|
|
157
|
+
print(page["pagination"]["total"])
|
|
158
|
+
async for p in client.permits.iter_all(dep_code="75", permit_type="PC_LOGEMENT"):
|
|
159
|
+
print(p["num_pa"])
|
|
160
|
+
|
|
161
|
+
asyncio.run(main())
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Alertes par webhook
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
alert = client.alerts.create(
|
|
168
|
+
name="Paris 18e rénovations",
|
|
169
|
+
center_lat=48.88,
|
|
170
|
+
center_lng=2.35,
|
|
171
|
+
radius_km=3,
|
|
172
|
+
permit_types=["PC_LOGEMENT"],
|
|
173
|
+
webhook_url="https://votre-application.fr/permisapi-hook",
|
|
174
|
+
)
|
|
175
|
+
# Le webhook_secret n'est renvoyé qu'ICI : conservez-le pour vérifier les signatures HMAC.
|
|
176
|
+
print(alert["webhook_secret"])
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Gestion des erreurs
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from permisapi_client import (
|
|
183
|
+
PermisAPI,
|
|
184
|
+
PermisAPIRateLimited,
|
|
185
|
+
PermisAPIQuotaExceeded,
|
|
186
|
+
PermisAPIUnauthorized,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
try:
|
|
190
|
+
client.permits.list(dep_code="75")
|
|
191
|
+
except PermisAPIUnauthorized:
|
|
192
|
+
print("Clé API invalide")
|
|
193
|
+
except PermisAPIQuotaExceeded:
|
|
194
|
+
print("Quota mensuel atteint : il se renouvelle le 1er du mois (UTC)")
|
|
195
|
+
except PermisAPIRateLimited as e:
|
|
196
|
+
print(f"Trop de requêtes par minute, nouvel essai possible dans {e.retry_after} s")
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Licence
|
|
200
|
+
|
|
201
|
+
MIT. Source des permis : SDES, base Sitadel, data.gouv.fr (Licence Ouverte Etalab).
|
|
202
|
+
|
|
203
|
+
## Liens
|
|
204
|
+
|
|
205
|
+
- Documentation : https://permisapi.fr/docs
|
|
206
|
+
- Référence complète de l'API : https://api.permisapi.fr/docs
|
|
207
|
+
- Nouveautés : https://permisapi.fr/changelog
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# permisapi-client
|
|
2
|
+
|
|
3
|
+
Client Python officiel de [PermisAPI](https://permisapi.fr) : 1,3 million de permis de
|
|
4
|
+
construire en France (base Sitadel, permis autorisés depuis 2013, 101 départements) dans
|
|
5
|
+
une API REST.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install permisapi-client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Démarrage rapide
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from permisapi_client import PermisAPI
|
|
17
|
+
|
|
18
|
+
client = PermisAPI(api_key="pk_live_...") # clé obtenue sur https://permisapi.fr/#pricing
|
|
19
|
+
|
|
20
|
+
# Liste paginée : {"data": [...], "pagination": {page, limit, total, has_next, next_url}}
|
|
21
|
+
page = client.permits.list(dep_code="75", limit=10)
|
|
22
|
+
for permit in page["data"]:
|
|
23
|
+
print(permit["num_pa"], permit["full_address"])
|
|
24
|
+
print(page["pagination"]["total"], "permis au total")
|
|
25
|
+
|
|
26
|
+
# Recherche géographique (PostGIS) : liste de permis, chacun avec distance_m
|
|
27
|
+
nearby = client.permits.near(lat=48.8599, lng=2.3423, radius_m=300)
|
|
28
|
+
|
|
29
|
+
# Détail d'un permis
|
|
30
|
+
permit = client.permits.get("07510125V0025")
|
|
31
|
+
|
|
32
|
+
# Statistiques d'une commune (Paris entier est rangé sous le code 75056 dans Sitadel)
|
|
33
|
+
stats = client.stats.commune("75056")
|
|
34
|
+
print(stats["total_permits"], stats["granted"], stats["trend_yoy_pct"])
|
|
35
|
+
|
|
36
|
+
# Toutes les pages, jusqu'à pagination.has_next == False
|
|
37
|
+
for p in client.permits.iter_all(dep_code="75", permit_type="PC_LOGEMENT"):
|
|
38
|
+
print(p["num_pa"])
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Coût : une recherche (`list`, `iter_all`, `near`, `search`) décompte 1 requête par permis
|
|
42
|
+
renvoyé. `iter_all` sur un département entier peut donc épuiser le quota mensuel de la
|
|
43
|
+
formule Gratuit (500 requêtes) ou Explorer (5 000).
|
|
44
|
+
|
|
45
|
+
Formules : **Gratuit** (1 département, 6 mois d'historique), **Explorer** (5 départements,
|
|
46
|
+
6 mois), **Régional** (5 départements, historique complet et données avancées), **Pro**
|
|
47
|
+
(les mêmes données avancées sur la France entière), **Business** et **Enterprise**. Les
|
|
48
|
+
exemples de cette page portent sur Paris (75).
|
|
49
|
+
|
|
50
|
+
## Données avancées (formules Régional, Pro, Business et Enterprise)
|
|
51
|
+
|
|
52
|
+
Les formules Gratuit et Explorer reçoivent une erreur 402 sur ces routes.
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
num_pa = "07510125V0025"
|
|
56
|
+
|
|
57
|
+
# Ventes immobilières DVF voisines (ventes de 2021 à 2025)
|
|
58
|
+
dvf = client.permits.dvf(num_pa, limit=5)
|
|
59
|
+
for m in dvf["matches"]:
|
|
60
|
+
print(m["date_mutation"], m["valeur_fonciere"], "EUR à", m["distance_m"], "m")
|
|
61
|
+
print("Prix médian au m² :", dvf["dvf_median_price_per_m2"])
|
|
62
|
+
|
|
63
|
+
# Score d'opportunité marchand de biens v0.3 (note 0-100 et palier)
|
|
64
|
+
score = client.permits.score_mdb(num_pa)
|
|
65
|
+
print(f"Score : {score['score']}/100 ({score['tier']})")
|
|
66
|
+
# Score déjà pré-calculé : components vaut None ; le détail des 11 signaux
|
|
67
|
+
# est donné par la route /v1/permits/{num_pa}/score/explain.
|
|
68
|
+
|
|
69
|
+
# Zonage PLU (constructible, à urbaniser, agricole, naturel)
|
|
70
|
+
plu = client.permits.plu(num_pa)
|
|
71
|
+
if plu["has_plu"]:
|
|
72
|
+
z = plu["zonage"]
|
|
73
|
+
print(f"Zone {z['code']}, constructible : {z['constructible']}")
|
|
74
|
+
|
|
75
|
+
# Risques Géorisques (inondation, séisme, sites Seveso proches...)
|
|
76
|
+
risks = client.permits.risks(num_pa)
|
|
77
|
+
print(f"Risque : {risks['risk_score']}/100 ({risks['risk_tier']})")
|
|
78
|
+
for risk in risks["risks"]:
|
|
79
|
+
print(f"- {risk['label']} (PPR : {risk['has_ppr']})")
|
|
80
|
+
|
|
81
|
+
# Votre avis sur un score
|
|
82
|
+
client.permits.score_feedback(
|
|
83
|
+
num_pa=num_pa,
|
|
84
|
+
score_received=72,
|
|
85
|
+
tier_received="high",
|
|
86
|
+
useful=True,
|
|
87
|
+
accuracy="correct",
|
|
88
|
+
comment="Score cohérent avec notre analyse du quartier.",
|
|
89
|
+
)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Export CSV (Business et Enterprise)
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
# Plafond : 100 000 lignes en Business, 1 000 000 en Enterprise
|
|
96
|
+
csv_bytes = client.permits.export(
|
|
97
|
+
dep_code="75",
|
|
98
|
+
permit_type="PC_LOGEMENT",
|
|
99
|
+
date_from="2024-01-01",
|
|
100
|
+
max_rows=5000,
|
|
101
|
+
)
|
|
102
|
+
with open("paris.csv", "wb") as f:
|
|
103
|
+
f.write(csv_bytes)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Serveur MCP (Claude, ChatGPT, Cursor)
|
|
107
|
+
|
|
108
|
+
Le serveur MCP officiel (paquet séparé `permisapi-mcp`) permet à Claude, ChatGPT, Claude
|
|
109
|
+
Desktop, Cursor et Windsurf d'interroger PermisAPI en langage naturel :
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install permisapi-mcp
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Configurez votre clé dans le client MCP, puis demandez directement :
|
|
116
|
+
> *« Liste les permis de logement autorisés à Paris ce mois-ci »*
|
|
117
|
+
|
|
118
|
+
Mise en place complète : [permisapi.fr/mcp](https://permisapi.fr/mcp).
|
|
119
|
+
|
|
120
|
+
## Async
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
import asyncio
|
|
124
|
+
from permisapi_client import AsyncPermisAPI
|
|
125
|
+
|
|
126
|
+
async def main():
|
|
127
|
+
async with AsyncPermisAPI(api_key="pk_live_...") as client:
|
|
128
|
+
page = await client.permits.list(dep_code="75")
|
|
129
|
+
print(page["pagination"]["total"])
|
|
130
|
+
async for p in client.permits.iter_all(dep_code="75", permit_type="PC_LOGEMENT"):
|
|
131
|
+
print(p["num_pa"])
|
|
132
|
+
|
|
133
|
+
asyncio.run(main())
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Alertes par webhook
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
alert = client.alerts.create(
|
|
140
|
+
name="Paris 18e rénovations",
|
|
141
|
+
center_lat=48.88,
|
|
142
|
+
center_lng=2.35,
|
|
143
|
+
radius_km=3,
|
|
144
|
+
permit_types=["PC_LOGEMENT"],
|
|
145
|
+
webhook_url="https://votre-application.fr/permisapi-hook",
|
|
146
|
+
)
|
|
147
|
+
# Le webhook_secret n'est renvoyé qu'ICI : conservez-le pour vérifier les signatures HMAC.
|
|
148
|
+
print(alert["webhook_secret"])
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Gestion des erreurs
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from permisapi_client import (
|
|
155
|
+
PermisAPI,
|
|
156
|
+
PermisAPIRateLimited,
|
|
157
|
+
PermisAPIQuotaExceeded,
|
|
158
|
+
PermisAPIUnauthorized,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
client.permits.list(dep_code="75")
|
|
163
|
+
except PermisAPIUnauthorized:
|
|
164
|
+
print("Clé API invalide")
|
|
165
|
+
except PermisAPIQuotaExceeded:
|
|
166
|
+
print("Quota mensuel atteint : il se renouvelle le 1er du mois (UTC)")
|
|
167
|
+
except PermisAPIRateLimited as e:
|
|
168
|
+
print(f"Trop de requêtes par minute, nouvel essai possible dans {e.retry_after} s")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Licence
|
|
172
|
+
|
|
173
|
+
MIT. Source des permis : SDES, base Sitadel, data.gouv.fr (Licence Ouverte Etalab).
|
|
174
|
+
|
|
175
|
+
## Liens
|
|
176
|
+
|
|
177
|
+
- Documentation : https://permisapi.fr/docs
|
|
178
|
+
- Référence complète de l'API : https://api.permisapi.fr/docs
|
|
179
|
+
- Nouveautés : https://permisapi.fr/changelog
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
Usage sync :
|
|
4
4
|
from permisapi_client import PermisAPI
|
|
5
5
|
client = PermisAPI(api_key="pk_live_...")
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
page = client.permits.list(dep_code="75", limit=10)
|
|
7
|
+
for permit in page["data"]:
|
|
8
|
+
print(permit["num_pa"], permit["full_address"])
|
|
8
9
|
|
|
9
10
|
Usage async :
|
|
10
11
|
from permisapi_client import AsyncPermisAPI
|
|
@@ -30,4 +31,4 @@ __all__ = [
|
|
|
30
31
|
"PermisAPIValidationError",
|
|
31
32
|
]
|
|
32
33
|
|
|
33
|
-
__version__ = "0.8.
|
|
34
|
+
__version__ = "0.8.1"
|