Message posté par : Michaël G
----------------------------------------
Bonjour à tous,
Je travaille actuellement à l'automatisation du téléchargement du dernier millésime de
la BDTOPO France métropolitaine au format SQL.
J'utilise pour cela l'API de téléchargement dont la documentation est disponible
au lien ci-après et je développe en Python :
https://geoservices.ign.fr/services-geoplateforme-telechargement
Grâce à l'API, j'arrive à lister les produits, les différents jeux de données
(millésimes) de chacun des produits puis sur un jeu de données spécifique, je parviens à
lister les fichiers associés.
Le problème se pose au moment du téléchargement, par exemple avec cette URL :
https://data.geopf.fr/telechargement/download/BDTOPO/BDTOPO_3-3_TOUSTHEMES_….
S’agissant de fichiers volumineux (4Go), j'ai testé les différentes versions de code
proposées ici :
https://www.alixaprodev.com/download-large-file-in-python-with-requests/
pour ne pas avoir à monter tout le fichier en RAM.
Après lancement du téléchargement, l'erreur suivante se produit : Connection broken:
IncompleteRead(62905 bytes read)
J'ai fait différents tests pour tenter de comprendre d'où pouvait venir le
problème mais n'ai pas encore trouvé de solutions.
Test 1 : le téléchargement du fichier via Firefox fonctionne.
Test 2 : le téléchargement par code Python du fichier ne fonctionne pas que je sois sur
mon réseau perso ou d'entreprise.
Test 3 : le téléchargement par code Python d'un plus petit fichier (par exemple la
BDTOPO en GPKG d'un département) fonctionne.
Test 4 : le téléchargement par code Python d'un fichier volumineux sur un autre site
(une distribution Linux de 4Go) fonctionne.
Test 5 : le téléchargement par code Python de la BDTOPO via les anciennes URL
(
https://wxs.ign.fr/859x8t863h6a09o9o6fy4v60/telechargement/prepackage/BDTOP…)
fonctionne.
Test 6 : l'utilisation de requests.post au lieu de requests.get ne fonctionne pas car
le service ne l'autorise pas.
Je n'y connais pas grand chose en protocole HTTP, mais je remarque que les headers qui
sont renvoyées sont différents entre les anciennes et les nouvelles URL.
L'ancienne URL indique un content-type à "application/octet-stream" et donne
le content-length. La nouvelle URL indique un content-type en "application/json"
ainsi que content-disposition à "attachment;
filename="BDTOPO_3-3_TOUSTHEMES_SQL_LAMB93_FXX_2023-09-15.7z.001" mais
n'indique pas de content-length.
En fait, j'ai l'impression que la connexion se coupe avant la fin du
téléchargement du fichier. Peut-être faut-il que j'ajoute des entêtes dans la requête
HTTP d'appel...
Voici la fonction :
-----------------
Code :
def download_file(url: str, file_path: str, verify_ssl = True):
"""
Télécharge un fichier par bloc.
Si le fichier existe localement, il est écrasé.
url : L'URL du fichier à télécharger.
file_path : Le chemin d'enregistrement du fichier.
verify_ssl : Vrai pour activer la vérification SSL, faux sinon.
"""
with requests.get(url, stream = True, verify = verify_ssl) as response:
response.raise_for_status()
for key, value in response.headers.items():
print(key, "=", value)
with open(file_path, 'wb') as file:
shutil.copyfileobj(response.raw, file)
-----------------
Et un exemple d'appel :
-----------------
Code :
download_file("https://data.geopf.fr/telechargement/download/BDTOPO/BDTOPO_3-3_TOUSTHEMES_SQL_LAMB93_FXX_2023-09-15/BDTOPO_3-3_TOUSTHEMES_SQL_LAMB93_FXX_2023-09-15.7z.001",
"c:/temp/BDTOPO.7z")
-----------------
Merci de votre aide.
PS : j'ai également publié cette même question sur la communauté Géoplateforme
OSMOSE.
PPS : j'ai trouvé sur un site un message de quelqu'un qui avait un problème
similaire et qui à contourner en utilisant curl via un subprocess...ce que je préfèrerais
éviter.
----------------------------------------
Le message est situé
https://georezo.net/forum/viewtopic.php?pid=365033#p365033
Pour y répondre : donnees(a)ml.georezo.net ou reply de votre messagerie
Pour vous désabonner connectez-vous sur le forum puis Profil / Abonnement
--
Association GeoRezo - le portail géomatique
https://georezo.net