How it works
A package resource is data distributed with an importable package, such as a template or small configuration file. importlib.resources.files returns a traversable resource container rather than promising an ordinary filesystem directory.
Packages may be loaded from different locations or supported archives. Reading through the resource interface avoids assuming that the user launched Python from your source directory. These Python 3.11 examples create a tiny temporary package so they can run independently.
Limitations and practical choices
Ensure the packaging configuration actually includes your data files. A working source checkout does not prove the built distribution contains them.
Use as_file only when another API needs a real path, and use that path inside its context. Do not write user preferences back into installed package resources.
Try it yourself
Create a package containing a greeting resource, then read it from a different working directory. Explain why a bare relative open call would not identify the package reliably.
Syntax
from importlib.resources import files
text = files(package).joinpath("message.txt").read_text(encoding="utf-8")Examples
Read bundled text
Create a small demonstration package and read its text resource.
import importlib
import sys
from importlib.resources import files
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as folder:
package = Path(folder) / "lesson_assets"
package.mkdir()
(package / "__init__.py").write_text("", encoding="utf-8")
(package / "message.txt").write_text("Welcome", encoding="utf-8")
sys.path.insert(0, folder)
try:
importlib.invalidate_caches()
import lesson_assets
resource = files(lesson_assets).joinpath("message.txt")
print(resource.read_text(encoding="utf-8"))
finally:
sys.path.remove(folder)
sys.modules.pop("lesson_assets", None)- The setup creates __init__.py to make a package and writes message.txt beside it. A temporary sys.path entry makes that package importable for this isolated demonstration.
- files uses the imported package as its anchor. joinpath locates the resource and read_text decodes it explicitly as UTF-8, independent of the working directory.
- In an installed application the package already exists, so use just the import and resource-reading lines. The finally block removes this example’s temporary import state.
- Expected output: Welcome
Check and read bytes
Inspect a resource and choose binary access deliberately.
import importlib
import sys
from importlib.resources import files
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as folder:
package = Path(folder) / "lesson_assets"
package.mkdir()
(package / "__init__.py").write_text("", encoding="utf-8")
(package / "message.txt").write_text("Welcome", encoding="utf-8")
sys.path.insert(0, folder)
try:
importlib.invalidate_caches()
import lesson_assets
resource = files(lesson_assets).joinpath("message.txt")
print(resource.is_file())
print(resource.read_bytes())
finally:
sys.path.remove(folder)
sys.modules.pop("lesson_assets", None)- The same temporary setup supplies a known resource. is_file confirms it is a file, then read_bytes returns its raw content.
- The b-prefixed output is a bytes representation rather than decoded text. Choose binary access for images or formats with their own decoding process.
- An existence check is not a substitute for handling a later read failure in real deployments. The resource interface avoids assuming that storage is a plain local directory.
- Expected output: True b'Welcome'
Provide a temporary real path
Bridge to an API that requires a filesystem path.
import importlib
import sys
from importlib.resources import files
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as folder:
package = Path(folder) / "lesson_assets"
package.mkdir()
(package / "__init__.py").write_text("", encoding="utf-8")
(package / "message.txt").write_text("Welcome", encoding="utf-8")
sys.path.insert(0, folder)
try:
importlib.invalidate_caches()
import lesson_assets
from importlib.resources import as_file
resource = files(lesson_assets).joinpath("message.txt")
with as_file(resource) as path:
print(path.read_text(encoding="utf-8"))
finally:
sys.path.remove(folder)
sys.modules.pop("lesson_assets", None)- as_file supplies a concrete Path for the file resource. When necessary, an implementation may extract a temporary file.
- The path is used inside the nested with block so its lifetime is respected. The example does not assume it remains valid after that context ends.
- Use this bridge for libraries that insist on a filename; prefer direct read_text or read_bytes when no actual path is needed.
- Expected output: Welcome
Best practices
- Ensure the packaging configuration actually includes your data files. A working source checkout does not prove the built distribution contains them.
- Use as_file only when another API needs a real path, and use that path inside its context. Do not write user preferences back into installed package resources.
Runtime & versions
Python interpreter. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
Python language reference