I have a Flask application that is constructed as following:
--- /app
------ /__pycache__
------ /static
--------- /files
--------- /assets
--------- /images
------ /templates
------ api.py
------ utils.py
------ config.py
------ sftp.py
--- wsgi.py
wsgi.py:
from app.main import app
if __name__ == "__main__":
app.run()
main.py:
from flask import Flask, render_template, request, session, flash, url_for, redirect
from werkzeug.utils import secure_filename
from .utils import *
from .config import *
from .sftp import sync_work_days
app = Flask(__name__)
app.secret_key = b'very_secret_key'
[...]
config.py:
import os
from wsgi import app
ROOT_PATH = app.instance_path
sftp.py:
import pysftp as sftp
from .config import *
from .utils import upload_working_days
import time, os
from datetime import datetime
from config import ROOT_PATH
def sync_work_days():
cnopts = sftp.CnOpts()
cnopts.hostkeys = None
s = sftp.Connection(host=SFTP_HOSTNAME, username=SFTP_USERNAME, password=SFTP_PASSWORD, cnopts=cnopts)
print("Connection succesfully established...")
remoteFilePath = '/files/company'
files = s.listdir_attr(remoteFilePath)
if files == []:
return "empty"
else:
for f in files:
localFilePath = os.path.join(ROOT_PATH, 'static/files/company')
# s.get(remoteFilePath, localFilePath)
upload_working_days(localFilePath)
time.sleep(5)
print("UPLOAD DONE")
s.rename(remoteFilePath f, remoteFilePath "/archives/" f)
When I run the app, I get the following error:
from wsgi import app
ImportError: cannot import name 'app' from partially initialized module 'wsgi' (most likely due to a circular import) (D:\[...redacted...]\wsgi.py)
All I want to do is to download a file via SSH and put it in app/static/files, and I can't just hardcode the path because the deployment environment is different.
UPDATE 1: I tried to cut off config.py from the loop and I made the following changes:
sftp.py:
import pysftp as sftp
from .config import *
from .main import app
from .utils import upload_working_days
import time, os
from datetime import datetime
def sync_work_days():
cnopts = sftp.CnOpts()
cnopts.hostkeys = None
filename = os.path.join(app.instance_path, 'my_folder', 'my_file.txt')
And this is the error I get:
ImportError: cannot import name 'app' from partially initialized module 'app.main' (most likely due to a circular import) (D:\[...redacted...]\app\main.py)
CodePudding user response:
You have a circular import because you are importing app in config.py from wsgi.py, which gets it from main.py which imports config.py.
And you are importing app in config.py because you need a setting from it. Have you considered keeping all your settings in config.py and importing them in main.py from there? That seems like a logical thing to do.
CodePudding user response:
The solution to this problem is the following:
In sftp.py, replace:
from .main import app
by:
from . import main
and instead of using app.instance_path
, use main.app.instance_path