Filesystem: A Centralized Registry of Common Filesystem Paths#

my.apis.Filesystem.fs#

An alias for “FS””

class my.apis.Filesystem.Filesystem(*, plat: Platform = <Platform.GNU: 4>, home: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd'), config: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/.config'), cache: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/.cache'), data: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/.local/share'), my: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/my'), creds: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/my/.creds'), corpus: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/my/corpus'), local: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/local'), logs: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/local/logs'), models: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/local/models'), metrics: Path, ~pydantic.functional_validators.BeforeValidator(func=~my.utils.SystemUtils.SystemUtils.path, json_schema_input_type=PydanticUndefined)] = PosixPath('/home/robbd/local/metrics'))#

A registry of file paths, mapping string names to Path objects.

Each instance carries the platform’s conventional user directories (home, config, cache, data) plus the workspace roots configured through environment variables like $MY and $MY_LOCAL. The class also collects a family of classmethod path utilities usable without any instance. A default instance is exported as fs (aliased FS and PATHS).

Examples

The default instance reflects the local machine:

>>> from pathlib import Path
>>> from my.apis import fs
>>> fs.home == Path.home()
True

I Primary Methods#

static Filesystem.compile_rgx(path: Path | str) → Pattern[str]#

Compile a boundary-aware pattern for a non-root POSIX path.

The match starts with /, ./, or one or more ../ segments. It will not begin inside a URI, UNC path, or DOS drive-root path. URI, UNC, DOS/backslash, empty, and filesystem-root inputs are rejected rather than interpreted heuristically.

Capture group 1 contains the literal path without its leading slash. Capture group 2 contains one optional trailing slash.

Parameters:

path – Non-root POSIX path to escape and match literally.

Returns:

Compiled path pattern with the literal body and trailing slash captured.

Raises:

ValueError – If path is not a non-root POSIX path.

Examples

Relative prefixes are part of the match but not the literal-body capture:

>>> from my.apis import Filesystem
>>> pattern = Filesystem.compile_rgx('/srv/app')
>>> match = pattern.search('from ../srv/app/logs')
>>> match[0], match[1]
('../srv/app/', 'srv/app')
>>> pattern.search('file:///srv/app') is None
True

II Public Methods#

property Filesystem.rgxs: dict[str, Pattern[str]]#

Compile patterns for every path-valued registry field.

Non-path metadata such as plat is omitted.

Returns:

Map from path field name to its compiled literal-path pattern.

Examples

Platform metadata is not a path pattern:

>>> from my.apis import fs
>>> 'plat' in fs.rgxs
False
>>> bool(fs.rgxs['home'].search(fs.home.as_posix()))
True
classmethod Filesystem.is_possible(raw: str | Path | None) → bool#

Check if the given value denotes a usable, non-trivial path.

Parameters:

raw – Path-like value to inspect.

Returns:

True unless the value is empty, None, or normalizes to a rootless/trivial path.

Examples

Empty-ish values fail; anything that normalizes to a real shape passes:

>>> from my.apis import Filesystem
>>> Filesystem.is_possible('/srv/app')
True
>>> Filesystem.is_possible('')
False
classmethod Filesystem.is_actual(raw: str | Path | None) → bool#

Check if the given path actually exists on this machine.

Parameters:

raw – Path-like value to inspect.

Returns:

True when the value is a possible path that exists on disk.

Examples

Existence is checked after normalization:

>>> from pathlib import Path
>>> from my.apis import Filesystem
>>> Filesystem.is_actual(Path.home())
True
>>> Filesystem.is_actual('/no/such/place')
False
classmethod Filesystem.path(raw: str | Path | None) → Path#

Normalize a path – see ut.path() for full documentation.

Expands ~ and environment variables, then resolves the result to an absolute path.

Examples

Relative segments are resolved lexically:

>>> from my.apis import Filesystem
>>> Filesystem.path('/srv/app/../logs')
PosixPath('/srv/logs')
classmethod Filesystem.is_relative_to(child: Path | str, parent: Path | str) → bool#

Check if the child path sits under the proposed parent, segment-aware.

A convenience wrapper over Path.is_relative_to() that accepts strings, so sibling names sharing a prefix (/srv/app2 vs /srv/app) are correctly kept apart.

Parameters:
  • child – Path to check.

  • parent – Proposed parent path.

Returns:

Whether the child is relative to parent.

Examples

Compare by whole path segments, not string prefixes:

>>> from my.apis import Filesystem
>>> Filesystem.is_relative_to('/srv/app/logs', '/srv/app')
True
>>> Filesystem.is_relative_to('/srv/app2', '/srv/app')
False
classmethod Filesystem.relativize(path: Path, *ancestors: Path | str) → Path | None#

Relativize the given path to the first matching parent if possible, or none otherwise.

Parameters:
  • path – Path to relativize, which must be absolute. Doesn’t have to exist.

  • *ancestors – One or more potential ancestors to check against.

Returns:

The same path but relative to the first matching ancestor, otherwise None.

Examples

The first matching ancestor wins; non-absolute paths are refused:

>>> from pathlib import Path
>>> from my.apis import Filesystem
>>> Filesystem.relativize(Path('/srv/app/logs/x.log'), '/opt', '/srv/app')
PosixPath('logs/x.log')
>>> Filesystem.relativize(Path('relative/x.log'), '/srv') is None
True
classmethod Filesystem.seek_project(path: Path | None = None) → Path | None#

Attempt to find the project root by looking for common indicators.

Walks the strict ancestors of the starting directory (not the directory itself), stopping at the user’s home directory. An ancestor counts as a project root when it contains a recognizable marker file (pyproject.toml, Taskfile, a lockfile, …) or directory (.git, node_modules, …).

Parameters:

path – Starting path to search from, defaulting to the working directory. If a file is given, its parent will be used.

Returns:

The first ancestor containing a project marker, or None if the walk reaches home.

classmethod Filesystem.shortpath(path: str | Path | None) → str#

Relativize the given path to a shorter form if possible. For casual use.

Candidate anchors are the working directory (.), the home directory (~), and any absolute paths found in environment variables; unmatched paths yield the empty string.

Examples

Paths under home shorten to the ~ form:

>>> from my.apis import fs
>>> fs.shortpath(fs.home / 'notes' / 'todo.md')
'~/notes/todo.md'