python import from .pyfile and from pyfile generate errors - python

I have my flask web application with 2 python.py files in the same directory like below:
app.py
afile.py
def foo():
app.py imports foo() like below (this runs fine in my local MacOS)
app.py
from afile import foo
However, in my server(Ubuntu22.10), I have to import foo with . in front of the module like this (otherwise I get an error):
app.py
from .afile import foo
But if I use the . in my Mac, I got an error.
I want to keep my code as consistent as possible. Could anyone kindly point out a solution?
Local environment: MacOS 12.6, python3.7, source codes in local user directory
Server: Ubuntu22.10, python3.10, source codes in /var/www apache2 folder

Related

Cant import from file in python

I am running a Flask server in Docker and cannot import create_app from app.py into my integration tests. I've tried a variety of naming approaches but Python is unable to find app.py.
The directory structure is as follows
/server
/test/integration/test.py
app.py
test.py has this import
from app import create_app
I tried relative imports as well but there was a "parent" error. I then played around with empty __init__.py files in an attempt to use relative imports. That didn't work. I am not sure why this is so involved to do really. What is the solution for this?
In test.py add:
# some_file.py
import sys
# caution: path[0] is reserved for script path (or '' in REPL)
sys.path.insert(1, '/path/to/app/folder')
import app
from app import create_app
This add the directory of the source file to the system so Python will know to go there when searching the things to import. This is true when both files are local on your computer. If there is a server you need to see how you modify the in-server Python environment to know the folder of the app.py file.
See: Importing files from different folder
You can try with relative imports
from ..app import create_app

How to import app file into test file in different directory Python

apologies if I'm going about this wrong, but I am quite new to python and can't quite figure out what the problem is! I have a simple Flask app that I'm trying to write tests using pytest for. The file structure is like this:
│── app.py
|── tests
│ ├── tests_app.py
I originally had app.py and tests_app.py in the same level and it all worked fine with tests passing, but now I have put tests in their own folder I can no longer import app without error.
I have tried the following in tests_app.py:
from app import app #this is what worked fine when app and tests were in the same folder
from ..app import app
from .. import app
and the linting error is 'Attempted relative import beyond top-level package' and when I run pytest it says 'ImportError: attempted relative import with no known parent package'.
Many thanks in advance!
p.s. I am using Python 3.8.5
You need to have app on the module search path. A quick fix would be to add the path to app.py to the PYTHONPATH environment variable:
export PYTHONPATH=/path/to/dir # where app.py is
If app.py is on the python path, then import app will work (barring any other import problems such as circular imports).
An effective and reproducible way to do this is to install your application. You can do this in develop mode, which means the code runs from its current directory. This is an understated, important part of developing a Python application, but to do it you will need to write code to package your application.

importing from another folder in virtualenv

I'm following the Flask Mega Tutorial, and I'm running into an issue once I get to the second part and restructure my folder structure to match theirs, I cannot import Flask.
My current folder structure is as follows
/FlaskTest
/app
/static, templates etc
/flask
/virtualenv folders etc
/tmp
run.py
as far as I can tell, the folder structures are identical other than naming of the top level directory.
in my __init__.py file (/app/__init__.py), I'm doing as instructed in the tutorial,
from flask import Flask
app = Flask(__name__)
from app import views
I'm getting an Import Error that "cannot import name 'Flask'". I'm guessing the issue is because the flask package was installed to /flask/lib/site-packages.
My question: How can I reference the sub folder of flask/site-packages?
I've read through the python import system documentation and from what I can make of it through the first pass of reading it over, I would need to likely do something like from flask import flask.Flask or something to that effect.
UPDATE: So after cd'ing around the directory and checking pip list, I realized that flask wasn't accessible to my app directory. I ran pip install flask in the app directory. Now my site runs, but I'm not sure if this is the best practice of doing things with Python. Please provide some clarity as what the best practice is for installing packages and where the packages reside.
UPDATE 2: After creating a directory called standalone. In this folder, I created a virtual environment called standalone-test. Once, I did that, I also mkdir'ed app and copied it's contents from FlaskTest so that way the code would be identical. I was able to run the run.py script by using python run.py, but I can't run python -m app like you had said without running into an error. The error is as follows if it helps.
"No module name app.main; 'app' is a package and cannot be directly executed.
I am able to run python run.py as I mentioned, but I'm not able to run the python -m app command as you had mentioned
I think something went wrong in your execution environment. Here are some explanations.
The virtualenv
See the documentation of virtualenv
If you have followed the tutorial:
The flask directory is your virtualenv,
On posix system, you have a flask/bin subdirectory, or
On Windows system, you have a flask\Scripts subdirectory.
I make the assumption that you are on posix system.
To activate your virtualenv, run:
source flask/bin/activate
Your prompt should change to something like: (flask)$.
To list the installed libraries use pip:
pip list
Make sure you see Flask. The tutorial encourages you to install a lot of Flask plugins, so there are a lot of Flask-Something…
If Flask is missing, install it:
pip install Flask
Run your app
Your application is in the app directory, it has an __init__.py file (it's a Python package).
In this file, you have:
from flask import Flask
app = Flask(__name__)
from app import views
From your FlaskTest/ directory, try to run this script like this:
cd FlaskTest/ # if not in this directory
python -m app
This should import Flask, instanciate your app (but don't run it), import the views module.
If app/views.py exist you should have no error.
=> at this point, we have simulated what run.py imports…
Now write run.py in your FlaskTest/ directory:
#!flask/bin/python
from app import app
app.run(debug=True)
Run it like this:
python run.py
Note that the shebang #!flask/bin/python is unusual, but should work in the context of the tutorial.
This should start your http server…

Python package missing when deploying

On my development (Win7) machine, my app runs fine. The folder structure looks like this (the script being run is run.py below):
package1/
__init__.py
run.py
..
Inside the app, there are some modules which do stuff like
import app from package1
Which works fine.
However, when I try deploying to a linux machine, and run that exact same file, I get an error:
ImportError: No module named package1
I looked into the sys.path of both machines when this script is being run. The first two lines of the windows machine are these:
C:\\Users\\USERNAME\\IdeaProjects\\PROJ_NAME\\package1
C:\\Users\\USERNAME\\IdeaProjects\\PROJ_NAME
Whereas the linux one only has this:
/home/username/webapps/PROJ_NAME/package1
I recognize the problem is that the second line is missing. But why is it missing? What am I missing? Did I build the folder structure wrong?
This is a crappy solution, and I don't like it, but it works.
I added this to run.py
# Fixing the python path
import sys
import os
file_location = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.abspath(os.path.join(file_location, os.pardir))
if not project_dir in sys.path:
sys.path.insert(0, project_dir)

django import local settings from the server

In my home directory, I have a folder called local. In it, there are files called __init__.py and local_settings.py. My django app is in a completely different directory. When the app is NOT running in DEBUG mode, I want it to load the local_settings.py file. How can this be acheived? I read the below:
Import a module from a relative path
Importing files from different folder in Python
http://docs.python.org/tutorial/modules.html
Basically, those tutorials are allowing to import from another directory, but what about a completely different working tree? I don't want to keep doing .., .., .. etc. Is there a way to goto the home directory?
I tried the following code:
import os, sys
os.chdir(os.path.join(os.getenv("HOME"), 'local'))
from local_settings import *
But i keep seeing errors in my apache error.log for it...
os.chdir just affects the current working directory, which has nothing whatsoever to do with where Python imports modules from.
What you need to do is to add the the local directory to the Pythonpath. You can either do this from the shell by modifying PYTHONPATH, or from inside Python by modifying sys.path:
import sys
import os
sys.path.append(os.path.expanduser("~/local"))
import local_settings
In response to your concerns about source control, you can just set the source control to ignore that file, and/or have a symlink installed as part of your deploy script to link the file on the os into another. I do both , though not in django. but it's a trivial task.
your deploy layout could look like this:
/current ( symlink to /releases/v3 )
/settings/local_settings.py
/releases/v1
/releases/v2
/releases/v3
and a task runs as part of your deploy:
cd /current
ln -s /settings/local_settings.py local_settings.py
if you're deploying with fab or capistrano, it's a few lines of configuration. i'm sure you could do this with puppet/chef simply too.

Categories