Reload Flask app when template file changes under Linux - python

I am developing a flask application under Linux, and i'm suffering when i make any changes to template files.
Actually i well configured my app to reload on template changes using
TEMPLATES_AUTO_RELOAD = True
PS: when i develop under Windows templates are reloading normally.
EDIT
I am using the built in server, and i run my app like this :
app = create_app()
manager = Manager(app)
#manager.command
def run():
"""Run in local machine."""
app.run(threaded=True)
Here is my configuration class
class DefaultConfig(object):
# Project name
PROJECT = "***"
# Turns on debugging features in Flask
DEBUG = True
# secret key
SECRET_KEY = "**************"
# Configuration for the Flask-Bcrypt extension
BCRYPT_LEVEL = 12
# Application root directory
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
# Application email
MAIL_FROM_EMAIL = "**********"
# Upload directory
UPLOAD_DIR = "static/uploads/"
# Avater upload directory
UPLOAD_AVATAR_DIR = os.path.join(UPLOAD_DIR, 'avatars/')
ALLOWED_AVATAR_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
# Instance folder path
INSTANCE_FOLDER_PATH = os.path.join('/home/karim/OpenXC/Dashboard/Flask', 'instance')
# Cache configuration
CACHE_TYPE = 'null'
CACHE_DEFAULT_TIMEOUT = 60
TEMPLATES_AUTO_RELOAD = True
# ToolbarExtention Configuration
DEBUG_TB_ENABLED = False
DEBUG_TB_INTERCEPT_REDIRECTS = False
DEBUG_TB_TEMPLATE_EDITOR_ENABLED = True
DEBUG_TB_PROFILER_ENABLED = True
About cache i am using the cache extension by it's disabled. Please check the config file.
Thanks,

I managed to fix my issue by adding my template folder to extra_files parameter of Flask app
Here is how :
extra_dirs = [
'/home/karim/flak_app/templates',
]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
for dirname, dirs, files in os.walk(extra_dir):
for filename in files:
filename = os.path.join(dirname, filename)
if os.path.isfile(filename):
extra_files.append(filename)
app.run(threaded=True, extra_files=extra_files)
Hope this will help someone someday :)

Related

flask resfull app permission error on file save

I'm trying to upload a file to my REST API, and then save it in a directory.
It's running on the build in flask development server.
I get this error:
PermissionError: [Errno 13] Permission denied: 'uploads/'
Here is my code:
class Upload(Resource):
def post(self):
new_file = request.files['file']
new_file.save('uploads/', 'file_name')
I understand why I get this error, but I can't figure out how to change permissions. How is that done?
I'm on windows 7.
BR Kresten
Did you set app['UPLOAD_FOLDER'] = 'uploads'?
Here is what I thought better for your uploaded files:
home_dir = os.path.expanduser("~")
UPLOAD_FOLDER = os.path.join(home_dir, "upload")
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
class Upload(Resource):
def post(self):
new_file = request.files['file']
file_name = secure_filename(new_file.filename)
new_file.save(os.path.join(app.config['UPLOAD_FOLDER'], file_name))

For loop not working as expected inside python flask

HI i have a small python script which untars a list of files present in a folder.Below is the script.
app = Flask(__name__)
#app.route('/untarJson')
def untarJson():
outdir="C:\\Users\\esrilka\\Documents\\Tar Files\\Untar"
inputfilefolder="C:\\Users\\esrilka\\Documents\\Tar Files\\New tar files\\"
jsonfiles=[]
for filenames in os.listdir(inputfilefolder):
if filenames.endswith(".tar.gz"):
head,tail= os.path.split(filenames)
basename=os.path.splitext(os.path.splitext(tail)[0])[0]
t = tarfile.open(os.path.join(inputfilefolder,filenames), 'r')
for member in t.getmembers():
if "autodiscovery/report.json" in member.name:
with open(os.path.join(outdir,basename + '.json' ), 'wb') as f:
f.write(t.extractfile('autodiscovery/report.json').read())
if __name__ == '__main__':
app.run(debug=True)
It works fine without flask and in the folder i have four tar files and all 4 files are untarred.
But when i use flask only one file is untarred and the only one file name is displayed.
how can i untar all files inside a folder and also return the name of the files(i.,. only short names and not with full path)
See if the below code works for you, I have changed only little bit to your original code and it works without any issues. All the available tar.gz files are untared and file names gets displayed after request completes,
from flask import Flask, jsonify
import tarfile
import os
app = Flask(__name__)
#app.route('/untarJson')
def untarJson():
outdir = "C:\\tests\\untared"
inputfilefolder = "C:\\tests"
jsonfiles = []
for filenames in os.listdir(inputfilefolder):
if filenames.endswith(".tar.gz"):
head, tail = os.path.split(filenames)
basename = os.path.splitext(os.path.splitext(tail)[0])[0]
t = tarfile.open(os.path.join(inputfilefolder, filenames), 'r')
for member in t.getmembers():
if "autodiscovery/report.json" in member.name:
with open(os.path.join(outdir, basename + '.json'), 'wb') as f:
f.write(t.extractfile('autodiscovery/report.json').read())
jsonfiles.append(os.path.join(outdir, basename + '.json'))
return jsonify(jsonfiles), 200
if __name__ == '__main__':
app.run(debug=True)
After request completed, something like below will be returned (output will be different in your case),
[
"C:\tests\untared\autodiscovery1.json",
"C:\tests\untared\autodiscovery2.json",
"C:\tests\untared\autodiscovery3.json"
]

Run Django script on Windows to create models on Linux

I'm running a data crawler on a Windows 7 machine. I'm inserting the results remotely to my Django 1.10 project on my CentOS 7 server. I have a copy of the Django project on both machines. This works fine for all fields in the model, except the ImageField.
Here is the part of my script that does the saving.
m = Object(strings=strings)
m.save()
image_content = ContentFile(requests.get(image_url).content, id + '.jpg')
m.image_file.save("C:\\Users\\Me\\Documents\\mysite.com\\imgs\\" + id + ".jpg", image_content)
m.save()
The image field is declared as:
image_file = models.ImageField(upload_to='avatars/', null=True, default=None)
My settings.py file on the Windows machine has the line:
MEDIA_ROOT = "/var/www/mysite.com/myproj/images/"
On the first run, there are no errors but the image_feild on the server is set to "."
On the second run, the error is:
IOError: C:\var\www\mysite.com\myproj\images exists and is not a directory.
So this is being created on the Windows machine, but I want the MEDIA_ROOT to be used as the destination directory on the server.
Either use os module.
import os
if os.name == 'nt':
# Windows code.
else:
# Unix code.
Or user relative paths.
# In settings.
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, '../media_root')
# In other places.
mage_file.save(os.path.join(MEDIA_ROOT, '/dir_name/file_name.jpg'), image_content)

Flask - Errno 13 premission denied

I'm writing a small web page whose task is to let a user upload his input file and with uploading I want to execute my calculation program in python which will give me output for the user.
My code looks like this:
import os
import os.path
import datetime
import subprocess
from flask import Flask, render_template, request, redirect, url_for
from werkzeug import secure_filename
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['ALLOWED_EXTENSIONS'] = set(['txt', 'gro', 'doc', 'docx'])
current_time = datetime.datetime.now()
file_time = current_time.isoformat()
proper_filename = file_time
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
def run_script():
subprocess.call(['/home/martyna/Dropbox/programowanie/project_firefox/topologia.py', '/uploads/proper_filename'])
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload', methods = ['POST'])
def upload():
file = request.files['file']
if file and allowed_file(file.filename):
file.save(os.path.join(app.config['UPLOAD_FOLDER'], proper_filename))
run_script().start()
return "Thank you for uploading"
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
Uploading goes well, but the problem is that when I hit upload I get message OSError: [Errno 13] Permission denied and the line causing the problem is:
subprocess.call(['/home/martyna/Dropbox/programowanie/project_firefox/topologia.py', '/uploads/2014-05-16T22:08:19.522441'])
program topologia.py runs from command python topologia.py input_file
I have no idea how to solve that problem.
You have two problems:
Your script is probably not marked as executable. You can work around that by using the current Python executable path; use sys.executable to get the path to that.
You are telling the script to process /uploads/proper_filename, but the filename you actually upload your file to is not the same at all; you should use the contents of the string referenced by proper_filename instead.
Put these two together:
import sys
from flask import current_app
def run_script():
filename = os.path.join(current_app.config['UPLOAD_FOLDER'], proper_filename)
subprocess.call([
sys.executable,
'/home/martyna/Dropbox/programowanie/project_firefox/topologia.py',
filename])
You do not need to call .start() on the result of run_script(); you'll get an attribute error on NoneType. Just call run_script() and be done with it:
run_script()
Executing a script from a command line and from a server will not be done with the same permissions.
user#mycomputer:~$ ./script
In this exemple, ./script is launched by user. So if it does some inputs/outputs, the access rigths will depend on user rights.
When it is a server that runs the script, in your case Flask, it is probably www-data that launch the script. So the access rights are not the same.
So to create a file into a folder the user executing the script should have the permissions on the folder.

Markers not showing on Google Map in Google App Engine

I have created a Google App Engine project in Python it runs on my localhost but when I upload it onto geo-event-maps.appspot.com the markers are not displaying.
I have a cron which runs to call on /place.
I have no log errors
My datastore is empty!
The txt files are being uploaded with:
file_path = os.path.dirname(__file__)
path = os.path.join(file_path, 'storing', 'txtFiles')
Is there a way of checking the files have been uploaded?!
I am at an absolute loss. Has anyone had these problems before?
Below is my main.py:
'''
Created on Mar 30, 2011
#author: kimmasterson
'''
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext import db
from placemaker import placemaker
import logging
import wsgiref.handlers
import os, glob
from google.appengine.dist import use_library
use_library('django', '1.2')
from google.appengine.ext.webapp import template
class Story(db.Model):
id = db.StringProperty()
loc_name = db.StringProperty()
title = db.StringProperty()
long = db.FloatProperty()
lat = db.FloatProperty()
link = db.StringProperty()
date = db.StringProperty()
class MyStories(webapp.RequestHandler):
def get(self):
temp = db.Query(Story)
temp = temp.count()
story_set = Story.all()
template_values = {
'storyTemp': story_set
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
class place(webapp.RequestHandler):
def get(self):
#path = '/storing/txtFiles'
file_path = os.path.dirname(__file__)
path = os.path.join(file_path, 'storing', 'txtFiles')
try:
for infile in glob.glob(os.path.join(path, '*.txt')):
#print infile
f = open(infile, 'r')
data = f.read()
newfile = infile.replace('.txt', '')
newfile = newfile.replace('/storing/txtFiles/', '')
#print newfile
storyname = 'http://www.independent.ie/national-news/' + newfile
#print storyname
#print newfile
#logging.info(data)
p = placemaker('HSnG9pPV34EUBcexz.tDYuSrZ8Hnp.LowswI7TxreF8sXrdpVyVIKB4uPGXBYOA9VjjF1Ca42ipd_KhdJsKYjI5cXRo0eJM-')
print p.find_places(data)
for place in p.places:
splitted = place.name.split()
for word in splitted:
temp = db.Query(Story)
temp = temp.filter("link = ", storyname)
results = temp.fetch(limit=1)
if len(results) > 0:
break
elif 'IE' in word:
print temp
print 'success'
print 'name of the file is:' + newfile
story = Story(name=newfile, long=place.centroid.longitude, lat=place.centroid.latitude, link=storyname, loc_name=place.name, title=newfile).put()
#logging.info(type(place.centroid.latitude))
except:
print 'error'
def main():
application = webapp.WSGIApplication([('/', MyStories), ('/place', place)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
Here is my cron.yaml
cron:
- description: running place
url: /place
schedule: every day 11:05
App.yaml is as follows:
application: geo-event-maps
version: 2
runtime: python
api_version: 1
handlers:
- url: .*
script: main.py
builtins:
- datastore_admin: on
You need to be sure your files are being uploaded with your application code, they can not be marked as static files or they won't be accessible to your code. Run appcfg.py with the --verbose flag and make sure they get uploaded.
Second issue, in your place class you define path as path = '/storing/txtFiles'. That is wrong. Your path will probably be something more like:
file_path = os.path.dirname(__file__)
path = os.path.join(file_path, 'storing', 'txtFiles')
Also, I suggest you don't use print, instead use self.response.out.write(stuff_to_write).
You might also want to see about using key_names. You'll be able to make your code quite a bit more efficient then by running a batch db.get instead of a db.Query inside a nested for-loop. Use Appstats and try to minimize the number of RPCs.
First make sure that you are accessing your files using a relative path.
Next ensure you have not marked the files as static within your app.yaml as static files are not uploaded to the same place as your application (they are sent somewhere that the Google Frontend servers can serve them more directly).

Categories