Форма колбы POST-запрос для заполнения оставшейся части шаблона jinja2 - PullRequest
0 голосов
/ 30 октября 2019

У меня есть веб-форма Flask, которая "ищет участников", используя поле ввода свободного текста. Я хочу программно выполнить нагрузочное тестирование этого веб-сайта с помощью некоторого инструмента командной строки, например curl, вместо того, чтобы издеваться над поведением пользователя с помощью чего-то вроде Selenium.

Вот бэкэнд Python:

# test.py
from time import sleep
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

class Config:
    SECRET_KEY = 'SUPER_SECRET_VALUE'

app = Flask(__name__)
app.config.from_object(Config)

class TestForm(FlaskForm):
    member_id = StringField('Member ID', validators=[DataRequired()])
    submit = SubmitField('Submit')

@app.route('/test', methods=['GET', 'POST'])
def test():
    form = TestForm()
    if form.validate_on_submit():
        member_id_field = form.member_id
        member_id = member_id_field.data
        # simulate doing something with `member_id`
        sleep(2)
        result = 'some result'
        return render_template(
            'test.html',
            title='test',
            form=form,
            result=result
        )
    else:
        return render_template(
            'test.html',
            title='test',
            form=form
        )

if __name__ == '__main__':
    app.run()

А вот HTML-форма:

<h1>Search for a member</h1>
<form action="" method="post" novalidate>
    {{ form.hidden_tag() }}
    <p>
        {{ form.member_id.label }}
        <br>
        {{ form.member_id(size=32) }}
    </p>
    <p>{{ form.submit() }}</p>

    {% if result is defined %}
        <h1>Result is: {{ result }}</h1>
    {% endif %}
</form>

Сначала я запускаю сервер с python3 test.py, а затем использую curl -X POST -H "Content-Type: application/json" -d '{"member_id":"123"}' http://127.0.0.1:5000/test/, чтобы попытаться отправить идентификатор участника в форму для запуска логики поиска.

Если я захожу на веб-сайт в браузере, я могу ввести идентификатор и заполняется раздел Result is:. Однако, используя curl, я ничего не получаю обратно:

<h1>Search for a member</h1>
<form action="" method="post" novalidate>
    <input id="csrf_token" name="csrf_token" type="hidden" value="BASDHSAHSADHASHDASHDAHSDH">
    <p>
        <label for="member_id">Member ID</label>
        <br>
        <input id="member_id" name="member_id" required size="32" type="text" value="123">
    </p>
    <p><input id="submit" name="submit" type="submit" value="Submit"></p>



Если заполнится Result is:, я знаю, что моя форма работает. Таким образом, подход с использованием веб-сайта работает, а командная строка - нет. В чем может быть проблема?

1 Ответ

0 голосов
/ 30 октября 2019

Это не самое оптимальное решение, так как оно не учитывает время рендеринга jinja, но вы можете добавить слой flask_restful, разрабатывая REST API для основной части обработки данных:

from time import sleep
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from flask_restful import Api, Resource
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

class Config:
    SECRET_KEY = 'SUPER_SECRET_VALUE'

def get_data(member_id):
    sleep(2)
    return f'getting data for {member_id}'

class TestForm(FlaskForm):
    member_id = StringField('Member ID', validators=[DataRequired()])
    submit = SubmitField('Submit')

class TestApi(Resource):
    def get(self):
        data = request.get_json(force=True)
        get_data(data)
        return data, 200
    def post(self):
        data = request.get_json(force=True)
        get_data(data)
        return data, 200

app = Flask(__name__)
app.config.from_object(Config)

api_manager = Api(app)
api_manager.add_resource(TestApi, '/api/test')

@app.route('/test', methods=['GET', 'POST'])
def test():
    form = TestForm()
    if form.validate_on_submit():
        member_id_field = form.member_id
        member_id = member_id_field.data
        # simulate doing something with `member_id`
        data = get_data(member_id)
        return render_template(
            'test.html',
            form=form,
            result=data
        )
    else:
        return render_template(
            'test.html',
            form=form
        )

if __name__ == '__main__':
    app.run()

А затем используйте:

curl -X POST -H "Content-Type: application/json" -d '{"member_id":"123"}' http://127.0.0.1:5000/api/test
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...