{"id":16539619,"url":"https://github.com/xuhdev/poorconn","last_synced_at":"2025-08-17T03:42:12.827Z","repository":{"id":141612542,"uuid":"372396822","full_name":"xuhdev/poorconn","owner":"xuhdev","description":"A Python package that simulates poor network conditions. It is suitable for testing purposes, for both Python and non-Python projects. Mirror of https://gitlab.com/xuhdev/poorconn","archived":false,"fork":false,"pushed_at":"2021-06-14T05:31:45.000Z","size":129,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-25T02:19:06.326Z","etag":null,"topics":["ci","pytest","python","testing"],"latest_commit_sha":null,"homepage":"https://poorconn.topbug.net/","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xuhdev.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING.rst","funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-31T05:52:48.000Z","updated_at":"2021-06-14T05:18:29.000Z","dependencies_parsed_at":"2023-04-19T18:02:04.483Z","dependency_job_id":null,"html_url":"https://github.com/xuhdev/poorconn","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/xuhdev/poorconn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuhdev%2Fpoorconn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuhdev%2Fpoorconn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuhdev%2Fpoorconn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuhdev%2Fpoorconn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xuhdev","download_url":"https://codeload.github.com/xuhdev/poorconn/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xuhdev%2Fpoorconn/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270803531,"owners_count":24648688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci","pytest","python","testing"],"created_at":"2024-10-11T18:49:49.697Z","updated_at":"2025-08-17T03:42:12.793Z","avatar_url":"https://github.com/xuhdev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. readme-roles\n\n.. role:: doc(literal)\n.. role:: func(literal)\n.. role:: mod(literal)\n\n.. readme-main\n\nPoorconn: Simulating Poor Network Conditions\n============================================\n\n.. image:: https://img.shields.io/pypi/v/poorconn.svg\n   :target: https://pypi.python.org/pypi/poorconn\n   :alt: PyPI\n\n.. image:: https://img.shields.io/pypi/pyversions/poorconn.svg\n   :target: https://pypi.python.org/pypi/poorconn\n   :alt: PyPI - Python Versions\n\n.. image:: https://img.shields.io/pypi/implementation/poorconn\n   :target: https://pypi.python.org/pypi/poorconn\n   :alt: PyPI - Implementation\n\n.. image:: https://img.shields.io/badge/-Documentation-informational\n   :target: https://poorconn.topbug.net\n   :alt: Documentation\n\n.. image:: https://img.shields.io/pypi/l/poorconn\n   :target: https://gitlab.com/xuhdev/poorconn/-/blob/master/COPYING\n   :alt: PyPI - License\n\n.. image:: https://gitlab.com/xuhdev/poorconn/badges/master/pipeline.svg\n   :target: https://gitlab.com/xuhdev/poorconn/-/commits/master\n   :alt: Pipeline Status\n\n.. image:: https://gitlab.com/xuhdev/poorconn/badges/master/coverage.svg\n   :target: https://gitlab.com/xuhdev/poorconn/-/commits/master\n   :alt: Coverage\n\nPoorconn is a Python package that simulates poor network conditions. It is suitable for testing purposes, for both\nPython and non-Python projects.\n\nIt is capable of simulating the following poor network conditions:\n\n- Throttled network connections. (:func:`delay_before_sending`, :func:`delay_before_sending_upon_acceptance`)\n- Servers that cut off connections immediately upon accepting them. (:func:`close_upon_acceptance`)\n- Connections that are initially slow, but become normal subsequently. (:func:`delay_before_sending_once`,\n  :func:`delay_before_sending_upon_acceptance_once`)\n\n\n.. _quickstart:\n\nQuickstart\n----------\n\nInstall this package via\n\n.. code-block:: console\n\n   $ pip install 'poorconn[full]'  # or \"pip install poorconn\" if you don't need pytest support\n\nCommand Line Usage\n~~~~~~~~~~~~~~~~~~\n\nThe following example starts a local HTTP server at port 8000 that hosts static files at the current working directory.\nIt always closes connections upon accepting them:\n\n.. code-block:: console\n\n   $ python -m poorconn -H localhost -p 8000 close_upon_acceptance\n\nIn this command, ``python -m poorconn`` invokes Poorconn's command line entrypoint, ``-H localhost`` specifies\nthe hostname, ``-p 8000`` specifies the port number, and ``close_upon_acceptance`` is a *simulation command* that\nsimulates a specific poor network conditions, which in this case is closing connections upon accepting them.\n\nAfter running the command above, connections from a client would establish but fail to communicate subsequently:\n\n.. code-block:: console\n\n   $ wget -t 1 http://127.0.0.1:8000\n   Connecting to 127.0.0.1:8000... connected.\n   HTTP request sent, awaiting response... No data received.\n   Giving up.\n\nFor another example, to start a local HTTP server that always throttle connections upon accepting them, simply replace\n``close_upon_acceptance`` above with ``delay_before_sending_upon_acceptance --t=1 --length=1024``:\n\n.. code-block:: console\n\n   $ python -m poorconn delay_before_sending_upon_acceptance --t=1 --length=1024\n\nHere, ``-H localhost -p 8000`` is omitted because it's Poorconn's default host and port settings. In this command,\n:func:`poorconn.delay_before_sending_upon_acceptance` delays roughly 1 seconds for every 1024 bytes sent. The connection\nis now throttled:\n\n.. code-block:: console\n\n   $ wget http://127.0.0.1:8000\n   Connecting to 127.0.0.1:8000... connected.\n   HTTP request sent, awaiting response... 200 OK\n   Length: 1609 (1.6K) [text/html]\n   Saving to: 'index.html'\n\n   index.html    1.57K   804 B/s    in 2.0s  \u003c====== NOTE the time\n\n   'index.html' saved [1609/1609]\n\n(Output above is abridged.)\n\nRun ``python -m poorconn -h`` to view the help message and see the `poorconn module API references\n\u003chttps://poorconn.topbug.net/apis/poorconn.html\u003e`__ for a list of simulation functions (which share the same names with\nsimulation commands).\n\nDocker Image\n~~~~~~~~~~~~\n\nYou can also run Poorconn as a command line tool using our\n`Docker image \u003chttps://gitlab.com/xuhdev/poorconn/container_registry/1996648\u003e`__ by replacing ``python -m poorconn``\nwith ``docker run registry.gitlab.com/xuhdev/poorconn``. For instance, the following achieves the same effect as the\nsecond command line example above:\n\n.. code-block:: console\n\n   $ docker run -p 8000:8000 registry.gitlab.com/xuhdev/poorconn delay_before_sending_upon_acceptance --t=1 --length=1024\n\nUsage in Python\n~~~~~~~~~~~~~~~\n\nRunning the following Python script achieves the same effects as the first command line example above:\n\n.. code-block:: python\n\n   from http.server import HTTPServer, SimpleHTTPRequestHandler\n   from poorconn import close_upon_acceptance, make_socket_patchable\n\n   # Start a local HTTP server that always closes connections upon established\n   with HTTPServer((\"localhost\", 8000), SimpleHTTPRequestHandler) as httpd:\n       httpd.socket = make_socket_patchable(httpd.socket)\n       close_upon_acceptance(httpd.socket)\n       httpd.serve_forever()\n\nThe code snippet above is very similar to that runs a basic http server in Python, except that the socket object\n``httpd.socket`` is patched by :func:`poorconn.close_upon_acceptance` before http server is running.\n\nFor the second command line example above, simply replace\n``close_upon_acceptance(s)`` above with ``delay_before_sending_upon_acceptance(s, t=1, length=1024)`` and adjust\nimports.\n\nIntegration with Pytest\n~~~~~~~~~~~~~~~~~~~~~~~\n\nIf you use `pytest`_, you can also take advantage of poorconn fixtures in :mod:`poorconn.pytest_plugin`. The following\nexample gets you started with testing against a slow HTTP server:\n\n.. code-block:: python\n\n   pytest_plugins = ('poorconn',)\n\n   from pathlib import Path\n   import time\n   import requests\n   import pytest\n\n   @pytest.mark.poorconn_http_server_config(t=2, length=1024)\n   def test_slow_http_server(poorconn_http_server, tmp_path):\n       \"Test GETing from a slow local http server that delays 2 seconds to send every 1024 bytes.\"\n       (tmp_path / 'index.txt').write_bytes(b'h' * 1024)\n       starting_time = time.time()\n       # Replace the following line with the program you want to test\n       content = requests.get(f'{poorconn_http_server.url}/index.txt').content\n       ending_time = time.time()\n       assert ending_time - starting_time \u003e 2\n\n.. readme-misc\n\nBug Reports and Feature Requests\n--------------------------------\n\nPlease open a ticket on the `GitLab Issue Tracker \u003chttps://gitlab.com/xuhdev/poorconn/-/issues\u003e`__.\n\nContributing\n------------\n\nContributions are welcome! To get started, check out :doc:`CONTRIBUTING`.\n\nCopyright and License\n---------------------\n\nUnless otherwise stated in the headers of some files, all files in this project are licensed under LGPLv3+:\n\nCopyright (C) 2020--2021 Hong Xu \u003chong@topbug.net\u003e\n\nThis program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General\nPublic License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any\nlater version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\nwarranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Lesser General Public License along with this program. If not, see\n\u003chttps://www.gnu.org/licenses/\u003e.\n\n.. _pytest: https://www.pytest.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxuhdev%2Fpoorconn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxuhdev%2Fpoorconn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxuhdev%2Fpoorconn/lists"}