#1 Wed 17 January 2024 09:17
- Tetranos
- Participant occasionnel
- Date d'inscription: 21 Sep 2020
- Messages: 16
API de téléchargement de la Geoplateforme et BDTOPO
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-geo … chargement
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/do … 15.7z.001.
S’agissant de fichiers volumineux (4Go), j'ai testé les différentes versions de code proposées ici : https://www.alixaprodev.com/download-la … -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/859x8t863h6a09o9o6fy … -15.7z.001) 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.
Hors ligne
#2 Wed 17 January 2024 15:09
- cquest
- Participant assidu
- Date d'inscription: 6 Jan 2013
- Messages: 874
Re: API de téléchargement de la Geoplateforme et BDTOPO
Je pense que ça n'a pas de rapport avec les entêtes qui n'ont que peu d'importance ici.
Je ne suis pas habitué à télécharger de gros fichiers avec python mais il me semble que c'est plutôt la façon de récupérer le fichier qui n'est pas cohérente entre le stream=True et l'utilisation de response.raw
Avec stream=True (qui est la bonne façon de télécharger un gros fichier), il faut ensuite avoir une boucle de réception qui va recevoir petit à petit le fichier et l'enregistrer au fur et à mesure sur disque.
Voir: https://realpython.com/python-download- … ng-fashion
subprocess c'est une façon d'utiliser depuis python des outils en ligne de commande comme curl ou wget pour télécharger le fichier, ce qui est moins portable. Je l'utilise assez souvent, mais du coup le code a souvent du mal à tourner sous Windows.
Christian Quest - https://amicale.net/@cquest sur Mastodon (terminé twitter/X)
Membre fondateur et porte parole d'OpenStreetMap France
Initiateur de opendatArchives, OpenEventDatabase, Panoramax
Hors ligne
#3 Wed 17 January 2024 15:31
- Tetranos
- Participant occasionnel
- Date d'inscription: 21 Sep 2020
- Messages: 16
Re: API de téléchargement de la Geoplateforme et BDTOPO
Bonjour Christian,
La version avec la boucle et le "chunk" est en effet également proposée dans le lien que j'ai cité.
J'ai même trouvé 2 déclinaisons, avec ou sans if (chunk) préalablement à l'appel au write : https://stackoverflow.com/questions/166 … h-requests
Mais cette solution donne sensiblement le même résultat :
Connection broken: InvalidChunkLength(got length b'', 0 bytes read)
C'est noté pour les headers, et pour le subprocess c'est bien pour cela que je voudrais éviter. Je crée une petite boîte à outils et j'aimerais pouvoir l'utiliser aussi bien sur mon poste (Windows) que sur le serveur de traitement auto (Linux).
Merci
Dernière modification par Tetranos (Wed 17 January 2024 15:33)
Hors ligne
#4 Wed 17 January 2024 16:03
- cquest
- Participant assidu
- Date d'inscription: 6 Jan 2013
- Messages: 874
Re: API de téléchargement de la Geoplateforme et BDTOPO
Plus léger avec urllib que requests:
Code:
from urllib.request import urlretrieve url = 'http://mirror.pnl.gov/releases/16.04.2/ubuntu-16.04.2-desktop-amd64.iso' dst = 'ubuntu-16.04.2-desktop-amd64.iso' urlretrieve(url, dst)
Christian Quest - https://amicale.net/@cquest sur Mastodon (terminé twitter/X)
Membre fondateur et porte parole d'OpenStreetMap France
Initiateur de opendatArchives, OpenEventDatabase, Panoramax
Hors ligne
#5 Wed 17 January 2024 16:12
- Tetranos
- Participant occasionnel
- Date d'inscription: 21 Sep 2020
- Messages: 16
Re: API de téléchargement de la Geoplateforme et BDTOPO
J'ai testé cette technique aussi mais ça bug pareil.
Hors ligne