Easily pick a place to store data for your Python code with standardized directory management, caching, and data format support.
—
PyStow's directory management system provides standardized, configurable data storage for Python applications. It handles automatic directory creation, environment variable configuration, and versioned storage patterns.
def module(key: str, *subkeys: str, ensure_exists: bool = True) -> Module:
"""Return a module for the application.
Args:
key: The name of the module. No funny characters. The envvar <key>_HOME where
key is uppercased is checked first before using the default home directory.
subkeys: A sequence of additional strings to join. If none are given, returns
the directory for this module.
ensure_exists: Should all directories be created automatically? Defaults to true.
Returns:
The module object that manages getting and ensuring
"""def join(key: str, *subkeys: str, name: str | None = None, ensure_exists: bool = True, version: VersionHint = None) -> Path:
"""Return the home data directory for the given module.
Args:
key: The name of the module. No funny characters. The envvar <key>_HOME where
key is uppercased is checked first before using the default home directory.
subkeys: A sequence of additional strings to join
name: The name of the file (optional) inside the folder
ensure_exists: Should all directories be created automatically? Defaults to true.
version: The optional version, or no-argument callable that returns an
optional version. This is prepended before the subkeys.
Returns:
The path of the directory or subdirectory for the given module.
"""PyStow respects several environment variables for configuration:
PYSTOW_HOME: Override the default base directory (e.g., /usr/local/data)PYSTOW_NAME: Change the default directory name from .data (e.g., mydata)<MODULE>_HOME: Set custom home for specific modules (e.g., MYAPP_HOME=/custom/path)Default directory structure follows the pattern:
$HOME/.data/
├── myapp/
│ ├── datasets/
│ │ └── v1/
│ └── config/
└── otherapp/
└── cache/With version support:
$HOME/.data/
└── myapp/
├── v1.0/
│ └── data.csv
└── v2.0/
└── data.csvimport pystow
# Get application directory
app_dir = pystow.join("myapp")
# Creates: $HOME/.data/myapp/
# Get nested directories
data_dir = pystow.join("myapp", "datasets", "raw")
# Creates: $HOME/.data/myapp/datasets/raw/
# Get file path
config_path = pystow.join("myapp", "config", name="settings.json")
# Returns: $HOME/.data/myapp/config/settings.jsonimport pystow
# Create a module for your application
module = pystow.module("myapp")
# Get subdirectories
data_module = module.module("datasets")
config_module = module.module("config")
# Get file paths
data_file = data_module.join(name="data.csv")
config_file = config_module.join(name="settings.json")import pystow
import requests
def get_data_version():
"""Get current data version from API"""
response = requests.get("https://api.example.com/version")
return response.json()["version"]
# Store data with version
data_path = pystow.join(
"myapp", "datasets",
name="data.csv",
version=get_data_version # Callable for dynamic versioning
)
# Or with static version
data_path = pystow.join(
"myapp", "datasets",
name="data.csv",
version="v1.2.3"
)import os
import pystow
# Set custom base directory
os.environ['PYSTOW_HOME'] = '/opt/data'
# Now all modules use /opt/data as base
app_dir = pystow.join("myapp") # -> /opt/data/myapp/
# Set app-specific directory
os.environ['MYAPP_HOME'] = '/custom/myapp/path'
app_dir = pystow.join("myapp") # -> /custom/myapp/path/import pystow
# Don't create directories automatically
path = pystow.join("myapp", "temp", ensure_exists=False)
# Only create if it doesn't exist
if not path.exists():
path.mkdir(parents=True)def joinpath_sqlite(key: str, *subkeys: str, name: str) -> str:
"""Get an SQLite database connection string.
Args:
key: The name of the module. No funny characters. The envvar <key>_HOME
where key is uppercased is checked first before using the default home
directory.
subkeys: A sequence of additional strings to join. If none are given, returns
the directory for this module.
name: The name of the database file.
Returns:
A SQLite path string.
"""Usage:
import pystow
import sqlite3
# Get SQLite connection string
db_path = pystow.joinpath_sqlite("myapp", "databases", name="data.db")
conn = sqlite3.connect(db_path)Install with Tessl CLI
npx tessl i tessl/pypi-pystow