Reputation: 401
Let says that I have this project structure:
src
|my_package
__init__.py
|utils
__init__.py
util.py
|resources
__init__.py
my_resource.yml
In util.py, I have this code which need the resource file to work:
import yaml
import importlib.resources
from my_package import resources
class Util:
def merge_settings(self, settings: dict)->dict:
with importlib.resources.path(resources, 'my_resource.yml') as p:
with open(p) as file:
default_settings = yaml.safe_load(file)
and everything works fine in my development environment.
Then I make a wheel with this code with my setup.py file:
import setuptools
import glob
resource_folder = 'my_package/resources'
setuptools.setup(
name="my_package",
version="0.3",
packages=setuptools.find_packages(),
data_files=[(resource_folder, glob.glob(resource_folder+r'/*.yml'))]
then I create a wheel:
python .\setup.py bdist_wheel
and I finally install it to be used in another project, using a virtual environment with name my_env:
(my_env) D:\dev pip install my_package-0.3-py3-none-any.whl
But my code is not running any more due to this line:
importlib.resources.path(resources, 'my_resource.yml')
The reason is found when exploring my_env folder, my_resource.yml is not in my_package anymore.
my_env
|my_package
|resources
my_resource.yml
|Lib
|site-packages
|my_package
|resources
__init__.py
But this location could be quite useful to modify easily this file... The how can I deal in the same time with a correct call of resources in my development environment and when using it after pip install ? I would like to always have access to the yml file for edition when required, even after pip install...
Tks for your help
Upvotes: 1
Views: 989
Reputation: 70175
your data_files
is both mis-specified and not the setting you want (it's intended for non-package data). the keys in data_files
are placed from the root of the prefix (so say you install your package into ./venv
instead of your data ending at ./venv/lib/python#.#/site-packages/my_package/resources/...
they're going to end up at venv/my_package/resources
-- definitely not what you want!).
the actual setting that you want is package_data
:
package_data={
'my_package.resources': '*.yml',
},
the mapping maps from dotted package names to globs and will place it inside site-packages
there's no need to use MANIFEST.in
, etc. as these files are automatically included in your package
for more on this, I made a video on the subject
Upvotes: 3