Skip to content

Utils

feu.utils

Contain the utility functions.

feu.utils.command

Contain utility functions to run commands.

feu.utils.command.run_bash_command

run_bash_command(cmd: str) -> None

Execute a bash command.

Parameters:

Name Type Description Default
cmd str

The command to run.

required
Example
>>> from feu.utils.command import run_bash_command
>>> run_bash_command("ls -l")  # doctest: +SKIP

feu.utils.http

Contain utility functions to manage HTTP requests.

feu.utils.http.fetch_data

fetch_data(
    url: str, timeout: float = 10.0, **kwargs: Any
) -> dict[str, Any]

Retrieve data for a given URL.

This function performs an HTTP GET request to fetch repository information. It configures a retry policy for transient errors (e.g., 429, 500, 502, 503, 504), handles network and timeout failures, validates the HTTP response, and returns the parsed JSON payload. Any unrecoverable error is raised as a RuntimeError with a clear message.

Parameters:

Name Type Description Default
url str

The URL.

required
timeout float

The number of seconds to wait for the server to send data before giving up.

10.0
**kwargs Any

Optional arguments that requests.get takes.

{}

Returns:

Type Description
dict[str, Any]

The parsed JSON object returned.

Raises:

Type Description
RuntimeError

If the request times out, if a network or HTTP error occurs, or if the response body contains invalid JSON.

Example
>>> from feu.utils.http import fetch_data
>>> data = fetch_data("https://pypi.org/pypi/requests/json")  # doctest: +SKIP

feu.utils.http.fetch_response

fetch_response(
    url: str, timeout: float = 10.0, **kwargs: Any
) -> Response

Retrieve data from a given URL with automatic retry logic.

This function performs an HTTP GET request with a configured retry policy for transient errors (429, 500, 502, 503, 504). If urllib3 is available, it applies exponential backoff with up to 5 retry attempts. The function validates the HTTP response and raises detailed errors for failures.

Parameters:

Name Type Description Default
url str

The URL to fetch.

required
timeout float

The number of seconds to wait for the server to send data before giving up. Defaults to 10.0.

10.0
**kwargs Any

Optional arguments that requests.get accepts.

{}

Returns:

Type Description
Response

A requests.Response object containing the HTTP response.

Raises:

Type Description
RuntimeError

If the request times out or if a network/HTTP error occurs.

Example
>>> from feu.utils.http import fetch_response
>>> response = fetch_response("https://pypi.org/pypi/requests/json")  # doctest: +SKIP
>>> response.json()  # doctest: +SKIP

feu.utils.installer

Contain utility functions to manage installers.

feu.utils.installer.InstallerSpec dataclass

Define a dataclass to represent an installer specification.

Parameters:

Name Type Description Default
name str

The installer name.

required
arguments str

A string containing optional installer arguments.

''
Example
>>> from feu.utils.installer import InstallerSpec
>>> installer1 = InstallerSpec("pip")
>>> installer1
InstallerSpec(name='pip', arguments='')
>>> installer2 = InstallerSpec("pip", arguments="-U")
>>> installer2
InstallerSpec(name='pip', arguments='-U')

feu.utils.io

Contain utility functions to export data to JSON format.

feu.utils.io.generate_unique_tmp_path

generate_unique_tmp_path(path: Path) -> Path

Return a unique temporary path given a path.

This function updates the name to add a UUID.

Parameters:

Name Type Description Default
path Path

The input path.

required

Returns:

Type Description
Path

The unique name.

Example
>>> import tempfile
>>> from pathlib import Path
>>> from feu.utils.io import generate_unique_tmp_path
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     path = generate_unique_tmp_path(Path(tmpdir).joinpath("data.json"))
...     path
...
PosixPath('/.../data-....json')

feu.utils.io.load_json

load_json(path: Path) -> Any

Load the data from a given JSON file.

Parameters:

Name Type Description Default
path Path

The path to the JSON file.

required

Returns:

Type Description
Any

The data from the JSON file.

Example
>>> import tempfile
>>> from pathlib import Path
>>> from feu.utils.io import save_json, load_json
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     path = Path(tmpdir).joinpath("data.json")
...     save_json({"key1": [1, 2, 3], "key2": "abc"}, path)
...     data = load_json(path)
...     data
...
{'key1': [1, 2, 3], 'key2': 'abc'}

feu.utils.io.save_json

save_json(
    to_save: Any, path: Path, *, exist_ok: bool = False
) -> None

Save the given data in a JSON file.

Parameters:

Name Type Description Default
to_save Any

The data to write in a JSON file.

required
path Path

The path where to write the JSON file.

required
exist_ok bool

If exist_ok is False (the default), FileExistsError is raised if the target file already exists. If exist_ok is True, FileExistsError will not be raised unless the given path already exists in the file system and is not a file.

False

Raises:

Type Description
FileExistsError

if the file already exists.

Example
>>> import tempfile
>>> from pathlib import Path
>>> from feu.utils.io import save_json
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     path = Path(tmpdir).joinpath("data.json")
...     save_json({"key1": [1, 2, 3], "key2": "abc"}, path)
...     data = load_json(path)
...     data
...
{'key1': [1, 2, 3], 'key2': 'abc'}

feu.utils.mapping

Contain utility functions for mappings.

feu.utils.mapping.sort_by_keys

sort_by_keys(mapping: Mapping[Any, Any]) -> dict[Any, Any]

Sort a dictionary by keys.

Parameters:

Name Type Description Default
mapping Mapping[Any, Any]

The dictionary to sort.

required

Returns:

Name Type Description
dict dict[Any, Any]

The sorted dictionary.

Example
>>> from feu.utils.mapping import sort_by_keys
>>> sort_by_keys({"dog": 1, "cat": 5, "fish": 2})
{'cat': 5, 'dog': 1, 'fish': 2}

feu.utils.mapping.sort_by_values

sort_by_values(
    mapping: Mapping[Any, Any],
) -> dict[Any, Any]

Sort a dictionary by values.

Parameters:

Name Type Description Default
mapping Mapping[Any, Any]

The dictionary to sort.

required

Returns:

Name Type Description
dict dict[Any, Any]

The sorted dictionary.

Example
>>> from feu.utils.mapping import sort_by_values
>>> sort_by_values({"dog": 1, "cat": 5, "fish": 2})
{'dog': 1, 'fish': 2, 'cat': 5}

feu.utils.package

Contain utility functions to manage packages.

feu.utils.package.PackageDependency dataclass

Define a dataclass to represent a package dependency.

Parameters:

Name Type Description Default
name str

The package name.

required
version_specifiers list[str] | None

Optional package version specifies.

None
extras list[str] | None

Optional package extra dependencies.

None
Example
>>> from feu.utils.package import PackageDependency
>>> pkg1 = PackageDependency("my_package")
>>> pkg1
PackageDependency(name='my_package', version_specifiers=None, extras=None)
>>> pkg2 = PackageDependency("my_package", version_specifiers=["==1.2.3"])
>>> pkg2
PackageDependency(name='my_package', version_specifiers=['==1.2.3'], extras=None)
>>> pkg3 = PackageDependency(
...     "my_package", version_specifiers=["==1.2.3"], extras=["security", "socks"]
... )
>>> pkg3
PackageDependency(name='my_package', version_specifiers=['==1.2.3'], extras=['security', 'socks'])

feu.utils.package.PackageSpec dataclass

Define a dataclass to represent a package specification.

Parameters:

Name Type Description Default
name str

The package name.

required
version str | None

An optional package version.

None
extras list[str] | None

Optional package extra dependencies.

None
Example
>>> from feu.utils.package import PackageSpec
>>> pkg1 = PackageSpec("my_package")
>>> pkg1
PackageSpec(name='my_package', version=None, extras=None)
>>> pkg2 = PackageSpec("my_package", version="1.2.3")
>>> pkg2
PackageSpec(name='my_package', version='1.2.3', extras=None)
>>> pkg3 = PackageSpec("my_package", version="1.2.3", extras=["security", "socks"])
>>> pkg3
PackageSpec(name='my_package', version='1.2.3', extras=['security', 'socks'])

feu.utils.package.PackageSpec.to_package_dependency

to_package_dependency() -> PackageDependency

Convert to a PackageDependency.

Returns:

Type Description
PackageDependency

The current package as a package dependency.

Example
>>> from feu.utils.package import PackageSpec
>>> pkg = PackageSpec("my_package")
>>> dep = pkg.to_package_dependency()
>>> dep
PackageDependency(name='my_package', version_specifiers=None, extras=None)

feu.utils.package.PackageSpec.with_version

with_version(version: str | None) -> PackageSpec

Create a new PackageSpec instance with the given version.

Parameters:

Name Type Description Default
version str | None

The new version to apply.

required

Returns:

Type Description
PackageSpec

A new instance of PackageSpec with the updated version.

Example
>>> from feu.utils.package import PackageSpec
>>> pkg = PackageSpec("my_package", version="1.2.0")
>>> pkg
PackageSpec(name='my_package', version='1.2.0', extras=None)
>>> pkg2 = pkg.with_version("1.2.3")
>>> pkg2
PackageSpec(name='my_package', version='1.2.3', extras=None)

feu.utils.package.extract_package_extras

extract_package_extras(requirement: str) -> list[str]

Extract the optional extras from a requirement string.

The requirement string may include extras in square brackets, e.g., 'package[extra1,extra2]'. This function returns the list of extras.

Parameters:

Name Type Description Default
requirement str

The requirement string containing the package name and optionally extra dependencies.

required

Returns:

Type Description
list[str]

A list of extra requirements, or an empty list if none exist.

Example
>>> from feu.utils.package import extract_package_extras
>>> extract_package_extras("numpy")
[]
>>> extract_package_extras("pandas[performance]")
['performance']
>>> extract_package_extras("requests[security,socks]")
['security', 'socks']

feu.utils.package.extract_package_name

extract_package_name(requirement: str) -> str

Extract the base package name from a requirement string.

The requirement string may include optional dependencies in square brackets, such as 'package[extra1,extra2]'. This function returns only the base package name without the extras.

Parameters:

Name Type Description Default
requirement str

The requirement string containing the package name and optionally extra dependencies.

required

Returns:

Type Description
str

The base package name without extras.

Raises:

Type Description
ValueError

if requirement does not start with a valid package name.

Example
>>> from feu.utils.package import extract_package_name
>>> extract_package_name("numpy")
'numpy'
>>> extract_package_name("pandas[performance]")
'pandas'
>>> extract_package_name("requests[security,socks]")
'requests'

feu.utils.package.generate_extras_string

generate_extras_string(extras: Sequence[str]) -> str

Generate a string with the package extras i.e. optional dependencies.

Parameters:

Name Type Description Default
extras Sequence[str]

The package optional dependencies.

required

Returns:

Type Description
str

A string with the package extras.

Example
>>> from feu.utils.package import generate_extras_string
>>> generate_extras_string(["security"])
'[security]'
>>> generate_extras_string(["security", "socks"])
'[security,socks]'
>>> generate_extras_string([])
''

feu.utils.package.is_wildcard_version

is_wildcard_version(version: str | None) -> bool

Indicate if a version string contains a wildcard.

Wildcard versions such as '2.12.*' are used to let the installer pick any matching version, and cannot be parsed as a concrete packaging.version.Version.

Parameters:

Name Type Description Default
version str | None

The version string to check.

required

Returns:

Type Description
bool

True if the version contains a wildcard, otherwise False.

Example
>>> from feu.utils.package import is_wildcard_version
>>> is_wildcard_version("2.12.*")
True
>>> is_wildcard_version("2.12.0")
False

feu.utils.platform

Contain platform utilities.

feu.utils.platform.get_current_arch

get_current_arch() -> str | None

Return the current CPU architecture using the registry's vocabulary.

The value returned by platform.machine() is mapped to one of "x86_64" or "arm64".

Returns:

Type Description
str | None

The architecture name, or None if it is not recognized.

Example
>>> from feu.utils.platform import get_current_arch
>>> get_current_arch()  # doctest: +SKIP
'x86_64'

feu.utils.platform.get_current_os

get_current_os() -> str | None

Return the current OS name using the registry's vocabulary.

The value returned by platform.system() is mapped to one of "linux", "macos", or "windows".

Returns:

Type Description
str | None

The OS name, or None if it is not recognized.

Example
>>> from feu.utils.platform import get_current_os
>>> get_current_os()  # doctest: +SKIP
'linux'

feu.utils.platform.get_python_version

get_python_version() -> str

Return the current Python version as a "major.minor" string.

Returns:

Type Description
str

The current Python version.

Example
>>> from feu.utils.platform import get_python_version
>>> get_python_version()  # doctest: +SKIP
'3.11'

feu.utils.platform.is_free_threaded

is_free_threaded() -> bool

Indicate whether the running Python interpreter is a free- threaded build with the GIL disabled.

Free-threaded builds (PEP 703 <https://peps.python.org/pep-0703/>_) expose sys._is_gil_enabled, which is only present starting from Python 3.13 free-threaded builds. On any other build, or when the GIL has been re-enabled at runtime, this returns False.

Returns:

Type Description
bool

True if the interpreter is running without the GIL, otherwise False.

Example
>>> from feu.utils.platform import is_free_threaded
>>> is_free_threaded()  # doctest: +SKIP
False