Skip to main content

Access resources on your terms

Project description

Acres: Access resources on your terms

PyPI release Codecov Coverage report

This module provides simple, consistent access to package resources.

from acres import Loader

loader = Loader(somepkg)

res_text = loader.readable('data/some_resource.txt').read_text()
res_bytes = loader.readable('data/another_resource.bin').read_bytes()

with loader.as_path('data') as data_dir:
    # data_dir is a pathlib.Path until the "with" scope closes

resource_path = loader.cached('data/another_resource.bin')
# The path pointed to by resource_path will exist until interpreter exit

Module loader

The primary use case for acres.Loader is to allow a directory module to provide access to its resources.

Suppose you have a module structure:

src/
  mypkg/
    data/
      resourceDir/
        ...
      __init__.py
      resource.ext
    __init__.py
    ...

In src/mypkg/data/__init__.py, add:

'''Data package

.. autofunction:: load_resource

.. automethod:: load_resource.readable

.. automethod:: load_resource.as_path

.. automethod:: load_resource.cached
'''

from acres import Loader

load_resource = Loader(__spec__.name)

mypkg.data.load_resource() is now a function that will return a Path to a resource that is guaranteed to exist until interpreter exit:

from mypkg.data import load_resource

resource_file: Path = load_resource('resource.ext')

For additional control, you can use load_resource.readable() to return a Path-like object that implements .read_text() and .read_bytes():

resource_contents: bytes = load_resource.readable('resource.ext').read_bytes()

Or a context manager with a limited lifetime:

with load_resource.as_path('resourceDir') as resource_dir:
    # Work with the contents of `resource_dir` as a `Path`

# Outside the `with` block, `resource_dir` may no longer point to an existing path.

Note that load_resource() is a shorthand for load_resource.cached(), whose explicitness might be more to your taste.

The __spec__.name anchor

Previous versions recommended using Loader(__package__). Before Python 3.10, __package__ might be None during a [zipimport][], and __package__ has been deprecated in Python 3.13, to be removed in 3.15.

__spec__.parent is an exact equivalent for __package__, but for __init__.py files, __spec__.name is equivalent. __spec__.name is also guaranteed to be a string and not None, which lets it play nicely with type checkers.

Interpreter-scoped resources, locally scoped loaders

Loader.cached uses a global cache. This ensures that cached files do not get unloaded if a Loader() instance is garbage collected, and it also ensures that instances can be created cheaply and garbage collected when out of scope.

Why acres?

importlib.resources provides a simple, composable interface, using the files() and as_file() functions:

from importlib.resources import files, as_file

with as_file(files(my_module) / 'data' / 'resource.ext') as resource_path:
    # Interact with resource_path as a pathlib.Path

# resource_path *may* no longer exist

files() returns a Traversable object, which is similar to a pathlib.Path, except that the object may not actually exist, so os functions may not work correctly on it. as_files() turns a Traversable into a Path that exists on the filesystem for the duration of the with block.

To make matters more complicated, if a package is unpacked on the filesystem, files() returns an actual Path object. It is therefore easy to miss bugs where a true Path is always needed but a Traversable may be returned when the package is zipped.

Finally, the scoping of as_files() is frequently inconvenient. If you pass a Path to an object inside an as_files() context, but the resource access is deferred, the Path may point to a nonexistent file or directory. Again, this bug will only exhibit when the package is zipped.

acres.Loader aims to clearly delineate the scopes and capabilities of the accessed resources, including providing an interpreter-lifetime scope.

Type annotations

acres is fully type-annotated, and checked with both mypy and pyright. The Loader.readable method returns a Traversable, which moved from importlib.abc in Python 3.10 to importlib.resources.abc in Python 3.11. To simplify the use of this annotation in functions that accept readable resources, use:

import acres.typ as at

def myfunc(resource: at.Traversable) -> ReturnType:
    ...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

acres-0.4.1.tar.gz (57.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

acres-0.4.1-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file acres-0.4.1.tar.gz.

File metadata

  • Download URL: acres-0.4.1.tar.gz
  • Upload date:
  • Size: 57.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for acres-0.4.1.tar.gz
Algorithm Hash digest
SHA256 426854074d44cf22376c837ff841a3aa5bb2e07b5ab1ea135d70ea0df8183aa3
MD5 b78471d113fb5650663dd541ea385027
BLAKE2b-256 fdf2f6596bbeffd651f967d0b086b21295e590d83945cdfbce84c859fde6fd65

See more details on using hashes here.

Provenance

The following attestation bundles were made for acres-0.4.1.tar.gz:

Publisher: test.yml on nipreps/acres

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file acres-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: acres-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for acres-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2c55915a1ba1ce39d321cde5a70197b4e9ee00989b6fc2790c6647283ba80cc8
MD5 0260a16410a8b2cd96f5dd5be5bba23e
BLAKE2b-256 73bfa909884db6a95b977f9a21e817e4e16bf2b6f50d01c92fcd58c8fe28767c

See more details on using hashes here.

Provenance

The following attestation bundles were made for acres-0.4.1-py3-none-any.whl:

Publisher: test.yml on nipreps/acres

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page