TP done async/sync
This commit is contained in:
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -1,4 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Poetry (m01_tp01_asyncio)" />
|
||||||
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (m01_tp01_asyncio)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (m01_tp01_asyncio)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
@@ -74,21 +74,23 @@ async def download_and_save(
|
|||||||
url (str): l'URL de l'image à télécharger.
|
url (str): l'URL de l'image à télécharger.
|
||||||
output_dir (Path): le répertoire où sauvegarder l'image.
|
output_dir (Path): le répertoire où sauvegarder l'image.
|
||||||
"""
|
"""
|
||||||
# TODO : votre code ici. Similaire à la version synchrone, mais avec `async`/`await`.
|
filename = None
|
||||||
# 1. Utilisez un bloc `try...except` pour gérer les erreurs (ClientError, asyncio.TimeoutError, IOError).
|
try:
|
||||||
#
|
filename = url.split("/")[-1]
|
||||||
# 2. Dans le bloc `try` :
|
output_path = output_dir / filename
|
||||||
# a. Extrayez le nom du fichier et construisez le chemin de sauvegarde (comme avant).
|
logging.debug(f"Début du téléchargement -> {url}")
|
||||||
# b. Logguez le début du téléchargement.
|
async with session.get(url, timeout=30) as response:
|
||||||
# c. Utilisez `async with session.get(url) as response:` pour effectuer la requête.
|
response.raise_for_status()
|
||||||
# d. Vérifiez le statut de la réponse avec `response.raise_for_status()`.
|
content = await response.read()
|
||||||
# e. Lisez le contenu de la réponse de manière asynchrone : `data = await response.read()`.
|
logging.debug(f"Sauvegarde de {filename} sur {output_path}")
|
||||||
# f. Utilisez `async with aiofiles.open(path, "wb") as f:` pour ouvrir le fichier
|
async with aiofiles.open(output_path, "wb") as f:
|
||||||
# sans bloquer la boucle événementielle.
|
await f.write(content)
|
||||||
# g. Écrivez les données dans le fichier : `await f.write(data)`.
|
logging.info(f"Image {filename} sauvegardée !")
|
||||||
# h. Logguez la confirmation de la sauvegarde.
|
except ClientError as e:
|
||||||
#
|
logging.error(f"Erreur {url}: {e}")
|
||||||
# 3. Dans les blocs `except`, logguez les erreurs spécifiques.
|
except IOError as e:
|
||||||
|
file_ref = f"le fichier {filename}" if filename else "un fichier"
|
||||||
|
logging.error(f"Erreur d'écriture pour {file_ref}: {e}")
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
async def main() -> None:
|
||||||
@@ -103,19 +105,16 @@ async def main() -> None:
|
|||||||
|
|
||||||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
logging.info(f"Le répertoire de sortie est : {OUTPUT_DIR}")
|
logging.info(f"Le répertoire de sortie est : {OUTPUT_DIR}")
|
||||||
|
start_time = time.perf_counter()
|
||||||
# TODO : votre code ici. C'est ici que la magie de l'asynchronisme opère.
|
async with aiohttp.ClientSession() as session:
|
||||||
# 1. Créez une session client avec `async with aiohttp.ClientSession() as session:`.
|
tasks = [download_and_save(session, url, OUTPUT_DIR) for url in IMG_URLS]
|
||||||
#
|
await asyncio.gather(*tasks)
|
||||||
# 2. À l'intérieur du `async with`, créez une liste de "tâches". Chaque tâche
|
end_time = time.perf_counter()
|
||||||
# est un appel à votre coroutine `download_and_save`.
|
duration = end_time - start_time
|
||||||
# Astuce : une compréhension de liste est parfaite pour ça.
|
logging.info("-" * 40)
|
||||||
# Exemple : `tasks = [download_and_save(session, url, OUTPUT_DIR) for url in IMG_URLS]`
|
logging.info("Tous les téléchargements sont terminés !")
|
||||||
#
|
logging.info(f"Temps total d'exécution : {duration:.2f} secondes !")
|
||||||
# 3. Utilisez `asyncio.gather()` pour lancer toutes les tâches en parallèle et
|
logging.info("-" * 40)
|
||||||
# attendre qu'elles se terminent toutes.
|
|
||||||
# La syntaxe est : `await asyncio.gather(*tasks)`
|
|
||||||
# (L'étoile `*` dépaquette la liste de tâches en arguments pour `gather`).
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -64,25 +64,20 @@ def download_and_save(session: requests.Session, url: str, output_dir: Path) ->
|
|||||||
url (str): L'URL de l'image à télécharger.
|
url (str): L'URL de l'image à télécharger.
|
||||||
output_dir (Path): Le répertoire où sauvegarder l'image.
|
output_dir (Path): Le répertoire où sauvegarder l'image.
|
||||||
"""
|
"""
|
||||||
# TODO : votre code ici. Suivez ces étapes :
|
filename = None
|
||||||
# 1. Utilisez un bloc `try...except` pour gérer les erreurs potentielles
|
try:
|
||||||
# (RequestException, IOError).
|
filename = url.split("/")[-1]
|
||||||
#
|
output_path = output_dir / filename
|
||||||
# 2. Dans le bloc `try` :
|
response = session.get(url, timeout=30)
|
||||||
# a. Extrayez le nom du fichier à partir de l'URL.
|
response.raise_for_status()
|
||||||
# Astuce : `url.split("/")[-1]` est une méthode simple.
|
with open(output_path, "wb") as f:
|
||||||
# b. Construisez le chemin de sauvegarde complet en utilisant `pathlib`.
|
f.write(response.content)
|
||||||
# Exemple : `output_dir / nom_du_fichier`
|
logging.info(f"Image {filename} sauvegardée !")
|
||||||
# c. Logguez le début du téléchargement.
|
except RequestException as e:
|
||||||
# d. Effectuez une requête GET avec `session.get(url)`. Pensez à ajouter un timeout.
|
logging.error(f"Erreur {url}: {e}")
|
||||||
# e. Vérifiez que la requête a réussi avec `response.raise_for_status()`.
|
except IOError as e:
|
||||||
# f. Ouvrez le fichier de destination en mode écriture binaire ('wb')
|
file_ref = f"le fichier {filename}" if filename else "un fichier"
|
||||||
# en utilisant un `with open(...)`.
|
logging.error(f"Erreur d'écriture pour {file_ref}: {e}")
|
||||||
# g. Écrivez le contenu de la réponse (`response.content`) dans le fichier.
|
|
||||||
# h. Logguez la confirmation de la sauvegarde.
|
|
||||||
#
|
|
||||||
# 3. Dans les blocs `except`, logguez l'erreur de manière descriptive
|
|
||||||
# (ex: `logging.error(...)`).
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
@@ -100,20 +95,18 @@ def main() -> None:
|
|||||||
# `exist_ok=True` évite une erreur si le répertoire existe déjà.
|
# `exist_ok=True` évite une erreur si le répertoire existe déjà.
|
||||||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
logging.info(f"Le répertoire de sortie est : {OUTPUT_DIR}")
|
logging.info(f"Le répertoire de sortie est : {OUTPUT_DIR}")
|
||||||
|
|
||||||
start_time = time.perf_counter()
|
start_time = time.perf_counter()
|
||||||
|
with requests.Session() as session:
|
||||||
# TODO : votre code ici. Suivez ces étapes :
|
for url in IMG_URLS:
|
||||||
# 1. Utilisez un gestionnaire de contexte `with requests.Session() as session:`
|
logging.info(f"Téléchargement de {url}...")
|
||||||
# pour créer une session qui sera utilisée pour toutes les requêtes.
|
download_and_save(session, url, OUTPUT_DIR)
|
||||||
# Ceci optimise les connexions réseau.
|
end_time = time.perf_counter()
|
||||||
#
|
duration = end_time - start_time
|
||||||
# 2. À l'intérieur du `with`, faites une boucle `for` sur la liste `IMG_URLS`.
|
logging.info("-" * 40)
|
||||||
#
|
logging.info("Téléchargement terminé !")
|
||||||
# 3. Dans la boucle, appelez la fonction `download_and_save()` pour chaque URL,
|
logging.info(f"Temps total d'exécution : {duration:.2f} secondes !")
|
||||||
# en lui passant la session, l'URL et le répertoire de sortie.
|
logging.info("-" * 40)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user