Proper setup.py creation - python

So I have a project which is structured as shown below:
project
├── src
│ ├── api
│ │ ├── __init__.py
│ │ └── api.py
│ ├── instance
│ │ ├── __init__.py
│ │ └── config.py
│ ├── packages
│ │ ├── __init__.py
│ │ └── app.py
├── tests
│ └── __init__.py
├── requirements.txt
├── README.md
├── .gitignore
└── setup.py
I am trying to create the setup.py in order to call the instance/config.py from the package/app.py. So I created the following setup.py:
from distutils.core import setup
from setuptools import setup, find_packages
setup(
name='project',
version='0.1dev0',
author='Author name',
author_email='my_email',
packages=['api', 'instance', 'packages'],
long_description=open('README.md').read()
)
But I get the following error:
...
warnings.warn(tmpl.format(**locals()))
package init file 'src\__init__.py' not found (or not a regular file)
error: package directory 'api' does not exist
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
So whenever I try to call the instance/config.py from the packages/app.py I get the following error:
from instance import config
ModuleNotFoundError: No module named 'instance'
What do I need to do to the setup.py file to make it work? Should the structure of the project be altered somehow?
Thanks a lot in advance!

In a nutshell, you have to create a root package project in project directory. See https://packaging.python.org/tutorials/packaging-projects/ for more details. Then
from project.instance import config
Rename src to project and put there __init__.py with imports
from . import api, instance, packages

Related

Getting ModuleNotFoundError: No module named trying to run unit test Python

I can run test_authentication.py no problem in PyCharm (Shift + F10). However, when I try to run python test_authentication.py in Anaconda Prompt, I am getting this error:
(etradebot) PS H:\My Drive\etradebot\tests> python test_authentication.py
Traceback (most recent call last):
File "H:\My Drive\etradebot\tests\test_authentication.py", line 4, in <module>
from authentication.authentication import Authentication
ModuleNotFoundError: No module named 'authentication'
This is my project's structure.
etradebot/
├── authentication/
│ ├── __init__.py
│ ├── authentication.py
│
├── etrade/
│ ├── __init__.py
│ ├── etrade.py
│
├── model/
│ ├── __init__.py
│ ├── model.py
│
├── tests/
│ ├── __init__.py
│ ├── test_authentication.py
│ ├── test_etrade.py
│ ├── test_model.py
│ ├── test_utils.py
│
├── utils/
│ ├── __init__.py
│ ├── fake_data.py
│ ├── logging_config.py
│
├── .gitignore
├── chromedriver.exe
├── msedgedriver.exe
├── main.py
├── strategy.py
Everywhere else in my project where I import authentication.py module, it import fine using the line:
from authentication.authentication import Authentication
Both my Anaconda Prompt and PyCharm IDE are using the same environment etradebot. Why does my test work in PyCharm but not Anaconda Prompt? Any suggestions are greatly appreciated.
I tried running python test_authentication.py in Anaconda Prompt and expected the unit test to run normally. Running test_authentication.py in PyCharm (Shift + F10) did work. I double-checked that both my Anaconda Prompt and PyCharm were using the same Anaconda environment etradebot, and they are. So I am confused.

pytest no module named common

I'm trying to get started with python and pytest, I have the following project structure :
.
├── my_module
│ ├── __init__.py
│ ├── common
│ │ ├── __init__.py
│ │ └── utils.py
│ └── my_script.py
└── test
├── __init__.py
└── test_my_script.py
When I run tests (using pytest), I get an error:
no module named 'common'.
I have also the following all configs files:
tox.ini
setup.py
setup.cfg
pyproject.toml
someone know what I missed?
EDIT
here is how I import utils from test_my_script.py :
from common.util import func1,func2
common.util module is not accessible from your test execution because it is located in my_module package.
You should use import starting from working directory which is your project root.
Consider using following import instead:
from my_module.common.util import func1, func2

Python venv shim shebang absolute path not working

EDIT:
This appears to be a shebang character limit issue. The workaround appears to be to create a wrapper script. If anyone has a better solution I'm all ears!
I'm building a CLI tool, i'm using virtualenvironment to build my package and create a command I can execute from the command line. I followed the guides from click here:
https://click.palletsprojects.com/en/8.1.x/setuptools/
I'm using pip install -e . to install the package.
I can see the ./venv/bin directory in my $PATH
I can see the shim for the cli in the ./venv/bin directory (see tree below)
running where cli gives me: <full path to venv>/venv/bin/cli so its on my path
If I try to run cli then i get cli: Command not found.
If I replace the shebang in the generated cli shim with #!/usr/bin/env python then it works!
I have tried setting the permissions to 777, this doesn't resolve the issue.
First question is why doesn't the default shebang work, second question is either how to resolve that issue or default to using #!/usr/bin/env python as the shebang?
I've put some more info about my environment etc below:
My environment:
shell is tcsh (cant switch)
Python 3.8.2
rhel 7
simple test dir structure is as follows:
.
├── cli_test
│ ├── __init__.py
│ └── cli.py
├── cli_test.egg-info
│ ├── dependency_links.txt
│ ├── entry_points.txt
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── venv
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── cli
│ │ ├── easy_install
│ │ ├── easy_install-3.8
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.8
│ │ ├── python
│ │ └── python3
│ └── pyvenv.cfg
└── setup.py
cli.py:
def cli():
print("Hello world")
setup.py:
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(
name="cli_test",
version=0.1,
packages=find_packages(),
python_requires='>=3.8',
install_requires = [
"Click"
],
entry_points = {
'console_scripts': [
'cli=cli_test.cli:cli'
],
},
)
The generated cli shim:
#!<full path to my venv>/venv/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'cli-test','console_scripts','cli'
__requires__ = 'cli-test'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('cli-test', 'console_scripts', 'cli')()
)

ImportError: No module named <module name> for local module imports in Python

I am very new to Python and I have the following structure for a project:
server/
├── config/
│ ├── __init__.py
│ ├── application.py
│ ├── dev.py
│ └── qa.py
├── lib/
│ ├── __init__.py
│ ├── redisdb.py
│ ├── logger.py
│ └── geo.py
└── scripts/
├── __init__.py
├── my_first_script.py
└── my_second_script.py
and in my_first_script.py file, I have the following code:
import pickle
from lib.redisdb import r
import re
import config.application as appconf
print( appconf.DOCUMENT_ENDPOINT )
partnerData = pickle.loads(r.get("partner_date_all"))
print( len(partnerData) )
When I run this code in the terminal using the command
python server/scripts/my_first_script.py
I am getting the following error:
Traceback (most recent call last):
File "my_first_script.py", line 3, in <module>
from lib.redisdb import r
ImportError: No module named lib.redisdb
I am using Python 2.7 version here. When I checked with Python 3 also, I have the same error. Now how can I execute this file? If my code doesn't have imports from the other local modules, everything works just fine.
Your modules are all siblings and you didn't not declare a parent package.
You could modify your structure this way so your modules can know each other.
server/ (assuming this is your project root)
server/ (assuming you want to call your package "server")
├── __init__.py
├── server.py (your package entry point)
├── config/
│ ├── __init__.py
│ ├── application.py
│ ├── dev.py
│ └── qa.py
├── lib/
│ ├── __init__.py
│ ├── redisdb.py
│ ├── logger.py
│ └── geo.py
└── scripts/
├── __init__.py
├── my_first_script.py
└── my_second_script.py
And now your imports can refer to the parent package:
for example:
# my_first_script.py
from server.config import application

Python/Django "Import Error" in project directory

I've been having troubles with this and cannot find the solution... I've browsed all SO questions about this but nothing worked in my case... So here's the problem:
I clone a project from git repository
Set up a virtualenv called env in project base dir with proper Python version(2.7) & install all reqs succesfully
Here's where it gets fun... I navigate to the folder that has my manage.py and do a python manage.py makemigrations which results in
from foo.bar.data import CoolioClass
ImportError: No module named foo.bar.data
My directories look like this (just for illustration):
project_root/
├──env/
├──django/
│ ├── app
│ │ └── models.py (from foo.bar.data import CoolioClass)
│ ├── django
│ │ └── settings.py
│ └── manage.py
└──foo/
├── bar
│ ├── __init__.py
│ ├── data.py
│ └── test.py
├── baz
│ ├── __init__.py
│ ├── data.py
│ └── test.py
└── __init__.py
When I print sys.path in python shell it results in:
/home/johnny/project_root/env/lib/python2.7
/home/johnny/project_root/env/lib/python2.7/plat-x86_64-linux-gnu
/home/johnny/project_root/env/lib/python2.7/lib-tk
/home/johnny/project_root/env/lib/python2.7/lib-old
/home/johnny/project_root/env/lib/python2.7/lib-dynload
/usr/lib/python2.7
/usr/lib/python2.7/plat-x86_64-linux-gnu
/usr/lib/python2.7/lib-tk
/home/johnny/project_root/env/local/lib/python2.7/site-packages
/home/johnny/project_root/env/lib/python2.7/site-packages

Categories

Resources