python - Python/Flask - 通过从 Jupyter Notebook 传递路径来上传文件
问题描述
语境
我创建了一个 Flask 应用程序,它允许我:
(1)上传一个GeoTIFF文件到指定文件夹(UPLOAD_FOLDER)
(2) 使用GDAL将上传的GeoTIFF作为Pandas数据框打开,并返回一个包含所有单元格值的JSON。应用程序代码如下:
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"
该应用程序工作正常(即我已经使用本地主机进行了测试并在调试模式下运行)。该应用程序允许我使用“选择文件”和“上传”按钮打开网页。上传文件后,我将被重定向到具有预期输出的“/rasterdata”页面。
我的任务是创建一个 Jupyter Notebook,基本上只需要用户指定他们想要上传的 GeoTIFF 的路径。指定路径后,Flask 应用程序需要运行并返回所有 GeoTIFF 单元格值的数据框。从那里,笔记本经历了一些需要数据框作为输入的处理步骤,但这些与我的问题无关。
问题
如何通过简单地在 Jupyter Notebook 中指定 GeoTIFF 的路径将文件上传到 UPLOAD_FOLDER?下面是我的 Jupyter Notebook 中的代码。我添加了评论,说明我卡在哪里了。我怀疑我需要修改 Flask 应用程序以获取路径名。不过,我找不到任何教程。我能找到的所有教程都给了我与我目前拥有的相似的代码。
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
解决方案
在处理上传/提取和 API 调用时,请求包是您最好的朋友。无论您的主机是什么网址,您都需要通过它。上传并不太难,可能看起来像这样:
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)`
推荐阅读
- c# - 如何正确地将接收到的串行数据解析成行?
- jmeter - 执行登录 API,其中身份验证过程与 Active Directory 一起发生
- java - 将工具提示文本设置为 JDialog 的关闭按钮
- python - TypeError:“用户”对象不能使用 Django 进行迭代
- postman - Postman 安装错误:System.UnauthorizedAccessException:访问路径“C:\Users\Noob\AppData\Local\Postman”被拒绝
- html - 如有必要,让卡片内容占据可用高度
- c# - GET 和 POST 请求的模型差异
- python - 使用 AWS Texttract 处理 PDF
- excel - excel中的多选下拉列表
- c - 是否可以在 C 中“取消字符串化” __func__ ?