{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Estimation de la latence et de la capacité d’une connexion à partir de mesures asymétriques" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ce document correspond au Sujet 4 du module 3 du MOOC \"Recherche reproductible : principes méthodologiques pour une science transparente\".\n", "\n", "On s'intéresse à comparer un modèle simple de la performance d'une connexion de réseau avec des données réelles." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "import os\n", "from os.path import exists\n", "import requests\n", "import gzip" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Téléchargement des données" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "filenames = [\n", " \"liglab2.log\", \n", " \"stackoverflow.log\",\n", "]\n", "urls = [\n", " \"http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.log.gz\",\n", " \"http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/stackoverflow.log.gz\",\n", "]" ] }, { "cell_type": "raw", "metadata": { "hideOutput": true }, "source": [ "# Facultatif : suppression des fichiers pour forcer le re-téléchargement\n", "for filename in filenames:\n", " try:\n", " os.remove(filename)\n", " except FileNotFoundError:\n", " pass" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Le fichier liglab2.log existe déjà, pas besoin de le télécharger.\n", "Le fichier stackoverflow.log existe déjà, pas besoin de le télécharger.\n" ] } ], "source": [ "# Si les fichiers n'existent pas encore, on les télécharge.\n", "\n", "def download_archive(filename, url):\n", " if not exists(filename):\n", " # Le fichier est une archive .gz\n", " archive = requests.get(url)\n", " content = gzip.decompress(archive.content)\n", " open(filename,'wb').write(content)\n", " print(f\"Téléchargement de {url} et extraction vers {filename}.\")\n", " else:\n", " print(f\"Le fichier {filename} existe déjà, pas besoin de le télécharger.\")\n", "\n", "\n", "for filename, url in zip(filenames, urls):\n", " download_archive(filename, url)\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on Response in module requests.models object:\n", "\n", "class Response(builtins.object)\n", " | The :class:`Response ` object, which contains a\n", " | server's response to an HTTP request.\n", " | \n", " | Methods defined here:\n", " | \n", " | __bool__(self)\n", " | Returns True if :attr:`status_code` is less than 400.\n", " | \n", " | This attribute checks if the status code of the response is between\n", " | 400 and 600 to see if there was a client error or a server error. If\n", " | the status code, is between 200 and 400, this will return True. This\n", " | is **not** a check to see if the response code is ``200 OK``.\n", " | \n", " | __enter__(self)\n", " | \n", " | __exit__(self, *args)\n", " | \n", " | __getstate__(self)\n", " | \n", " | __init__(self)\n", " | Initialize self. See help(type(self)) for accurate signature.\n", " | \n", " | __iter__(self)\n", " | Allows you to use a response as an iterator.\n", " | \n", " | __nonzero__(self)\n", " | Returns True if :attr:`status_code` is less than 400.\n", " | \n", " | This attribute checks if the status code of the response is between\n", " | 400 and 600 to see if there was a client error or a server error. If\n", " | the status code, is between 200 and 400, this will return True. This\n", " | is **not** a check to see if the response code is ``200 OK``.\n", " | \n", " | __repr__(self)\n", " | Return repr(self).\n", " | \n", " | __setstate__(self, state)\n", " | \n", " | close(self)\n", " | Releases the connection back to the pool. Once this method has been\n", " | called the underlying ``raw`` object must not be accessed again.\n", " | \n", " | *Note: Should not normally need to be called explicitly.*\n", " | \n", " | iter_content(self, chunk_size=1, decode_unicode=False)\n", " | Iterates over the response data. When stream=True is set on the\n", " | request, this avoids reading the content at once into memory for\n", " | large responses. The chunk size is the number of bytes it should\n", " | read into memory. This is not necessarily the length of each item\n", " | returned as decoding can take place.\n", " | \n", " | chunk_size must be of type int or None. A value of None will\n", " | function differently depending on the value of `stream`.\n", " | stream=True will read data as it arrives in whatever size the\n", " | chunks are received. If stream=False, data is returned as\n", " | a single chunk.\n", " | \n", " | If decode_unicode is True, content will be decoded using the best\n", " | available encoding based on the response.\n", " | \n", " | iter_lines(self, chunk_size=512, decode_unicode=False, delimiter=None)\n", " | Iterates over the response data, one line at a time. When\n", " | stream=True is set on the request, this avoids reading the\n", " | content at once into memory for large responses.\n", " | \n", " | .. note:: This method is not reentrant safe.\n", " | \n", " | json(self, **kwargs)\n", " | Returns the json-encoded content of a response, if any.\n", " | \n", " | :param \\*\\*kwargs: Optional arguments that ``json.loads`` takes.\n", " | :raises ValueError: If the response body does not contain valid json.\n", " | \n", " | raise_for_status(self)\n", " | Raises stored :class:`HTTPError`, if one occurred.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data descriptors defined here:\n", " | \n", " | __dict__\n", " | dictionary for instance variables (if defined)\n", " | \n", " | __weakref__\n", " | list of weak references to the object (if defined)\n", " | \n", " | apparent_encoding\n", " | The apparent encoding, provided by the chardet library.\n", " | \n", " | content\n", " | Content of the response, in bytes.\n", " | \n", " | is_permanent_redirect\n", " | True if this Response one of the permanent versions of redirect.\n", " | \n", " | is_redirect\n", " | True if this Response is a well-formed HTTP redirect that could have\n", " | been processed automatically (by :meth:`Session.resolve_redirects`).\n", " | \n", " | links\n", " | Returns the parsed header links of the response, if any.\n", " | \n", " | next\n", " | Returns a PreparedRequest for the next request in a redirect chain, if there is one.\n", " | \n", " | ok\n", " | Returns True if :attr:`status_code` is less than 400, False if not.\n", " | \n", " | This attribute checks if the status code of the response is between\n", " | 400 and 600 to see if there was a client error or a server error. If\n", " | the status code is between 200 and 400, this will return True. This\n", " | is **not** a check to see if the response code is ``200 OK``.\n", " | \n", " | text\n", " | Content of the response, in unicode.\n", " | \n", " | If Response.encoding is None, encoding will be guessed using\n", " | ``chardet``.\n", " | \n", " | The encoding of the response content is determined based solely on HTTP\n", " | headers, following RFC 2616 to the letter. If you can take advantage of\n", " | non-HTTP knowledge to make a better guess at the encoding, you should\n", " | set ``r.encoding`` appropriately before accessing this property.\n", " | \n", " | ----------------------------------------------------------------------\n", " | Data and other attributes defined here:\n", " | \n", " | __attrs__ = ['_content', 'status_code', 'headers', 'url', 'history', '...\n", "\n" ] } ], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }