Modules organization for deploying in Python - python

I am currently working on a Flask application. I would like to organize my .py files in different folders. This is a three that can describe all the folders.
Application
|_Interpreter
|_
__init__.py
parser.py
|_ Classes
|_ Interfaces
__init__.py
Expressions.py
|_ Operations
__init__.py
Arithmetic.py
Operations.py
|_ SymbolTable
__init__.py
Symbol.py
Symbol_table.py
__init__.py
Driver.py
From my knowledge, the __init__.py makes the folder a module, then you should be able to import them from another files.
For example, from the file Operations.py I want to import Expressions.py. This is how I would do it:
from Classes.Interfaces.Expression import Expression The issue is that I keep getting a ModuleNotFoundError: No module named 'Classes' I've tried to use
import sys
sys.path.append('\..')
But it doesn't work all the times, in the example given it doesn't work.
I know that I can append the path of the file in my computer, but I think that it will produce some issues if I want to deploy an application to a server. Which is the best option to import modules?

Have you tried adding an __init__.py to you Application folder?
You might want to use from Application.Classes.Interfaces.Expression import Expression then.

Related

"ModuleNotFoundError" when importing modules inside package

I am trying to make my own package so that I can use the files in a different folder. This package contains a few different modules and then the main module that imports all the others inside it. For example:
Folder
|- main.py
|- other.py
|- something.py
|- __init__.py
Inside the main.py I have the imports:
import other
import something
and it works just fine when running the file itself; however, I added the __init__.py file and tried to import it into a different folder. The package is recognized, but the main.py gives me the following error:
Exception has occurred: ModuleNotFoundError No module named
'univariate'
File "C:...\stats.py", line 8, in
import univariate
File "F:...\testing.py", line 7, in
from stats import stats
For clarification, the actual main file is called stats.py. This is my first experience trying to make a package so I might be missing something. Thank you.
You need to change your imports into relative imports
import .other
import .something
or to change it to absolute imports rooted to your project folder
import x.y.other
import x.y.something
you can read here about the imports
When you have a module that you're trying to import you don't need the ".py" part.
Having a folder with a init.py file (even a blank one) means that a project that contains that folder can import from it.
/myproject
| - /mymodule
| - |- stats.py
| - |- other.py
| - |- something.py
| - |- __init__.py
| - main.py
then in main.py all you need to do is import mymodule or from mymodule import stats
I always hate to FTFM someone, but here's a link to how to build packages from the official documentation. But, where this really starts to shine is when you need to package your module so that someone else can run it Digital Ocean has a pretty good tutorial here.

What is the correct way to use unittest in python with the test modules in a directory inside the main package?

I am currently developing a python package with 3.7.1 and am trying to use unittest with a /test directory containing test modules, which will then contain multiple test cases. I am trying to use the following directory structure:
|_ app/
|_ main.py
|_ my_module/
|_ MyPackage.py
|_ test/
|_ test_MyPackage.py
Inside test_MyPackage.py I am trying to import the required class from MyPackage using from my_module.MyPackage import MyClass as if the module was placed inside the app/ directory but this does not work as the import fails. I know that imports in python don't work like this, and tried it after reading the same question at Running unittest with typical test directory structure which appears to be outdated. I have also read that using python -m unittest should work provided that the test cases are in a /test directory and named test_*.py, but this did not work either, and outputs "Ran 0 tests in 0.000s".
So far the only way I'm able to use my unit tests is to move them to the app/ directory each time I want to run them. Would anybody be able to advise me on the how to use unittests in a separate directory like this without moving them to the app/ directory or importing them with a separate test module permanently inside the app/ directory?
This is working now, I added an __init__.py file in the test/ directory and the tests all ran successfully when using python -m unittest. I thought this file wasn't required after Python 3.3 but it appears that unittest doesn't work correctly without it

Import error using relative import syntax

I have a project structured like so:
/proj
main.py
config/
__init__.py
setup.py
gui/
__init__.py
app.py
The program is run by calling python main.py.
In main.py I have from gui import App.
In gui/__init__.py I have from .app import App.
Lastly, in app.py I have from ..config import configure; this throws a ValueError that reads attempted relative import beyond top-level package. To resolve this, I can alter the strucure:
/proj
main.py
proj/
config/
__init__.py
setup.py
gui/
__init__.py
app.py
But then I have to change the import statments to include proj (i.e. from proj.gui import App). Is it possible to use relative imports in the former case with the current structure? If not, how can I import what I need from the config subpackage?
As strange as it sounds, you can do :
from config import configure
in app.py, for your former case (current structure), because when you run python main.py, it interprets config as the next level package, and .. won't work.
(Btw, I think there is lots of room for Python imports to improve. The current PEP 328 is confusing at best).

Import method from __init__.py

Having some issues with importing modules in python. This is my folder structure
my_app/
app.py
__init__.py (I want to import a function from this file)
folder1/
__init.py
method1.py
folder2/
__init__.py
method.py
In my root __init__.py I have this function
def want_to_be_run_elsewhere():
pass
In my app.py, I want to import this function and run it when I start my application, but I'm unsure how to do it.
from my_app import want_to_be_run_elsewhere
This throws a no module named my_app
From what I can tell, I have all the necessary __init__.py files, so maybe it could be sys.path related?
I've read some similar threads on here but I haven't been able to solve this.
Usually you would do the import like
from . import want_to_be_run_elsewhere
This doesn't work here, because you are calling app.py. If you import my_app.app, it is part of the module. If you call it it is not. Importing from the module it is in using . will then not work.
You could either move app.py outside of my_app, removing it from the module and making imports work again.
Or you can use
from __init__ import want_to_be_run_elsewhere
in app.py
I believe
from my_app import want_to_be_run_elsewhere
will only work if you have actually pip install -e my_app/. Then it should work too.

PyCharm auto-import Fails To Import Properly

I have an app structured like so:
api/
|_app/
|_ __init__.py
|_conf/
|_resources/
|_ __init__.py
|_controller.py
|_dao/
|_ __init__.py
|_thing_dao.py
|_etc...
I want to use the function get_thing_by_id in thing_dao.py inside of controller.py. In PyCharm I start to type get_thing_by_id and it prompts me to auto-import the function. The problem is it simply does from thing_dao import get_thing_by_id but when I attempt to run the app (Flask) I get ImportError: No module named 'thing_dao'. What I end up having to do is a relative import or start at the module level from app.dao.thing_dao import get_thing_by_id.
I suspect this issue is related to my project structure and less of a PyCharm bug. Is there a way I could structure my project to better hint to PyCharm how to do imports? I've looked through the configuration option for auto-imports and PyCharm and they're quite slim so I suspect that I'm doing something wrong.
I discovered I had my directories marked as a "Source Root". Unmarking them made the imports work properly.

Categories