Upload image to folder with Flask - python

I have a flask app to let a user upload a picture. I want to be able to save that picture into a folder. However, the console returns an error. The path is correct, so I am not sure what am I missing:
Error:
/c/UOMDataAnalytics/MINSTP201902DATA4/Homework/VisualizePictures/OldPortsApp/static/Images/uploads/WIN_20140917_095804.JPG
Flask code:
import os
import pandas as pd
import numpy as np
import sqlalchemy
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
from flask import Flask, jsonify, render_template,make_response,url_for
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename
from flask import request, redirect
app = Flask(__name__, static_url_path='/static')
UploadDir="/Images/uploads/"
# image upload route
#app.route("/upload-image", methods=["GET", "POST"])
def upload_image():
app.config["IMAGE_UPLOADS"] = UploadDir
# print (app.config["IMAGE_UPLOADS"])
if request.method == "POST":
if request.files:
image = request.files["image"]
image.save(os.path.join(app.config["IMAGE_UPLOADS"], image.filename))
print(image.filename)
return redirect(request.url)
return render_template("public/upload_image.html")
if __name__ == "__main__":
app.run()
I would expect to see the uploaded picture on the upload directory. I want to deploy this to heroku.

I think it's an issue with path. just try to replace this line
image.save(os.path.join(os.path.abspath(__file__),'..', UploadDir, image.filename)).
I think It'll work.

This one worked fine for me!
picture_path = os.path.join(app.root_path, '/Images/uploads/', image.filename)
image.save(picture_path)

Related

TypeError: Blueprint.__init__() got an unexpected keyword argument 'template_folder'

This is what my directory looks like
p/
student/
template/
student/
index.html/
views.py/
__init__.py/
app.py/
this is what my app.py file looks like
from flask import Flask, render_template
from p import app
#app.route("/")
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run()
__init__.py file
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] =
"postgresql://postgres:1234#localhost/studentRegDB"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
Migrate(app, db)
from p.student.views import student_blueprints
app.register_blueprint(student_blueprints, url_prefix='/student')
views.py file
from flask import Flask, request
import psycopg2
from p import db
from p.student.forms import studentform
from p.student.models import Student
from flask import Flask, render_template, url_for,redirect
from flask_blueprint import Blueprint
student_blueprints = Blueprint('student', __name__, template_folder='student')
#student_blueprints.route("/add", methods=["GET", "POST"])
def addstudent():
form = studentform()
if form.validate_on_submit():
name = request.form['name']
course = request.form['course']
new_student = Student(name,course)
db.session.add(new_student)
db.session.commit()
return redirect(url_for("success.html"))
return render_template("student.html", form=form)
when run the code i get the following error
student_blueprints = Blueprint('student', name, template_folder='student')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Blueprint.init() got an unexpected keyword argument 'template_folder'
thank you for your help
You have to be very careful with names. The package flask_blueprint is unrelated to the flask blueprints you get from from flask import Blueprint, and has completely different parameters.
I suggest you pip uninstall flask-blueprint, and change your code to
from flask import Blueprint

Running python with Flask lib but return "Not Found" page

I am completely new to learning webdev stuffs.
I follow a tutorial on how to upload an image with Flask, and here's the program in Python
from flask import Flask, render_template, request, redirect, jsonify, make_response, url_for
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
#app.route("/upload-image", methods=["GET", "POST"])
def upload_image():
if request.method == "POST":
if request.files:
image = request.files["image"]
print(image)
return redirect(request.url)
return render_template("upload_image.html")
if __name__ == "__main__":
app.run()
But when I try to run the Python on the terminal, it returns local http://127.0.0.1:5000/ but when I opened it, it returns
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Where is the mistake, then?

TypeError: storage must be a werkzeug.FileStorage in Flask Upload

So what I did is that I tried to run my flask app but suddenly I got a error which is
TypeError: storage must be a werkzeug.FileStorage
This is the code that I use...
init.py
# IMPORT
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_uploads import UploadSet, configure_uploads, IMAGES, patch_request_class
from blogapp.config import Config
# INIT
db = SQLAlchemy()
bcrypt = Bcrypt()
login_manager = LoginManager()
migrate = Migrate()
login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info'
photos = UploadSet('photos', IMAGES)
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
bcrypt.init_app(app)
login_manager.init_app(app)
migrate.init_app(app, db)
configure_uploads(app, photos)
patch_request_class(app)
from blogapp.users.routes import users
from blogapp.posts.routes import posts
from blogapp.main.routes import main
from blogapp.errors.handlers import errors
app.register_blueprint(users)
app.register_blueprint(posts)
app.register_blueprint(main)
app.register_blueprint(errors)
return app
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY')
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI')
UPLOADED_PHOTOS_DEST = os.path.join(basedir, 'uploads')
I have a uploads folder in my parent directory
routes.py
from flask import (render_template, url_for, flash,
redirect, request, abort, Blueprint)
from flask_login import current_user, login_required
from blogapp import db, photos
from blogapp.models import Post
from blogapp.posts.forms import PostForm
posts = Blueprint('posts', __name__)
#posts.route("/post/new", methods=['GET', 'POST'])
#login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
filename = photos.save(form.photo.data)
file_url = photos.url(filename)
else:
file_url = None
if form.validate_on_submit():
post = Post(title=form.title.data, content=form.content.data, image=form.photo.data, author=current_user)
db.session.add(post)
db.session.commit()
flash('Your post has been created!', 'success')
return redirect(url_for('main.home'))
return render_template('create_post.html', title='New Post',
form=form, file_url=file_url, legend="Post")
Can someone help me?
I'm a bit confuse with how I got the error..
Did I do something wrong?
There isn't any thing I could find out there, so for me this is very confusing..
Could it be something wrong with the application factory while using flask upload?
Traceback
When I have a look at your routes.py, I see some possible problems.
new_post does accept both get and post requests, but does not handle them differently.
e.g. usually when there is a get request, you want to just render the empty form, but when there is a post request, you want to e.g. save the file.
You have two if form.validate_on_submit statements. You can simplify them when you move the else to the bottom, just above the return statement. Actually, you do not need an else path as, when the if path is valid, you leave the function with the return redirect already.
About your problem.
The error message clearly says, that form.photo.data is no uploaded file.
Please fix the above suggestions and try it again.
Also make sure you do not send an empty form. Btw - you did not show your form template. Maybe there is no data field?
If you followed all suggestions, but without success, please set a breakpoint just after e.g. form = PostForm() and carefully step through your program and especially inspect what value form.photo.data shows.
All you have to do is in your HTML file, set the FORM "enctype = multipart/form-data"

Flask: NameError: 'app' is not defined?

My Flask application has been running fine for the last 24 hours, however I just took it offline to work on it and i'm trying to start it up again and i'm getting this error:
Traceback (most recent call last):
File "runserver.py", line 1, in <module>
from app import app
File "/home/MY NAME/APP FOLDER NAME/app.py", line 15, in <module>
from Views import *
File "/home/MY NAME/APP FOLDER NAME/Views.py", line 1, in <module>
#app.route('/contact', methods=('GET', 'POST'))
NameError: name 'app' is not defined
I am running the application currently by calling python runserver.py
runserver.py:
from app import app
app.run(threaded = True, debug=True, host='0.0.0.0')
Views.py: contains all of my routes, I won't post them all, as the error is coming from the first time app is mentioned in this file.
#app.route('/contact', methods=('GET', 'POST'))
def contact():
form = ContactForm()
if request.method == 'POST':
msg = Message("CENSORED,
sender='CENSORED',
recipients=['CENSORED'])
msg.body = """
From: %s <%s>,
%s
""" % (form.name.data, form.email.data, form.message.data)
mail.send(msg)
return "><p><br>Successfully sent message!</p></body>"
elif request.method == 'GET':
return render_template('contact.html', form=form)
app.py: Here is the top of my app.py file, where I define app = Flask(__name__) as well as import my statements.
from flask import Flask, request, render_template, redirect, url_for, send_file
from geopy.geocoders import Bing
from geopy.exc import GeocoderTimedOut
import re
import urllib
from bs4 import BeautifulSoup
from openpyxl import load_workbook
from openpyxl.styles import Style, Font
import os
import pandas as pd
import numpy as np
import datetime
from Helper_File import *
from Lists import *
from Views import *
from flask_mail import Mail, Message
from forms import ContactForm
global today
geolocator = Bing('Censored')
app = Flask(__name__)
EDIT: I have made the changes suggested in the answer below, but am getting this when I access the page:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Here is my file structure:
DHLSoftware.com
|-static
|-style.css
|-templates
|- seperate html file for each page template
|-app.py
|-forms.py
|-helper_file.py
|-Lists.py
|-runserver.py
|-Views.py
In app.py you should remove the from Views import *. Instead in your Views.py you need to have from app import app
That will bring app into the views namespace and I believe that should work for you.

References and URL rules in Flask

I've got a problem with my simple app in Flask. I want to write a registration page, that connect with datebase by SQLAlchemy. I've got app.py file that look like this:
import flask
import settings
import os
from flask_sqlalchemy import SQLAlchemy
# Views
from main import Main
from login import Login
from remote import Remote
from register import Register
#from models import User
#from models import Task
app = flask.Flask(__name__)
app.config['SESSION_TYPE'] = 'filesystem'
app.secret_key = os.urandom(24)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////database.db'
db = SQLAlchemy(app)
# Routes
app.add_url_rule('/',
view_func=Main.as_view('main'),
methods=["GET"])
app.add_url_rule('/<page>/',
view_func=Main.as_view('page'),
methods=["GET"])
app.add_url_rule('/login/',
view_func=Login.as_view('login'),
methods=["GET", "POST"])
app.add_url_rule('/remote/',
view_func=Remote.as_view('remote'),
methods=['GET', 'POST'])
app.add_url_rule('/register/',
view_func=Register.as_view('register'),
methods=['GET', 'POST'])
#app.errorhandler(404)
def page_not_found(error):
return flask.render_template('404.html'), 404
app.debug = True
app.run()
So, as you can see I have URL rules in this file and now I want to use db variable in Register view, so I need import it there, my code for this file looks like this:
import flask, flask.views
from app import db
class Register(flask.views.MethodView):
def get(self):
return flask.render_template('register.html')
def post(self):
new_user = User(username = request.form['username'],
password = request.form['passwd']
db.session.add(new_user)
db.session.commit()
return flask.redirect(flask.url_for('index'))
In that case I get error, cause I have "tied" references, in app file is:
from register import Register
but in Register file is
from app import db
So it, obviously can't work, my solutions is to add URL rule in Register file. But I don't know how. Could you anyone help me?
Sorry for my confusing title, but I just getting started with Flask and I dnon't know how to name it.
You need to move your db assignment to before the imports that expect db to exist:
import flask
import settings
import os
from flask_sqlalchemy import SQLAlchemy
app = flask.Flask(__name__)
app.config['SESSION_TYPE'] = 'filesystem'
app.secret_key = os.urandom(24)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////database.db'
db = SQLAlchemy(app)
# Views
# These can now use
# from app import db
# because that line has executed above
from main import Main
from login import Login
from remote import Remote
from register import Register
#from models import User
#from models import Task
Now when you import the register module and the from app import db line runs, the db variable actually exists in the app module.
Note that you cannot now use app.py as the main script; if you use python app.py then it'll be imported as the __main__ module instead of app module, and using from app import db will create a new module, separate from the main script.
Either use a separate serving script, like serve.py and move your app.run() call into that file:
from app import app
app.debug = True
app.run()
or use from __main__ import db.
You also are missing a closing ) in your register module:
new_user = User(username = request.form['username'],
password = request.form['passwd']
# ^ ^

Categories

Resources