How to run exported python package from within? - python

I took a few days to understand pip install workflow, and now that I'm aware of at list main problems, I'm facing this import issue that I just can't find a workaround.
I have this minimum executable example:
packagetest/
__init__.py
main.py
aux.py
setup.py
aux.py
class Aux:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
main.py
from packagetest.aux import Aux
def printAux():
print(Aux('aux1'))
if __name__ == "__main__":
printAux()
setup.py
from setuptools import find_packages, setup
setup(
name='packagetest',
version='0.1',
packages=find_packages(),
)
That's it. That's my python package.
Then I run pip install . and in another project, let's say project2.py, I can call:
from packagetest import main
main.printAux()
and that's my output:
aux1
Everything works perfectly, except not. If I run pip uninstall packagetest, go into my packagetest/ folder and then try to run python main.py I catch this error:
Traceback (most recent call last):
File "main.py", line 1, in <module>
from packagetest.aux import Aux
ModuleNotFoundError: No module named 'packagetest'
That's because my packagetest is not installed and python can't find packagetest when i'm importing it with from packagetest.aux import Aux. if I change it to from aux import Aux it works perfectly, but in this case I can't export this project using pip install because aux will not be recognized as a module. I tried and I catch this another error on project2.py:
Traceback (most recent call last):
File "project2.py", line 1, in <module>
from packagetest import main
File "/home/leonardo/.local/lib/python3.8/site-packages/packagetest/main.py", line 1, in <module>
from aux import Aux
ModuleNotFoundError: No module named 'aux'
My question is how to make my project executable without installing it? I want an import that works in both cases, and don't want my modules to be executable only it my package is installed inside pip packages. I wan't to clone my repo and execute my project in a new machine without being forced to install in via pip.
Is it possible? How big projects handle that?

Related

Setup.py ... breaks when name and py_modules are different

I'm trying to get an in depth understanding of a bare minimum python package. As a setup.py this works perfectly:
from setuptools import setup
setup(
name='helloworld',
version='0.0.1',
description='Say hello!',
py_modules=['helloworld'],
package_dir={'': 'src'},
)
Again, I can import and run "helloworld" just fine. However, when I change "name" and "py_modules" to be something different from each other the system breaks. According to Mark Smith's EuroPython lecture "name" is what you pip install and "py_modules" is what you import.
from setuptools import setup
setup(
name='installMe',
version='0.0.1',
description='Say hello!',
py_modules=['importMe'],
package_dir={'': 'src'},
)
So I installed the software in a python virtual environment:
python3 -m venv bareMinEnv
source bareMinEnv/bin/activate
pip install -e .
and everything looked fine:
pip list
Package Version Location
---------- ------- ------------------------------------------------------------------
installMe 0.0.1 /mnt/d/PROJECTS/PACKAGE_CREATION/min2/bareMinimumPythonPackage/src
pip 20.2.3
setuptools 49.2.1
However, it breaks at the importation step. Here it show's I can't import "importMe":
>>> from importMe import say_hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'importMe'
and here is evidence I can't import "installMe":
>>> from installMe import say_hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'installMe'
All of this works if I keep the names the same. So how to I make them different while maintaining functionality? I've created a dozen packages and I don't understand why it's not behaving as I believe the documentation describes. Again, this is easy to fix by keeping the names the same. However, I'm trying to understand every detail about the pip packaging system. Thanks in advance.

Getting an error for a module that I definitely imported

import pyinputplus as pyip
while True:
prompt='Want to know how to keep an idiot busy for hours?\n'
response=pyip.inputYesNo(prompt)
if response=='no':
break
print('Thank you. Have a nice day.')
When I run my above code , I get this error:
Traceback (most recent call last):
File "c:\users\XXXXXX\mu_code\idiot.py", line 1, in <module>
import pyinputplus as pyip
File "c:\users\XXXXXX\mu_code\pyinputplus\__init__.py", line 15, in <module>
import pysimplevalidate as pysv # type: ignore
ModuleNotFoundError: No module named 'pysimplevalidate'
I cannot figure it out. The module is definitely installed. I've even moved it from the folder it was originally installed in to the mu folder where the py file is saved. Any help would be appreciated.
The ModuleError says that you do not have pysimplevalidate installed.
Using the same python executable as you are using to run your script (idiot.py), run
python -m pip install pysimplevalidate
or, even more bullet-proof:
<path_to_python.exe> -m pip install pysimplevalidate
If you are not sure what python executable the script is using, you can check it with
# put this on top of your script
import sys
print(sys.executable) # will print C:\path\to\python.exe

How to dynamically pip install a .whl file from python code and then use the library

I am trying to pip install a .whl file dynamically (the name of the file will change each time I run it) and import it from the same python script. I tried running it in a different subprocess but I am not able to access the import from within the same file. I think python's importlib might have the answer but I haven't been able to figure it out.
import subprocess
import sys
#staticmethod
def install_file(lib):
subprocess.check_call([sys.executable, "-m", "pip3", "install", lib])
# pip install the whl
install_file(whl_file_name)
# dynamically get the name of the .whl file and import it
whl = __import__(whl_file_name)
whl.do_something()
returns the following error
Traceback (most recent call last):
File "<stdin>", line 12, in <module>
ModuleNotFoundError: No module named 'name_of_whl_file'
I had a similar problem. Solved it this way:
def install_file(package: str):
subprocess.check_call([sys.executable, "-m", "pip", "install", "--no-cache-dir", "--no-index", "--find-links", "whlFolder", package], shell=True)
This method installs de package from the package name (e.g: 'tensorflow') instead of the filename, searching for the lib file in folder 'whlFolder'.
The package parameter must be informed with the package/ library name and the version (optionally). E.g:
#Installing the latest available version
install_file('tensorflow')
#Installing a specific version
install_file('tensorflow==2.2.0')

Import a file within the same package python

I'm using Python 3.6
my file structure:
ACS-backend
ACS
-__init__.py
-main.py
-VCDN.py
bin
data
docs
venv
weights
-.gitignore
-requirements.txt
-setup.py
I'm trying to import VCDNN in my main.py with from ACS.VCDNN import VCDNN I have tried with just .VCDNN from VCDNN and just VCDNN from VCDNN the last one used to work before ive added the ACS folder.
To run it from cmd i simply do venv/Scripts/activate.bat to activate my current VENV and then just python main.py and the error I get is:
Traceback (most recent call last):
File "main.py", line 5, in <module>
from ACS.VCDNN import VCDNN
ModuleNotFoundError: No module named 'ACS'
Though when running from PyCharm i see that it executes:
C:\work\COMP1682\ACS-backend\venv\Scripts\python.exe C:/work/COMP1682/ACS-backend/ACS/main.py
which works fine, but when I run the exact same command from my CMD it still gives me the same error.
Try from .VCDN import VCDNN, that would be correct relative import.

ModuleNotFoundError: No module named 'bayesnet'

I'm trying to use the OpenBayes module, but the problems start from the very first step :'(
When I try to import from OpenBayes
I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Мари\AppData\Local\Programs\Python\Python36\lib\site-packages\OpenBayes\__init__.py", line 7, in <module>
from bayesnet import *
ModuleNotFoundError: No module named 'bayesnet'
UPD: While installing (from .exe file) for py2 i gor error: "could not set a key value" (not a python error, but in dialog window)
I tried using pip install from console, but still get errors there.
Command "python setup.py egg_info" failed with error code 1 in C:\Users\CD3B~1\AppData\Local\Temp\pip-build-m4nnwa4o\OpenBayes\
Also not sure which py (2 or 3) is used when i type a command from console(
(Sorry for all that stupis questions)
You should
from OpenBayes import *
or
from OpenBayes import BNet
Here is an example demonstrating it's usage:
https://github.com/willasaywhat/OpenBayes-Fork/blob/master/Examples/bn_asia.py
I had the same problem and I created a directory with the same name as the root folder (within the root folder). Python then referred Its import calls to the src directory and not the folder. I also changed the python interpreter to a virtual (anaconda.exe), as the python install did not contain many of the modules that were being called by the application (flask, etc)
It's a weird workaround, but it worked for me. Hope this helps

Categories

Resources