0

Summary: My goal: working on upload from mod1.py. I expect the uploaded file at /static/img/. However, there is nothing happens when tried

I have never done this procedure before. What I want is to be able to import and reuse function from mod2 in mod1. The mod1 is main. Both modules are in a same root folder. I don't use django. I put an empty init.py on the same directory. Please help suggest a specific ideas relate to mod2.

the structure

root/
    __init__.py

    mod1.py

    mod2.py

mod1 (a working .py):

from flask import Flask, redirect, render_template, request, url_for

app = Flask(__name__)
app.config["DEBUG"] = True

comments = []

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("main_page.html", comments=comments)

    comments.append(request.form["contents"])
    return redirect(url_for('index'))

mod2 (a working .py):

import os
#from flask import Flask, flash, request, redirect, url_for
from flask import Flask, flash, redirect, render_template, request, url_for

from werkzeug.utils import secure_filename
from flask import Request
from flask_uploads import IMAGES, UploadSet, configure_uploads



UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'docx'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024


photos = UploadSet("photos", IMAGES)
app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
configure_uploads(app, photos)


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'photo' in request.files:
        photos.save(request.files['photo'])
        flash("Photo saved successfully.")
        return render_template('upload.html')
    return render_template('upload.html')


from flask import send_from_directory

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)


from werkzeug.middleware.shared_data import SharedDataMiddleware
app.add_url_rule('/uploads/<filename>', 'uploaded_file', build_only=True)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
    '/uploads':  app.config['UPLOAD_FOLDER']
})

What I tried on mod1:

import os
from flask import Flask, flash, redirect, render_template, request, url_for

from werkzeug.utils import secure_filename
from flask import Request
from flask_uploads import IMAGES, UploadSet, configure_uploads

from mod1 import getPhotos
from mod1 import upload

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'docx'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

photos = getPhotos()

app.config["UPLOADED_PHOTOS_DEST"] = "static/img"
app.config["SECRET_KEY"] = os.urandom(24)
configure_uploads(app, photos)

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

upload()

"""
#as a function
@app.route('/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'photo' in request.files:
        photos.save(request.files['photo'])
        flash("Photo saved successfully.")
        return render_template('upload.html')
    return render_template('upload.html')
"""
from flask import send_from_directory
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

from werkzeug.middleware.shared_data import SharedDataMiddleware
app.add_url_rule('/uploads/<filename>', 'uploaded_file', build_only=True)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
    '/uploads':  app.config['UPLOAD_FOLDER']
})

There is no error. When I open the /static/img, nothing happens. My research on these pages are not solved: What is __init__.py for? And https://realpython.com/python-modules-packages/

Am I in the right direction? What are your suggestions? Thank you very much for your specific suggestion.

2 Answers2

0

Firstly, I don't see where you've tried to import mod2 in mod1. But python, allows relative imports. For your case from .mod2 import xxx should work.

If you want to compose your you Flask application, you should not create an app in each file, but instead blueprints, and register those in your single Flask app.

ljmc
  • 4,830
  • 2
  • 7
  • 26
  • I am sorry. The above codes "**what I tried on mod1**" have been edited to "from mod2 import ..." Thank you for your comment. Did you mean only use one app = Flask(__name__) in mod2.py ? – Kamus Suwanto Aug 13 '22 at 10:39
  • Over your entire app, `mod1`, `mod2`, etc, there should be a single `app = Flask(__name__)`, then you can register blueprints with this app. – ljmc Aug 13 '22 at 10:45
  • nice. This is the first point I learn about import. I will consider blueprint for the next. Thanks again – Kamus Suwanto Aug 13 '22 at 10:57
0

I think you are trying to import variables from mod2 which is not possible, you might want to turn that into a function like this:

photos = UploadSet("photos", IMAGES)
def getPhotos(photos = photos):
    return(photos)

Then you can import the getPhotos function and use it like so:

from mod2 import getPhotos
photos = getPhotos()

Instead of importing UploadSet and configure_uploads from mod2, import them from flask.

from flask_uploads import UploadSet, configure_uploads
mepro
  • 31
  • 3
  • mepro, it works after applying your codes. The above code, **what I tried on mod1**, has been edited to a working one. In addition to edit the codes, I altered the wsgi.py file in pythonanywhere to **from mod2 import app as application**. Thank you so much for this valuable point. At this moment I can't rate your post, not enough point. I will come back. – Kamus Suwanto Aug 15 '22 at 08:18
  • Also, I added your function in mod2 for it to work: **photos = UploadSet("photos", IMAGES) def getPhotos(photos = photos): return(photos)** – Kamus Suwanto Aug 15 '22 at 08:29
  • I am glad it works for you and that I could help. – mepro Aug 27 '22 at 15:33