werkzeug.exceptions.BadRequestKeyError При попытке получить файл .csv из запроса GET, используя Flask - PullRequest
0 голосов
/ 01 мая 2020

Я пытаюсь получить файл .csv из формы, получить его на своем сервере, открыть его и обработать nunmers, чтобы вернуть действительные, но когда я пытаюсь открыть файл из запроса, я получаю "werkzeug .exceptions.BadRequestKeyError "

Мой html такой:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Flask Tutorial</title>
  </head>
  <body>
    <form action="/api/listtels" method="get">
      <label for="tels">file:</label>
      <input name="tels" type="file" id="tels"><br><br>
      <input type="submit" value="send">
    </form>
  </body>
</html>

А мой код python такой:

import flask
import csv
from flask import Flask, render_template, request, jsonify

app = flask.Flask(__name__)
app.config["DEBUG"] = True

@app.route('/', methods=['GET'])
def home():
    return render_template("home.html")

@app.route('/api/listtels', methods=['GET'])
def ltels():

    tels = "ERROR" 
    ret = "ERROR"
    if 'tels' in request.args:
        tels = request.files['tels']
        ret = "tel\n"
    else:
        return("\'tels\' arg is needed")
    with open(tels, encoding='UTF-8') as f:
        rows = csv.reader(f,delimiter=",",lineterminator="\n")
        next(rows, None)
        for row in rows:
            tel = row[0]
            tel = str(''.join(filter(str.isnumeric, tel)))
            if len(tel) == 11:
                ret = ret + tel + "\n"
            elif len(tel) == 13:
                ret = ret + "+" + tel + "\n"
    return (ret)


app.run()

Прошло 3 дня с тех пор Я начал использовать Python и Flask, поэтому, плз, без суждений: D

1 Ответ

0 голосов
/ 02 мая 2020

Механизм flask request.files предполагает, что запрос будет POST, потому что невозможно загрузить файл с помощью запроса GET (вы можете получить данные файла, но это не совсем то же самое вещь *).

Следовательно, атрибут метода формы должен быть POST, а для атрибута enctype также должно быть установлено значение * multipart / form-data"для абсолютной корректности.

<form action="/api/listtels" method="POST" enctype="multipart/form-data">

На стороне сервера

  • Маршрут должен принимать только запросы POST.
  • Имена файловых входов не являются частью request.args, поэтому тест членства должен быть изменен на test request.files.
  • Загруженный файл необходимо декодировать и загрузить в буфер, чтобы его можно было обработать с помощью csv.reader (или его можно записать на диск и затем прочитать обратно)

    import io

    @app.route ('/ api / listtels', method = ['POST']) def ltels ():

    tels = "ERROR" 
    ret = "ERROR"
    # Check if the file is loaded
    if 'tels' in request.files:
        tels = request.files['tels']
        ret = "tel\n"
    else:
        return("\'tels\' arg is needed")
    # Load decoded file data into a text buffer
    buf = io.StringIO(tels.read().decode('utf-8'))
    rows = csv.reader(buf,delimiter=",",lineterminator="\n")
    next(rows, None)
    for row in rows:
        tel = row[0]
        tel = str(''.join(filter(str.isnumeric, tel)))
        if len(tel) == 11:
            ret = ret + tel + "\n"
        elif len(tel) == 13:
            ret = ret + "+" + tel + "\n"
    

    return (ret)

* Вы можете получить содержимое с помощью GET, вставив содержимое файла в <input type="textarea"...> или манипулируя данными формы с помощью javascript перед отправкой на сервер.

...