{ "info": { "author": "Florian Wilhelm", "author_email": "florian.wilhelm@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Operating System :: Unix", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only", "Topic :: Utilities" ], "description": "[![ReadTheDocs](https://readthedocs.org/projects/border-patrol/badge/?version=latest)](https://border-patrol.readthedocs.io/en/latest/?badge=latest)\n[![Coveralls](https://img.shields.io/coveralls/github/pyscaffold/border-patrol/master.svg)](https://coveralls.io/r/pyscaffold/border-patrol)\n[![PyPI-Server](https://img.shields.io/pypi/v/border-patrol.svg)](https://pypi.org/project/border-patrol/)\n\n# Border-Patrol\n\nBorder-Patrol logs all imported packages and their version to support you while debugging. In 95% of all cases when\nsomething suddenly breaks in production it is due to some different version in one of your requirements. Pinning down the\nversions of all your dependencies and dependencies of dependencies inside a virtual environments helps you to overcome\nthis problem but is quite cumbersome and thus this method is not always applied in practice. Also sometimes, like when\nyou are using PySpark, you might not be 100% sure which library versions are installed on some cluster nodes.\n\nWith Border-Patrol you can easily find the culprit by looking in the logs of the last working versions and compare it\nto the failing one since Border-Patrol will list all imported packages and their corresponding version right at the\nend of your application, even if it crashed.\n\n\n## Usage\n\nBorder-Patrol is really simple to use, just install it with `pip install border-patrol`\nand import it before any other package, e.g.:\n```python\nfrom border_patrol import with_print_stdout\n\nimport pandas as pd\n```\nIf you run those lines in a script, you will get a similar output to this one:\n```console\nPython version is 3.6.7 |Anaconda, Inc.| (default, Oct 23 2018, 14:01:38)\n[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]\nFollowing packages were imported:\nPACKAGE VERSION PATH\nborder_patrol 0.1 /Users/fwilhelm/Sources/border_patrol/src/border_patrol\ncycler 0.10.0 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/cycler.py\ndateutil 2.7.5 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/dateutil/__init__.py\nmatplotlib 2.2.3 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/matplotlib/__init__.py\nnumpy 1.15.1 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/numpy/__init__.py\npandas 0.23.4 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/pandas/__init__.py\npyparsing 2.3.0 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/pyparsing.py\npytz 2018.7 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/pytz/__init__.py\nsix 1.11.0 /Users/fwilhelm/anaconda/envs/lib/python3.6/site-packages/six.py\n```\n\nIf you import `with_print_stdout`, Border-Patrol will use `print` as output function whereas `with_print_stderr` will\nprint to standard error. Since most production applications will rather use the `logging` module, you can tell\nBorder-Patrol to use it by importing `with_log_{error|warning|info|debug}`.\nFor instance `from border_patrol import with_log_info` will log the final report by using the `INFO` logging level.\n\nIf you want even more fine grained control you can import the `BorderPatrol` class directly from the `border_patrol` package\nand use the `register()` and `unregister()` method to activate and deactivate it, respectively. At any point the\ntracking can be circumvented by using `border_patrol.builtin_import`.\n\n\n## How does it work?\n\nBorder-Patrol is actually quite simple. It overwrites the `__import__` function in Python's `builtins` package to track\nevery imported module. For each module the corresponding package is determined and the version number is retrieved with\nthe help of the `__version__` attribute which most professional libraries provide at the package level. If this fails\nthe distribution name for the package is determined, e.g. `scikit-learn` is the distribution containing the `sklearn` package,\nwith the help of `pkg_resources` which is a part of `setuptools`. Then the distribution name is used to determine the\nversion number also using `pkg_resources`, similar to how `pip` would do it.\n\nFinally, Border-Patrol registers an `atexit` handler to be called when your application finishes and\nreports all imported modules. To avoid any problem registering these things more than once, Border-Patrol is implemented\nas a singleton and thus it is *not* thread-safe.\n\n\n## Note\n\nThis project has been set up using PyScaffold 3.1. For details and usage information on PyScaffold see https://pyscaffold.org/.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/pyscaffold/border-patrol", "keywords": "", "license": "mit", "maintainer": "", "maintainer_email": "", "name": "border-patrol", "package_url": "https://pypi.org/project/border-patrol/", "platform": "any", "project_url": "https://pypi.org/project/border-patrol/", "project_urls": { "Documentation": "https://border-patrol.readthedocs.io/", "Homepage": "https://github.com/pyscaffold/border-patrol" }, "release_url": "https://pypi.org/project/border-patrol/0.2/", "requires_dist": [ "pytest; extra == 'testing'", "pytest-cov; extra == 'testing'" ], "requires_python": ">=3.4", "summary": "Logs all imported packages and their version", "version": "0.2" }, "last_serial": 4665409, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "81b07044adf9e2328db91945792091c1", "sha256": "07b3ce719b3719bfda8e0a4dd11c6aa436c55fe84a6841337a8d5bd55b14eb9f" }, "downloads": -1, "filename": "border_patrol-0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "81b07044adf9e2328db91945792091c1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.4", "size": 7054, "upload_time": "2019-01-04T16:11:03", "url": "https://files.pythonhosted.org/packages/ef/ab/fb0c2417eb5a98bf55ba9c81867393223602f0e80ea5a1eff5ce6d72398b/border_patrol-0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2477b768bb5984f2839c0c5ff5cc7fe7", "sha256": "a14c15a89174e1d468d2b1f27553cdc4dfe54ba4c034b2f17b88128fd0f59a06" }, "downloads": -1, "filename": "border-patrol-0.1.tar.gz", "has_sig": false, "md5_digest": "2477b768bb5984f2839c0c5ff5cc7fe7", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 16767, "upload_time": "2019-01-04T16:11:05", "url": "https://files.pythonhosted.org/packages/09/e5/54bac6ebaec967a0acfb22ff1add7497a69a63226fd02e07138116c851dc/border-patrol-0.1.tar.gz" } ], "0.1rc2": [ { "comment_text": "", "digests": { "md5": "e36b641022767db415c7f82d113c363c", "sha256": "ebc34057e0dfe1a7374fedadd672921992af27096c9c9bc30d9cb179e9be01ab" }, "downloads": -1, "filename": "border_patrol-0.1rc2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e36b641022767db415c7f82d113c363c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.4", "size": 6911, "upload_time": "2019-01-02T15:21:20", "url": "https://files.pythonhosted.org/packages/7d/32/b0e132b33b9407b81df32598d9aabfcb89af81cd416e02c477a4230577fc/border_patrol-0.1rc2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "769afeb7b1e54261cd4859e9d4f843c4", "sha256": "7d364e638fb08d2ab656e06942ac8135aa730a64ee75693ffed0489f7da7beb1" }, "downloads": -1, "filename": "border-patrol-0.1rc2.tar.gz", "has_sig": false, "md5_digest": "769afeb7b1e54261cd4859e9d4f843c4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.4", "size": 13500, "upload_time": "2019-01-02T15:21:22", "url": "https://files.pythonhosted.org/packages/d1/17/8b776b1e835a100ad929a0eedceb5c0795c2d37e7c2911cb101ea2c65023/border-patrol-0.1rc2.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "ec680b9aedb1578cae57f1b95d9041d1", "sha256": "e4053b20dd0536d59d9d728ea167bdaa904b5dc17daa4f197c4c044efdc6b03c" }, "downloads": -1, "filename": "border_patrol-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ec680b9aedb1578cae57f1b95d9041d1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.4", "size": 7451, "upload_time": "2019-01-06T11:48:05", "url": "https://files.pythonhosted.org/packages/aa/a4/bc7418c219dd1178740a570ea56b211cd49491c6fe3e1a19a1225b570ef3/border_patrol-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "46b5cc143f622c49427761a95aebb832", "sha256": "489cf3852d509b5bfb6d44044911ff73b18944149f5fddc85435f1149655b7e4" }, "downloads": -1, "filename": "border-patrol-0.2.tar.gz", "has_sig": false, "md5_digest": "46b5cc143f622c49427761a95aebb832", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 17771, "upload_time": "2019-01-06T11:48:08", "url": "https://files.pythonhosted.org/packages/d0/34/832560b7fa4be381fd1cdeb3887bb986f07706bcfea43833fd8b56ded2f1/border-patrol-0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ec680b9aedb1578cae57f1b95d9041d1", "sha256": "e4053b20dd0536d59d9d728ea167bdaa904b5dc17daa4f197c4c044efdc6b03c" }, "downloads": -1, "filename": "border_patrol-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ec680b9aedb1578cae57f1b95d9041d1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.4", "size": 7451, "upload_time": "2019-01-06T11:48:05", "url": "https://files.pythonhosted.org/packages/aa/a4/bc7418c219dd1178740a570ea56b211cd49491c6fe3e1a19a1225b570ef3/border_patrol-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "46b5cc143f622c49427761a95aebb832", "sha256": "489cf3852d509b5bfb6d44044911ff73b18944149f5fddc85435f1149655b7e4" }, "downloads": -1, "filename": "border-patrol-0.2.tar.gz", "has_sig": false, "md5_digest": "46b5cc143f622c49427761a95aebb832", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.4", "size": 17771, "upload_time": "2019-01-06T11:48:08", "url": "https://files.pythonhosted.org/packages/d0/34/832560b7fa4be381fd1cdeb3887bb986f07706bcfea43833fd8b56ded2f1/border-patrol-0.2.tar.gz" } ] }