# `rootpath` [![PyPI version](https://badge.fury.io/py/rootpath.svg)](https://badge.fury.io/py/rootpath) [![Build Status](https://travis-ci.com/grimen/python-rootpath.svg?branch=master)](https://travis-ci.com/grimen/python-rootpath) [![Coverage Status](https://codecov.io/gh/grimen/python-rootpath/branch/master/graph/badge.svg)](https://codecov.io/gh/grimen/python-rootpath)
*Python project/package root path detection.*
## Introduction
Auto-magic project/package root path detection - from a child module file for Python libraries/projects.
It does this by detecting typical package/project root files/folders (e.g. `.git`, `requirements.txt`, etc.), but it can also be overriden easily if needed.
As a little bonus it exposes an optional helper for adding root path to the Python load path (`sys.path`) for resolving Python module import hell (which is terribly broken by design).
## Install
Install using **pip**:
```sh
pip install rootpath
```
## Use: Basic
Detect a project/package root path:
**1.** Assuming we have a **python** library/application project...
```
/home/me/projects
└── py-foo
└── foo
└── utils
└── __init__.py
└── baz.py
└── say.py
└── __init__.py
└── bar.py
README.md
requirements.txt
setup.py
```
`foo/bar.py` - top level package module
```python
import rootpath
def bar():
path = rootpath.detect()
assert path == '/home/me/projects/py-foo'
print('---')
print('FILE:', __file__)
print('ROOT:', path)
print('---')
if __name__ == '__main__':
bar()
```
`foo/utils/baz.py` - nested level package module (dependency)
```python
import rootpath
def baz():
path = rootpath.detect()
assert path == '/home/me/projects/py-foo'
print('---')
print('FILE:', __file__)
print('ROOT:', path)
print('---')
if __name__ == '__main__':
baz()
```
`foo/utils/say.py` - nested level package module (dependency)
```python
import rootpath
def say():
print('---')
print('SAY: {0}'.format(rootpath.detect()))
print('---')
if __name__ == '__main__':
say()
```
**2.** Let's run the files individually - they should both with successful assertions and output accurately detected root paths...
```sh
$ cd /home/me/projects/py-foo
$ python ./foo/bar.py
---
FILE: /home/me/projects/py-foo/foo/bar.py
ROOT: /home/me/projects/py-foo
---
$ python ./foo/utils/baz.py
---
FILE: /home/me/projects/py-foo/foo/utils/baz.py
ROOT: /home/me/projects/py-foo
---
$ python ./foo/utils/say.py
---
SAY: /home/me/projects/py-foo
---
```
## Use: Painless Python module imports
Using the above example code project as a reference, as and example to enable painless Python module imports:
**1.** Let's make use of the load path helper in the higher order modules...
`foo/bar.py`
```python
import rootpath
# 1. prepends root path to `sys.path`
rootpath.append()
# 2. will import correctly without errors no matter if imported/executed from same path or any other system path - which is not true for the native Python 3 relative import
import rootpath.utils.say as say
def bar():
say()
if __name__ == '__main__':
bar()
```
`foo/utils/baz.py`
```python
import rootpath
# 1. prepends root path to `sys.path`
rootpath.append()
# 2. will import correctly without errors no matter if imported/executed from same path or any other system path - which is not true for the native Python 3 relative import
import rootpath.utils.say as say
def baz():
hello()
if __name__ == '__main__':
baz()
```
**2.** Let's run the files individually - `say` module should be imported correctly without any errors from any module path namespace...
```sh
$ cd /home/me/projects/py-foo
$ python ./foo/bar.py
---
SAY: /home/me/projects/py-foo
---
$ python ./foo/utils/baz.py
---
SAY: /home/me/projects/py-foo
---
$ python ./foo/utils/say.py
---
SAY: /home/me/projects/py-foo
---
$ cd /home/me/projects/py-foo/foo
$ python ./bar.py
---
SAY: /home/me/projects/py-foo
---
$ python ./utils/baz.py
---
SAY: /home/me/projects/py-foo
---
$ python ./utils/say.py
---
SAY: /home/me/projects/py-foo
---
$ cd /home/me/projects/py-foo/foo/utils
$ python ./utils/baz.py
---
SAY: /home/me/projects/py-foo
---
$ python ./utils/say.py
---
SAY: /home/me/projects/py-foo
---
```
## About
This project was mainly initiated - in lack of well tested and reliable existing alternatives - to be used at our work at **[Markable.ai](https://markable.ai)** to have common code conventions between various programming environments where **Python** (research, CV, AI) is heavily used.
## License
Released under the MIT license.
Raw data
{
"_id": null,
"home_page": "https://github.com/grimen/python-rootpath",
"name": "rootpath",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "python,utlity,common,root,rootpath,root-path,detect,autodetect,auto-detect,project-root,project-root-path,package-root,package-root-path",
"author": "Jonas Grimfelt",
"author_email": "grimen@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/95/e0/b7876f1572456fac44210d53b30fe5250172d0300bed65ca23d577f7246c/rootpath-0.1.1.tar.gz",
"platform": "",
"description": "\n# `rootpath` [![PyPI version](https://badge.fury.io/py/rootpath.svg)](https://badge.fury.io/py/rootpath) [![Build Status](https://travis-ci.com/grimen/python-rootpath.svg?branch=master)](https://travis-ci.com/grimen/python-rootpath) [![Coverage Status](https://codecov.io/gh/grimen/python-rootpath/branch/master/graph/badge.svg)](https://codecov.io/gh/grimen/python-rootpath)\n\n*Python project/package root path detection.*\n\n\n## Introduction\n\nAuto-magic project/package root path detection - from a child module file for Python libraries/projects.\n\nIt does this by detecting typical package/project root files/folders (e.g. `.git`, `requirements.txt`, etc.), but it can also be overriden easily if needed.\n\nAs a little bonus it exposes an optional helper for adding root path to the Python load path (`sys.path`) for resolving Python module import hell (which is terribly broken by design).\n\n\n## Install\n\nInstall using **pip**:\n\n```sh\npip install rootpath\n```\n\n\n## Use: Basic\n\nDetect a project/package root path:\n\n**1.** Assuming we have a **python** library/application project...\n\n```\n/home/me/projects\n \u2514\u2500\u2500 py-foo\n \u2514\u2500\u2500 foo\n \u2514\u2500\u2500 utils\n \u2514\u2500\u2500 __init__.py\n \u2514\u2500\u2500 baz.py\n \u2514\u2500\u2500 say.py\n \u2514\u2500\u2500 __init__.py\n \u2514\u2500\u2500 bar.py\n README.md\n requirements.txt\n setup.py\n```\n\n`foo/bar.py` - top level package module\n\n```python\nimport rootpath\n\ndef bar():\n path = rootpath.detect()\n\n assert path == '/home/me/projects/py-foo'\n\n print('---')\n print('FILE:', __file__)\n print('ROOT:', path)\n print('---')\n\nif __name__ == '__main__':\n bar()\n```\n\n`foo/utils/baz.py` - nested level package module (dependency)\n\n```python\nimport rootpath\n\ndef baz():\n path = rootpath.detect()\n\n assert path == '/home/me/projects/py-foo'\n\n print('---')\n print('FILE:', __file__)\n print('ROOT:', path)\n print('---')\n\nif __name__ == '__main__':\n baz()\n```\n\n`foo/utils/say.py` - nested level package module (dependency)\n\n```python\nimport rootpath\n\ndef say():\n print('---')\n print('SAY: {0}'.format(rootpath.detect()))\n print('---')\n\nif __name__ == '__main__':\n say()\n```\n\n**2.** Let's run the files individually - they should both with successful assertions and output accurately detected root paths...\n\n```sh\n$ cd /home/me/projects/py-foo\n\n$ python ./foo/bar.py\n\n---\nFILE: /home/me/projects/py-foo/foo/bar.py\nROOT: /home/me/projects/py-foo\n---\n\n$ python ./foo/utils/baz.py\n\n---\nFILE: /home/me/projects/py-foo/foo/utils/baz.py\nROOT: /home/me/projects/py-foo\n---\n\n$ python ./foo/utils/say.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n\n```\n\n\n## Use: Painless Python module imports\n\nUsing the above example code project as a reference, as and example to enable painless Python module imports:\n\n**1.** Let's make use of the load path helper in the higher order modules...\n\n`foo/bar.py`\n\n```python\nimport rootpath\n\n# 1. prepends root path to `sys.path`\nrootpath.append()\n\n# 2. will import correctly without errors no matter if imported/executed from same path or any other system path - which is not true for the native Python 3 relative import\nimport rootpath.utils.say as say\n\ndef bar():\n say()\n\nif __name__ == '__main__':\n bar()\n```\n\n`foo/utils/baz.py`\n\n```python\nimport rootpath\n\n# 1. prepends root path to `sys.path`\nrootpath.append()\n\n# 2. will import correctly without errors no matter if imported/executed from same path or any other system path - which is not true for the native Python 3 relative import\nimport rootpath.utils.say as say\n\ndef baz():\n hello()\n\nif __name__ == '__main__':\n baz()\n```\n\n**2.** Let's run the files individually - `say` module should be imported correctly without any errors from any module path namespace...\n\n```sh\n$ cd /home/me/projects/py-foo\n\n$ python ./foo/bar.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ python ./foo/utils/baz.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ python ./foo/utils/say.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ cd /home/me/projects/py-foo/foo\n\n$ python ./bar.py\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ python ./utils/baz.py\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ python ./utils/say.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ cd /home/me/projects/py-foo/foo/utils\n\n$ python ./utils/baz.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n\n$ python ./utils/say.py\n\n---\nSAY: /home/me/projects/py-foo\n---\n```\n\n\n## About\n\nThis project was mainly initiated - in lack of well tested and reliable existing alternatives - to be used at our work at **[Markable.ai](https://markable.ai)** to have common code conventions between various programming environments where **Python** (research, CV, AI) is heavily used.\n\n\n## License\n\nReleased under the MIT license.\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python project/package root path detection.",
"version": "0.1.1",
"split_keywords": [
"python",
"utlity",
"common",
"root",
"rootpath",
"root-path",
"detect",
"autodetect",
"auto-detect",
"project-root",
"project-root-path",
"package-root",
"package-root-path"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "a915f6a6607c80f73ddd7706b505c384",
"sha256": "98f417747b3e25d2ad1e94a555d7562b48f642cbdf993dabc61259170720ed45"
},
"downloads": -1,
"filename": "rootpath-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a915f6a6607c80f73ddd7706b505c384",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 15176,
"upload_time": "2019-03-10T11:21:07",
"upload_time_iso_8601": "2019-03-10T11:21:07.826335Z",
"url": "https://files.pythonhosted.org/packages/4f/f9/959835686c78b7a95d8d806a97fa0be020c2deccb96de2b60659744319b9/rootpath-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "316a106b7644b562ad3175397f4e327c",
"sha256": "ecc3f9de280ff11c6ade0e956229e4dcb74c1ead5efde8579ba721e6459c518f"
},
"downloads": -1,
"filename": "rootpath-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "316a106b7644b562ad3175397f4e327c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12191,
"upload_time": "2019-03-10T11:21:09",
"upload_time_iso_8601": "2019-03-10T11:21:09.266888Z",
"url": "https://files.pythonhosted.org/packages/95/e0/b7876f1572456fac44210d53b30fe5250172d0300bed65ca23d577f7246c/rootpath-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2019-03-10 11:21:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "grimen",
"github_project": "python-rootpath",
"travis_ci": true,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "setupextras",
"specs": [
[
">=",
"0.1.5"
]
]
},
{
"name": "six",
"specs": [
[
">=",
"1.11.0"
]
]
},
{
"name": "coloredlogs",
"specs": [
[
">=",
"10.0"
]
]
},
{
"name": "termcolor",
"specs": [
[
">=",
"1.1.0"
]
]
},
{
"name": "colour-runner",
"specs": [
[
">=",
"0.0.5"
]
]
},
{
"name": "deepdiff",
"specs": [
[
">=",
"3.3.0"
]
]
},
{
"name": "pygments",
"specs": [
[
">=",
"2.2.0"
]
]
},
{
"name": "tox",
"specs": [
[
">=",
"3.0.0"
]
]
},
{
"name": "coverage",
"specs": [
[
">=",
"4.5.2"
]
]
},
{
"name": "codecov",
"specs": [
[
">=",
"2.0.15"
]
]
}
],
"tox": true,
"lcname": "rootpath"
}