Reading json in pythonanywhere flask app - python

First I have seen this question. My problem is I have a flask app running on pythonanywhere that reads info from a json file in the same directory on the server, and get the following error:
Internal Server Error:The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application..
I simplified the app down to:
from flask import Flask
import json
app = Flask(__name__)
#app.route('/')
#app.route('/index')
def index():
return 'Index'
#app.route('/courses')
def courses():
with open('courses.json', 'r') as f:
these_courses = json.load(f)
return str(these_courses)
If I go to the index page I see index, as expected, but if I try to go to /courses then I get the error.The whole things runs fine on localhost, then with the same code I get an error on the server, so I know reading from the file works fine. This makes me think it might be a problem unique to json combined with pythonanywhere.
Edit: Perhaps a problem with the path name for courses.json, but it's in the same directory so I feel like it should be fine, just a thought

Turns out it was a pathname problem. I guess on files need to be routed from the root directory.
I ran:
def courses():
my_dir = os.path.dirname(__file__)
json_file_path = os.path.join(my_dir, 'courses.json')
return json_file_path
to find the path, then changed the function to:
def courses():
with open('/home/username/path/to/file/courses.json', 'r') as f:
these_courses = json.load(f)
return str(these_courses)
and now it worked :D
Then to make a better version that doesn't break when you move the project I did it like this:
def courses():
my_dir = os.path.dirname(__file__)
json_file_path = os.path.join(my_dir, 'courses.json')
with open(json_file_path, 'r') as f:
these_courses = json.load(f)
return str(these_courses)

As an alternative:
import pathlib
path = pathlib.Path('courses.json').absolute()
these_courses = json.loads(path.read_text())

Related

File uploads using flask looking in CWD for file to upload instead of using users sample directory

Basically my issue is, whenever I go to upload a file through Flask it wants the file that is being uploaded in the same directory as the Python file my flask server is being run from. This becomes an issue when I go to my local machine instead of my VM and it searches for /home/kali/Downloads/(sample name) instead of wherever the sample is on the windows machine ex(C:\temp(sample)). It also does this on the VM itself where it is only looking in the /home/kali/Downloads folder for the sample to be uploaded. It's almost like it skips the sample entirely.
Here is my code:
from flask import Flask, render_template, request, redirect, send_file
import os
import shutil
from flaskmalwarecheck import malwaresignature
from flaskmalwarecheck import formattedpdf
from flaskmalwarecheck import entropy
import argparse
from elastic import elasticupload
filetypes = [b'MZ']
app= Flask(__name__)
#app.route('/')
def main():
return render_template('attempt.html')
#app.route('/upload', methods = ['GET', 'POST'])
def upload():
try:
upload_folder = "/home/kali/Downloads/webserverup/"
if request.method == 'POST':
n = request.files['file']
filename = n.filename
with open(filename, 'rb') as f:
header = f.read(32)
for call in filetypes:
if call in header:
n.save(os.path.join(upload_folder,filename))
os.chdir(upload_folder)
malware_file, ISO8601, hashmethod, arch, importeddlls, imphash, fuzzyhash,warnings = malwaresignature(n.filename)
formattedpdf(n.filename,malware_file,ISO8601, hashmethod, arch, importeddlls, imphash, fuzzyhash,warnings)
download()
os.remove(n.filename)
os.chdir('..')
elasticupload()
return redirect('/download', code=302)
else:
return redirect('/download', code=302)
except FileNotFoundError as e:
return redirect('/download', code=302)
#app.route('/download')
def download():
return send_file('/home/kali/Downloads/webserverup/Sample.pdf', as_attachment=True)
#app.route('/transparent')
def transparent():
with app.open_resource('flaskmalwarecheck.py', 'r') as e:
contents = e.read()
return contents
parser = argparse.ArgumentParser()
parser.add_argument("ip", help="Enter host IP", type=str)
parser.add_argument("port", help="Port to be hosted on", type=int)
args = parser.parse_args()
if __name__ == "__main__":
app.run(host=args.ip, port=args.port, ssl_context=('cert.pem', 'key.pem'))
The code uploaded really wonky so if something is misplaced it most likely isnt in the actual code, but feel free to point it out anyways. If you also want to see the HTML page I can provide that, but I didn't think it was relevant. This is my first time working with Flask so any pointers would be greatly appreciated as well ;)
You might want to use the config variable UPLOAD_FOLDER to specify where the uploaded file goes & secure_filename to strip & sanitize the path
import os
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/path/to/the/uploads'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
#app.route(...<route info>...)
def upload_file():
...
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
...
See Flask documentation on Uploading Files

download file FROM web TO flask server

My flask app should download files from urls which are posted to my app by a json object.
The files should be downloaded for further processing. I do not get an error message. A lot of tutorials are about how a user uploads a file, but this is not my case. Can anyone help?
import os
from flask import Flask, request, jsonify
import urllib.request as web
app = Flask(__name__)
download_folder=os.path.join(app.instance_path,'downloads')
app.config['DOWNLOAD_FOLDER'] = download_folder
#app.route('/syncaudio', methods=['POST'])
def syncaudio():
files = request.get_json(force=True)
for file_url in files['syncFileUrls']:
local_file = os.path.join(app.config['DOWNLOAD_FOLDER'], file_url.rsplit('/')[-1])
web.urlretrieve(file_url, local_file)
if __name__ == '__main__':
app.run(debug=True)
urlretrieve(file_url,local_file) is the right way of doing it, there is nothing specific to Flask.
I suggest you to try in a Python interpreter to see if that works:
>>> import urllib.request
>>> urllib.request.urlretrieve('http://some/url', '/some/file/location.txt')
If that works, this means your code is never getting executed.
You may want to print the value of files to see if the list is not empty.
I found the solution!
for downloading FROM web TO flask server I do not need to create a folder like this:
download_folder=os.path.join(app.instance_path,'downloads')
app.config['DOWNLOAD_FOLDER'] = download_folder
I just have to create a download folder via:
os.makedirs('downloads')
really simpel :)

is there any way of continously reading CSV file and show it on HTML using Flask?

I have written a small job that takes the data from CSV and show it on HTML using Flask. It works fine but I want to automate it in a way that it starts showing any change in CSV. The CSV file is getting data from live system which means that the file content is changing with time. From my code it only shows me only show me present file and does not update for the newer content.
I have tried running bat file that will start python script but the problem is once it is started, I need to start python again so that it takes latest CSV.
from flask import Flask,render_template
import tablib
app = Flask (__name__)
dataset = tablib.Dataset()
with open(os.path.join(os.path.dirname(__file__),'file.csv')) as f:
dataset.csv = f.read()
#app.route("/")
def index():
return dataset.html
if __name__ == "__main__":
app.run()
You need to read the file within your index function.
#app.route("/")
def index():
dataset = tablib.Dataset()
with open(os.path.join(os.path.dirname(__file__),'file.csv')) as f:
dataset.csv = f.read()
return dataset.html

Python Error [Errno 36]: File name too long

I searched for this error, but couldn't find out how to handle it. I am getting the following error, when trying to open a file:
[Errno 36] File name too long: '/var/www/FlaskApp/FlaskApp/templates/
Here is my simple code. I am trying to open a json file and render it with Flask into a website:
#app.route("/showjson/")
def showjson():
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
data_in = open(os.path.join(SITE_ROOT, "static/data", "btc.json"), "r")
data_out = ""
for line in data_in:
data_out += line.rstrip()
data_in.close()
return render_template(data_out)
Does anybody know a solution? Many thanks in advance.
You are passing the render_template function the entirety of your JSON file, when it is looking for the filename of a template file. This is why you are getting a file name is too long error.
You can use the send_from_directory function to send the JSON file. Import the function first:
from flask import send_from_directory
Then use it like so:
#app.route("/showjson/")
def showjson(path):
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
return send_from_directory(os.path.join(SITE_ROOT, "static/data"), "btc.json")

Error Reading CSV file using Python, Flask

I'm very new to python and flask. I simply wanted to read a CSV file but it's giving me an error of "FileNotFoundError: [Errno 2] No such file or directory: 'Dog-Data.csv'" everytime I try to run run.py
Here are my file order
DD\
static\
(bunch of image files)
templates\
(bunch of template files)
__init__.py
views.py
Dog-Data.csv
views.py
from flask import render_template
from app import app
import csv
#app.route('/')
#app.route('/Home')
def home():
return render_template("Home.html",title='Home')
#app.route('/MakeaMatch')
def makeamatch():
return render_template("MakeaMatch.html",title='Make a Match!')
#app.route('/Game')
def game():
return render_template("Game.html",title='Game')
#app.route('/ListofDogs')
def listofdogs():
return render_template("ListofDogs.html",title='List of Dogs')
#app.route('/About')
def about():
return render_template("About.html", title='About')
#app.route('/Contact')
def contact():
return render_template("Contact.html", title='Contact')
#app.route('/MatchResult')
def matchresult():
class DogBreed:
def __init__(self, br, per, si, lif, hou, cli):
self.breed = br
self.personality = per
self.size = si
self.lifestyle = lif
self.housing = hou
self.climate = cli
self.match = 0
#List that will contain class DogBreed
ListOfBreeds = []
data_file = open('Dog-Data.csv')
csv_file = csv.reader(data_file)
for row in csv_file:
#print (row) #will print the csv file
#print (row[2]) #will print element of that row
dog_breed = DogBreed(row[0],row[1].lower().split(", "),row[2].lower(),row[3].lower(),row[4].lower(),row[5].lower())
ListOfBreeds.append(dog_breed)
data_file.close()
#MORE CODES HERE. OMITTED BECAUSE I DON'T THINK IT'S RELEVANT
return render_template("MatchResult.html",title='Match Result',posts=ListOfBreeds)
The webpage loads and templates shows up fine if I comment out the lines involving CSV. However, it doesn't of course show the result I want it too.
I've also tried putting the Dog-Data.csv into the static folder and used
data_file = open('static/Dog-Data.csv')
but this didn't work either.
Thanks so much for help.
Have you tried to give the full path instead of just a relative path?
Python sometimes takes the working directory as a "home" path, which might or might not be the same as your view.py is situated in.
ok so really simple mistake that took hours for me to solve.
I should be passing it from the root folder which means I should've put
data_file = open('app/Dog-Data.csv')
and now it works. T__T

Categories

Resources