slushie


Nameslushie JSON
Version 0.2.4 PyPI version JSON
download
home_pagehttps://github.com/saleguas/slushie
SummarySlushie: A Python library for relative path manipulation.
upload_time2023-11-19 23:20:18
maintainer
docs_urlNone
authorSalvador Aleguas
requires_python>=3
licenseMIT
keywords path sys-path manipulation python-path module-path
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Slushie 🍧

🍭 Ever wanted to just get a file from a sibling or parent directory without pulling your hair out? Slushie is the perfect "it just works" solution to relative paths in Python.

<!-- include media/slushie.gif -->

![Slushie Demo](media/slushie.gif)

## Table of Contents

- [❔ Why Slushie?](#-why-slushie)
- [πŸš€ Installation](#-installation)
- [🌈 Usage](#-usage)
- [πŸ”¬ Running Tests](#-running-tests)
- [🀝 Contributing](#-contributing)
- [πŸ“œ License](#-license)

## ❔ Why Slushie?

Relative paths and imports in Python are an absolute nightmare due to how `PYTHONPATH` works and finds modules.

For example, 
```
project_root/
β”‚   main.py
β”‚
β”œβ”€β”€β”€package1/
β”‚   β”‚   module1.py
β”‚   β”‚   file.csv
β”‚   β”‚
β”‚   └───subpackage1/
β”‚       β”‚   module2.py
```

If I wanted to import `module1.py` from `main.py`, you'd think it would be something like the following:

```
from package1 import module1
from package1.subpackage1 import module2
```

<!-- bold -->

**This (most likely) will not work. Why?**

Python relies on the dreaded `PYTHONPATH` environment variable to determine where to look for modules to import. 

`PYTHONPATH` is a list of directories that Python checks whenever you attempt an import. If `package1` and `subpackage1` are not included in the `PYTHONPATH`, Python doesn’t know where to look for `module1.py`, and `module2.py`, resulting in an `ImportError`.

Additionally, attempting to open `file.csv`, using the traditional open command like this:

```
open("package1/file.csv")
```

will most likely not even find the file, and even if it does, there's a high chance it will break if it is ever moved to another machine or ran from a different directory.

This is because the search for `file.csv` is relative to the current working directory where the Python script is executed, not necessarily where main.py is located.

**TL;DR: If you use python's default import and open commands, you either have to do some Python witchcraft or risk randomly breaking your code.**

## πŸš€ Installation

Install it directly from PyPI:

```
pip install slushie
```

## 🌈 Usage


### sip(*parts: str) -> str

**Purpose**: Create absolute paths relative to the current FILE. Ideal for accessing files in parent or sibling directories without a fuss.

#### Parameters:
- `*parts: str` - Parts of the path to join.

#### Usage:
Access `hello.txt` located in a sibling directory from `script.py`.

```
/project
    /folder1
        script.py
    /folder2
        hello.txt
```

```python
path = sip('..', 'folder2', 'hello.txt')
print(path)

# Output:
# /path/to/project/folder2/hello.txt
# In this case, sip('.') refers to /path/to/project/folder1/
```

The above code is fundamentally equivalent to the following:

```python
import os
import sys

path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'folder2', 'hello.txt')
print(path)

# Output:
# /path/to/project/folder2/hello.txt
```

This is extremely useful, as if you ever need to open a file, such as a csv for data analysis or a text file for logging, you should almost always be using relative paths as to avoid breaking your code when you move it to a different machine or share it with someone else. Slushie makes this easy.

```python
### gulp(directory: str = '.') -> Iterator[None]

**Purpose**: Temporarily include directories in the Python path, easing the import of modules/packages.

#### Parameters:
- `directory: str` - Directory to add directories from.

#### Usage:
Import a module from a sibling directory.

```python
with gulp('../sibling_directory'):
    import a_module_from_sibling_directory
```

### freeze(path: str) -> None

**Purpose**: Make a specific directory permanently available for imports.

#### Parameters:
- `path: str` - Path to append to `sys.path`.

#### Usage:
```python
freeze('../another_directory')
import a_module_from_another_directory
```

### pour(directory: str = '.') -> Iterator[Tuple[str, str]]

**Purpose**: Easily access the current and parent directory paths of the current file the code is being written in.

#### Parameters:
- `directory: str` - Directory to get paths for.

#### Usage:
```python
with pour() as (current_dir, parent_dir):
    print(f"Current Directory: {current_dir}")
    print(f"Parent Directory: {parent_dir}")
```

### melt() -> str

**Purpose**: Find the directory of the calling script, aiding in understanding the execution context.

#### Usage:
```python
caller_path = melt()
print(f"Caller Path: {caller_path}")

# Output:
# Caller Path: /path/to/calling/script.py
# This is the path of the script that called melt(), not the path of melt() itself.
# So if I had script /path/to/calling/script.py that called melt(), and melt() was located at /path/to/melt.py, the output would still be:
# Caller Path: /path/to/calling/script.py
```


### slurp() -> str

**Purpose**: Identify where the terminal command was executed from.

#### Usage:
```python
terminal_path = slurp()
print(f"Terminal Path: {terminal_path}")

# So if the script was located at /path/to/script.py and the terminal command was executed from /path/to, the output would be:
# Terminal Path: /path/to
```

### scoop(file: str, mode: str = 'r', ...) -> TextIO

**Purpose**: Simplify opening files by managing paths relative to the current script automatically.

#### Parameters:
Literally the same as the built-in `open()` function. It's just a wrapper around it that automatically manages paths relative to the current script.


#### Usage:
```python
with scoop('../data.txt', 'r') as file:
    data = file.read()
    print(data)
```

## πŸ”¬ Running Tests

Keeping Slushie frosty with some cool tests:

- **For Linux:**
  ```
  ./run_tests.sh
  ```

- **For Windows:**
  ```
  run_tests.bat
  ```

## 🀝 Contributing

Contribute your own flavors to make Slushie even more delightful! 🌈

## πŸ“œ License

Slushie is lovingly served under the MIT License. Scoop into the [LICENSE](LICENSE) file for the full details.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/saleguas/slushie",
    "name": "slushie",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3",
    "maintainer_email": "",
    "keywords": "path sys-path manipulation python-path module-path",
    "author": "Salvador Aleguas",
    "author_email": "salvadoraleguas@example.com",
    "download_url": "https://files.pythonhosted.org/packages/5a/ae/bb554bb42dd7c85e8443344f32f12198e5fcb527119f9d40289c71e17936/slushie-0.2.4.tar.gz",
    "platform": null,
    "description": "# Slushie \ud83c\udf67\r\n\r\n\ud83c\udf6d Ever wanted to just get a file from a sibling or parent directory without pulling your hair out? Slushie is the perfect \"it just works\" solution to relative paths in Python.\r\n\r\n<!-- include media/slushie.gif -->\r\n\r\n![Slushie Demo](media/slushie.gif)\r\n\r\n## Table of Contents\r\n\r\n- [\u2754 Why Slushie?](#-why-slushie)\r\n- [\ud83d\ude80 Installation](#-installation)\r\n- [\ud83c\udf08 Usage](#-usage)\r\n- [\ud83d\udd2c Running Tests](#-running-tests)\r\n- [\ud83e\udd1d Contributing](#-contributing)\r\n- [\ud83d\udcdc License](#-license)\r\n\r\n## \u2754 Why Slushie?\r\n\r\nRelative paths and imports in Python are an absolute nightmare due to how `PYTHONPATH` works and finds modules.\r\n\r\nFor example, \r\n```\r\nproject_root/\r\n\u2502   main.py\r\n\u2502\r\n\u251c\u2500\u2500\u2500package1/\r\n\u2502   \u2502   module1.py\r\n\u2502   \u2502   file.csv\r\n\u2502   \u2502\r\n\u2502   \u2514\u2500\u2500\u2500subpackage1/\r\n\u2502       \u2502   module2.py\r\n```\r\n\r\nIf I wanted to import `module1.py` from `main.py`, you'd think it would be something like the following:\r\n\r\n```\r\nfrom package1 import module1\r\nfrom package1.subpackage1 import module2\r\n```\r\n\r\n<!-- bold -->\r\n\r\n**This (most likely) will not work. Why?**\r\n\r\nPython relies on the dreaded `PYTHONPATH` environment variable to determine where to look for modules to import. \r\n\r\n`PYTHONPATH` is a list of directories that Python checks whenever you attempt an import. If `package1` and `subpackage1` are not included in the `PYTHONPATH`, Python doesn\u2019t know where to look for `module1.py`, and `module2.py`, resulting in an `ImportError`.\r\n\r\nAdditionally, attempting to open `file.csv`, using the traditional open command like this:\r\n\r\n```\r\nopen(\"package1/file.csv\")\r\n```\r\n\r\nwill most likely not even find the file, and even if it does, there's a high chance it will break if it is ever moved to another machine or ran from a different directory.\r\n\r\nThis is because the search for `file.csv` is relative to the current working directory where the Python script is executed, not necessarily where main.py is located.\r\n\r\n**TL;DR: If you use python's default import and open commands, you either have to do some Python witchcraft or risk randomly breaking your code.**\r\n\r\n## \ud83d\ude80 Installation\r\n\r\nInstall it directly from PyPI:\r\n\r\n```\r\npip install slushie\r\n```\r\n\r\n## \ud83c\udf08 Usage\r\n\r\n\r\n### sip(*parts: str) -> str\r\n\r\n**Purpose**: Create absolute paths relative to the current FILE. Ideal for accessing files in parent or sibling directories without a fuss.\r\n\r\n#### Parameters:\r\n- `*parts: str` - Parts of the path to join.\r\n\r\n#### Usage:\r\nAccess `hello.txt` located in a sibling directory from `script.py`.\r\n\r\n```\r\n/project\r\n    /folder1\r\n        script.py\r\n    /folder2\r\n        hello.txt\r\n```\r\n\r\n```python\r\npath = sip('..', 'folder2', 'hello.txt')\r\nprint(path)\r\n\r\n# Output:\r\n# /path/to/project/folder2/hello.txt\r\n# In this case, sip('.') refers to /path/to/project/folder1/\r\n```\r\n\r\nThe above code is fundamentally equivalent to the following:\r\n\r\n```python\r\nimport os\r\nimport sys\r\n\r\npath = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'folder2', 'hello.txt')\r\nprint(path)\r\n\r\n# Output:\r\n# /path/to/project/folder2/hello.txt\r\n```\r\n\r\nThis is extremely useful, as if you ever need to open a file, such as a csv for data analysis or a text file for logging, you should almost always be using relative paths as to avoid breaking your code when you move it to a different machine or share it with someone else. Slushie makes this easy.\r\n\r\n```python\r\n### gulp(directory: str = '.') -> Iterator[None]\r\n\r\n**Purpose**: Temporarily include directories in the Python path, easing the import of modules/packages.\r\n\r\n#### Parameters:\r\n- `directory: str` - Directory to add directories from.\r\n\r\n#### Usage:\r\nImport a module from a sibling directory.\r\n\r\n```python\r\nwith gulp('../sibling_directory'):\r\n    import a_module_from_sibling_directory\r\n```\r\n\r\n### freeze(path: str) -> None\r\n\r\n**Purpose**: Make a specific directory permanently available for imports.\r\n\r\n#### Parameters:\r\n- `path: str` - Path to append to `sys.path`.\r\n\r\n#### Usage:\r\n```python\r\nfreeze('../another_directory')\r\nimport a_module_from_another_directory\r\n```\r\n\r\n### pour(directory: str = '.') -> Iterator[Tuple[str, str]]\r\n\r\n**Purpose**: Easily access the current and parent directory paths of the current file the code is being written in.\r\n\r\n#### Parameters:\r\n- `directory: str` - Directory to get paths for.\r\n\r\n#### Usage:\r\n```python\r\nwith pour() as (current_dir, parent_dir):\r\n    print(f\"Current Directory: {current_dir}\")\r\n    print(f\"Parent Directory: {parent_dir}\")\r\n```\r\n\r\n### melt() -> str\r\n\r\n**Purpose**: Find the directory of the calling script, aiding in understanding the execution context.\r\n\r\n#### Usage:\r\n```python\r\ncaller_path = melt()\r\nprint(f\"Caller Path: {caller_path}\")\r\n\r\n# Output:\r\n# Caller Path: /path/to/calling/script.py\r\n# This is the path of the script that called melt(), not the path of melt() itself.\r\n# So if I had script /path/to/calling/script.py that called melt(), and melt() was located at /path/to/melt.py, the output would still be:\r\n# Caller Path: /path/to/calling/script.py\r\n```\r\n\r\n\r\n### slurp() -> str\r\n\r\n**Purpose**: Identify where the terminal command was executed from.\r\n\r\n#### Usage:\r\n```python\r\nterminal_path = slurp()\r\nprint(f\"Terminal Path: {terminal_path}\")\r\n\r\n# So if the script was located at /path/to/script.py and the terminal command was executed from /path/to, the output would be:\r\n# Terminal Path: /path/to\r\n```\r\n\r\n### scoop(file: str, mode: str = 'r', ...) -> TextIO\r\n\r\n**Purpose**: Simplify opening files by managing paths relative to the current script automatically.\r\n\r\n#### Parameters:\r\nLiterally the same as the built-in `open()` function. It's just a wrapper around it that automatically manages paths relative to the current script.\r\n\r\n\r\n#### Usage:\r\n```python\r\nwith scoop('../data.txt', 'r') as file:\r\n    data = file.read()\r\n    print(data)\r\n```\r\n\r\n## \ud83d\udd2c Running Tests\r\n\r\nKeeping Slushie frosty with some cool tests:\r\n\r\n- **For Linux:**\r\n  ```\r\n  ./run_tests.sh\r\n  ```\r\n\r\n- **For Windows:**\r\n  ```\r\n  run_tests.bat\r\n  ```\r\n\r\n## \ud83e\udd1d Contributing\r\n\r\nContribute your own flavors to make Slushie even more delightful! \ud83c\udf08\r\n\r\n## \ud83d\udcdc License\r\n\r\nSlushie is lovingly served under the MIT License. Scoop into the [LICENSE](LICENSE) file for the full details.\r\n\r\n\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Slushie: A Python library for relative path manipulation.",
    "version": "0.2.4",
    "project_urls": {
        "Homepage": "https://github.com/saleguas/slushie"
    },
    "split_keywords": [
        "path",
        "sys-path",
        "manipulation",
        "python-path",
        "module-path"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f2754fbaf64543d6b455ad4f03cb64b72886bab5f2be5398416bc01e9d4db76d",
                "md5": "40bd582441594c391e79993637e6909a",
                "sha256": "3cc853e23ac25d04a88a8c585b1450b69e76c559ef49d3e9cff6e065e8ae5667"
            },
            "downloads": -1,
            "filename": "slushie-0.2.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "40bd582441594c391e79993637e6909a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3",
            "size": 6932,
            "upload_time": "2023-11-19T23:20:16",
            "upload_time_iso_8601": "2023-11-19T23:20:16.328509Z",
            "url": "https://files.pythonhosted.org/packages/f2/75/4fbaf64543d6b455ad4f03cb64b72886bab5f2be5398416bc01e9d4db76d/slushie-0.2.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5aaebb554bb42dd7c85e8443344f32f12198e5fcb527119f9d40289c71e17936",
                "md5": "da9f8e73f77d19d0979aa1546592c529",
                "sha256": "e912ea7624d83cf23aadcdd6e41bdac05a98bd35437d513ea67047ae0a65429e"
            },
            "downloads": -1,
            "filename": "slushie-0.2.4.tar.gz",
            "has_sig": false,
            "md5_digest": "da9f8e73f77d19d0979aa1546592c529",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3",
            "size": 6572,
            "upload_time": "2023-11-19T23:20:18",
            "upload_time_iso_8601": "2023-11-19T23:20:18.432853Z",
            "url": "https://files.pythonhosted.org/packages/5a/ae/bb554bb42dd7c85e8443344f32f12198e5fcb527119f9d40289c71e17936/slushie-0.2.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-19 23:20:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "saleguas",
    "github_project": "slushie",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "slushie"
}
        
Elapsed time: 1.51037s