I am right now writing a program which grabs images from the internet and use them to start a server and write the html.
Here is my code:
import json
import requests
import urllib2
import webserver
import bottle
from bottle import run, route, request
#get images
r = requests.get("http://web.sfc.keio.ac.jp/~t14527jz/midterm/imagelist.json")
r.text
imageli = json.loads(r.text)
i = 1
for image in imageli:
if i <= 5:
fname = str(i)+".png"
urllib.urlretrieve(image,fname)
i += 1
#to start a server
#route('/')
#write a HTML, here is where the problem is,
#the content of html is <image src= "1.png"> but the picture is not on the server.
#and I don't know how to do it
def index():
return "<html><head><title>Final exam</title></head><body> <img src=\"1.png\"/>\n <img src=\"2.png\"/>\n <img src=\"3.png\"/>\n<img src=\"4.png\"/>\n<img src=\"5.png\"/>\n</body></html>"
if __name__ == '__main__':
bottle.debug(True)
run(host='localhost', port=8080, reloader=True)
And I am having a problem that the images cannot be shown on the website, the console says images cannot be found.
How can I solve this problem?
The problem here is that you haven't defined a route for serving your static files. You could set the root directory to serve static files by adding this route:
# To serve static png files from root.
#bottle.get('/<filename:re:.*\.png>')
def images(filename):
return bottle.static_file(filename, root='')
But you should really move these to a subdirectory, as in:
import json
import requests
import urllib
import bottle
from bottle import run, route, request
#get images
r = requests.get("http://web.sfc.keio.ac.jp/~t14527jz/midterm/imagelist.json")
r.text
imageli = json.loads(r.text)
i = 1
for image in imageli:
if i <= 5:
fname = "static/{}.png".format(i) # Note update here
urllib.urlretrieve(image, fname)
i += 1
#to start a server
#route('/')
def index():
return "<html><head><title>Final exam</title></head><body> <img src=\"1.png\"/>\n <img src=\"2.png\"/>\n <img src=\"3.png\"/>\n<img src=\"4.png\"/>\n<img src=\"5.png\"/>\n</body></html>"
# To serve static image files from static directory
#bottle.get('/<filename:re:.*\.(jpg|png|gif|ico)>')
def images(filename):
return bottle.static_file(filename, root='static')
if __name__ == '__main__':
bottle.debug(True)
run(host='localhost', port=8080, reloader=True)
Related
I have a JSON file in the flask app that i send via either send_from_directory() or via send_file() i have tried both. This triggers on button click but the browser opens the file directly instead of getting a download dialog box. I researched a bit and found out Firefox and Chrome have an inbuilt option to do this, however i want it to always download instead of opening no matter the setting in the browser.
Flask Code
def download_file():
filename = "requiredFields.json"
return send_from_directory(app.config['MAIN_FOLDER'],filename,as_attachment=True)
HTML That calls it
Download
If you set mimetype to 'application/octet-stream' then browser should save it.
send_file(..., mimetype='application/octet-stream')
send_from_directory(..., mimetype='application/octet-stream')
Doc: send_file
See also: Do I need Content-Type: application/octet-stream for file download?
EDIT:
Minimal working example - you have to only set correct filenames in index()
It doesn't matter if you have file .json, .txt, image, .pdf or other. It works for all types of files.
from flask import Flask, render_template_string, send_from_directory
app = Flask(__name__)
app.config['MAIN_FOLDER'] = '.'
#app.route('/')
def index():
all_filenames = [
'requiredFields.json',
'input.txt',
'image.jpg',
'document.pdf',
]
return render_template_string('''
{% for file in all_files %}
Download {{file}}<br/>
{% endfor %}''', all_files=all_filenames)
##app.route('/download_file/<filename>')
#app.route('/download_file/<path:filename>')
def download_file(filename):
return send_from_directory(app.config['MAIN_FOLDER'], filename, as_attachment=True, attachment_filename=filename, mimetype='application/octet-stream')
if __name__ == '__main__':
app.run() #debug=True
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
I have one web application with Rest API ,In that application I have some video files now i am creating one intermediate server in this one.I am accessing my web content using API but here i need to check updates in regular intervals if new updates will be there i need to download them.
Here files are video files and i'm using flask
I tried this i'm not getting
from flask import Flask,render_template,json,jsonify
import schedule
import time
import requests,json
from pathlib import Path
import multiprocessing
import time
import sys
import schedule,wget,requests,json,os,errno,shutil,time,config
def get_videos():
response = requests.get('my api here')
data = response.json()
files =list() # collecting my list of video files
l = len(data)
for i in range(l):
files.append(data[i]['filename'])
return files
def checkfor_file(myfiles):
for i in range(len(myfiles)):
url = 'http://website.com/static/Video/'+myfiles[i] # checking file exists are not in my folder
if url:
os.remove(url)
else:
pass
def get_newfiles(myfiles):
for i in range(len(myfiles)):
url = config.videos+myfiles[i]
filename= wget.download(url)# downloading video files here
def move_files(myfiles):
for i in range(len(myfiles)):
file = myfiles[i]
shutil.move(config.source_files+file,config.destinatin) # moving download folder to another folder
def videos():
files = set(get_videos()) # getting only unique file only
myfiles = list(files)
checkfor_file(myfiles)
get_newfiles(myfiles)
move_files(myfiles)
def job():
videos()
schedule.every(10).minutes.do(job) # running for every ten minutes
while True:
schedule.run_pending()
time.sleep(1)
pi =Flask(__name__)
#pi.route('/')
def index():
response = requests.get('myapi')
data = response.json()
return render_template('main.html',data=data)
So i am following the web.py uploading and storing guide to test it out but i keep geting a
error stating that [Errno 2] No such file or directory :< help
this is my code
import web
urls = (
'/hello', 'index',
'/hello/upload', 'upload'
)
app = web.application(urls, globals()) # handels http request that aks for urls
# the base ells lpthw.web to use the templates/layout.html file as the base template for all the other templates
render = web.template.render('templates/', base="layout")
# must use port 127.0.0.1:5000
class index(object):
def GET(self):
return render.hello_form()
def POST(self):
form = web.input(name="Nobody", greet="Hello")
greeting = "%s, %s" % (form.greet, form.name)
return render.index(greeting = greeting)
class upload(object):
def POST(self):
x = web.input(files={})
filedir = '/project/webtest/templates' # directory were you want to save the file
if 'files' in x: # check if the file -object is created
filepath=x.files.filename.replace('\\','/') # replace the windows -style slashes with linux ones
filename=filepath.split('/')[-1] #splits the and chooses the last part (the filename with extension
fout = open(filedir +'/'+ filename,'w') # creates the file where the uploaded file should be stored
fout.write(x.files.file.read()) #writes the uploaded file to the newly created file.
fout.close() #closes the file
else:
return "Error no file"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
help thx
import web
urls = ('/upload', 'Upload')
class Upload:
def GET(self):
web.header("Content-Type","text/html; charset=utf-8")
return view.upload()
def POST(self):
x = web.input(myfile={})
filedir = '/path/where/you/want/to/save' # change this to the directory you want to store the file in.
if 'myfile' in x: # to check if the file-object is created
filepath=x.myfile.filename.replace('\\','/')
filename=filepath.split('/')[-1]
fout = open(filedir +'/'+ filename,'w')
fout.write(x.myfile.file.read()) # writes the uploaded file to the newly created file.
fout.close() # closes the file, upload complete.
raise web.seeother('/upload')
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
upload.html
<html>
<head>
<title>File upload</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data" action="">
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
</body>
</html>
for your reference http://webpy.org/cookbook/storeupload/
I met the same problem myself, and tried to ask that here. But nobody answers.
Finally, I figured it out what's the problem and would like to share with you!
This part: filedir = '/project/webtest/templates' should be an absolute path.
And it should be an existing directory (at least in my trail it should be an existing directory, otherwise it would prompt the same error as you posted)! The file need not to be exciting since we are going to create it by copying the uploaded file.
For example in my mac, it's '/Users/J/pythonex/projects/gothonweb/docs', and it's an existing directory. If it's not an existing directory, you will get the same error message.
Last, the most tricky part. Im my mac, the uploaded files are actually stored in my disk in that exact directory. But I can't see them in my finder until I relaunch the finder. I don't know why is that. But for my computer, that's the case.
Context
I have created a Flask application that allows me to:
(1) upload a GeoTIFF file to a specified folder (UPLOAD_FOLDER)
(2) use GDAL to open the uploaded GeoTIFF as a Pandas data frame, and return a JSON containing all the cell values. The app code is below:
import os
import gdal
import numpy as np
import pandas as pd
import json
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = 'PATH_GOES_HERE' #specify path
ALLOWED_EXTENSIONS = set(['tif'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('get_raster_data',
filename=filename))
return '''
<!doctype html>
<title>Upload raster file</title>
<h1>Upload raster file</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
#app.route('/rasterdata', methods=['GET'])
def get_raster_data():
filename = secure_filename(request.args.get('filename'))
try:
if filename and allowed_file(filename):
f = os.path.join(app.config['UPLOAD_FOLDER'], filename)
rast_data = gdal.Open(f)
rast_array = np.array(rast_data.GetRasterBand(1).ReadAsArray())
return pd.DataFrame(rast_array).to_json()
except IOError:
pass
return "Unable to read file"
The application works properly (i.e. I've tested using a local host and running in debug mode). The application allows me to open a web page with "Choose file" and "upload" buttons. Once I upload the file I am redirected to the '/rasterdata' page which has the expected output.
I have been tasked with creating a Jupyter Notebook that basically only requires users to specify the path to a GeoTIFF that they would like to upload. Once the path is specified the Flask app needs to run and return a data frame of all the GeoTIFF's cell values. From there, the Notebook goes through a few processing steps that require the data frame as the input, but these are not relevant to my question.
Question
How can I upload a file to UPLOAD_FOLDER by simply specifying the path to the GeoTIFF in the Jupyter Notebook? Below is the code from my Jupyter Notebook. I've added comments specifying where I am stuck. I suspect that I will need to modify the Flask app to take in a path name. I could not find any tutorials for this though. All the tutorials I could find give me code that is similar to what I currently have.
url = f'http://localhost:5000/upload'
my_path = r'C:\Users\admievan\Desktop\FlaskGDAL\my_raster.tif'
#Opening the upload page
with urllib.request.urlopen(path) as url:
#THIS IS WHERE I AM STUCK
#I want to pass my_path to the Flask application rather than having to
#manually navigate to the file in the GUI interface that comes up when clicking
#the "Choose file" button
#Reading the data web page as a panadas data frame
#This part works fine if 'my_raster.tif' is already in the UPLOAD_FOLDER
url = f'http://localhost:5000/rasterdata?filename=my_raster.tif'
df = pd.read_json(url, orient='rows')
df
The requests package is your best friend when it comes to dealing with uploads/extractions and API calls.
Whatever your host is for the url is where you would need to pass this through.
Uploading is not too difficult and could look something like this:
import os
import base64
import urllib
import json
import requests
def jupyter_upload(token, filePath, resourceDstPath, jupyterUrl='http://localhost:8888'):
dstPath = urllib.quote(resourceDstPath)
dstUrl = '%s/api/contents/%s' % (jupyterUrl, dstPath)
fileName = filePath[1 + filePath.rfind(os.sep):]
headers = {}
headers['Authorization'] = 'token '+token
with open(filePath, 'r') as myfile:
data=myfile.read()
b64data=base64.encodestring(data)
body = json.dumps({
'content':b64data,
'name': fileName,
'path': resourceDstPath,
'format': 'base64',
'type':'file'
})
return requests.put(dstUrl, data=body, headers=headers, verify=True)`