Python setup runs scripts in his own directory

Viewed 50

I have structure like that

src/
   setup.py
   my_folder/
             my_script.py
             my_data.json

My .py file uses data from my_data.json and it simple points to it with path my_data.json, because it is rigth next to it? Yeah it works correctly when I run it normally by python my_script.py but when I try to make it via setup file and run it with some alias then it's clearly runs from /src directory and it doesn't see my my_data.json file because it should point to my_folder/my_data.json. When I print os.getcwd() then I see that my_script.py is run from /src directory, that's kind of weird... My setup looks like this:

setup(
  name='main',
    entry_points={
        'console_scripts': [
            'my_alias = my_folder.my_script:main'
        ],
    },
    include_package_data=True,
    packages=find_packages()
)

Do you have any idea how to force to run my script in his directory not directory where setup is placed?

1 Answers

I'd highly recommend avoiding moving into the packages directory if you can avoid it, but something like:

import os

os.chdir(os.path.dirname(os.path.abspath(__file__)))

would probably work.

if you just need to get the resources you included inside of your module, you could do something like this in my_script:

import json
import pkg_resources

raw = pkg_resources.resource_string(__name__, 'my_data.json')
data = json.loads(raw)

pkg_resources.resource_string returns the contents of my_data.json as a bytestring. There are also .resource_stream and .resource_filename methods if you want to be able to open them as files within python or with a subprocess, respectively. This gives you compatibility with zip_safe environments, which may or may not be useful to you depending on what you're doing.

I'm not sure if its technically required, but I find sometimes setup scripts don't play nicely with automatically adding data files to your package, and some manual intervention like the following is required:

setup(
    name='mypackage',
    entry_points={
        'console_scripts': [
            'my_alias = mypackage.my_script:main'
        ],
    },
    package_data={'mypackage': ['*.json']},  # Important addition
    include_package_data=True,
    packages=find_packages()
)
Related