웹사이트 검색

Flask에서 들어오는 요청 데이터를 처리하는 방법


소개

웹 애플리케이션은 종종 사용자로부터 들어오는 요청 데이터를 처리해야 합니다. 이 페이로드는 쿼리 문자열, 양식 데이터 및 JSON 개체의 형태일 수 있습니다. Flask는 다른 웹 프레임워크와 마찬가지로 요청 데이터에 액세스할 수 있습니다.

이 자습서에서는 쿼리 문자열, 양식 데이터 또는 JSON 개체를 허용하는 세 가지 경로로 Flask 애플리케이션을 빌드합니다.

전제 조건

이 자습서를 완료하려면 다음이 필요합니다.

  • 이 프로젝트는 로컬 환경에 Python을 설치해야 합니다.
  • 이 프로젝트는 virtualenv를 하나의 단일 명령으로 사용합니다.
  • API 엔드포인트를 테스트하려면 Postman과 같은 도구를 다운로드하고 설치해야 합니다.

이 튜토리얼은 Pipenv v2020.11.15, Python v3.9.0 및 Flask v1.1.2에서 검증되었습니다.

프로젝트 설정

요청을 사용하는 다양한 방법을 시연하려면 Flask 앱을 만들어야 합니다. 예제 앱은 보기 기능 및 경로에 대해 단순화된 구조를 사용하지만 이 자습서에서 배우는 내용은 클래스 기반 보기, 청사진 또는 Flask-Via와 같은 확장과 같은 보기를 구성하는 모든 방법에 적용할 수 있습니다.

먼저 프로젝트 디렉토리를 생성해야 합니다. 터미널을 열고 다음 명령을 실행합니다.

  1. mkdir flask_request_example

그런 다음 새 디렉터리로 이동합니다.

  1. cd flask_request_example

다음으로 Flask를 설치합니다. 터미널을 열고 다음 명령을 실행합니다.

  1. pipenv install Flask

pipenv 명령은 이 프로젝트에 대한 virtualenv, Pipfile, 설치 flask 및 Pipfile.lock을 생성합니다.

프로젝트의 virtualenv를 활성화하려면 다음 명령을 실행하십시오.

  1. pipenv shell

Flask에서 들어오는 데이터에 액세스하려면 request 객체를 사용해야 합니다. request 개체는 무엇보다도 mimetype, 리퍼러, IP 주소, 원시 데이터, HTTP 메서드 및 헤더를 포함하여 요청에서 들어오는 모든 데이터를 보유합니다.

request 개체가 보유한 모든 정보가 유용할 수 있지만 이 문서의 목적을 위해 일반적으로 엔드포인트 호출자가 직접 제공하는 데이터에 초점을 맞춥니다.

Flask에서 요청 개체에 대한 액세스 권한을 얻으려면 Flask 라이브러리에서 가져와야 합니다.

from flask import request

그런 다음 모든 보기 기능에서 사용할 수 있습니다.

코드 편집기를 사용하여 app.py 파일을 만듭니다. Flaskrequest 개체를 가져옵니다. 또한 query-example, form-examplejson-example에 대한 경로를 설정합니다.

# import main Flask class and request object
from flask import Flask, request

# create the Flask app
app = Flask(__name__)

@app.route('/query-example')
def query_example():
    return 'Query String Example'

@app.route('/form-example')
def form_example():
    return 'Form Data Example'

@app.route('/json-example')
def json_example():
    return 'JSON Object Example'

if __name__ == '__main__':
    # run app in debug mode on port 5000
    app.run(debug=True, port=5000)

그런 다음 터미널을 열고 다음 명령으로 앱을 시작합니다.

  1. python app.py

앱이 포트 5000에서 시작되므로 다음 링크를 사용하여 브라우저에서 각 경로를 볼 수 있습니다.

http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
http://127.0.0.1:5000/json-example (or localhost:5000/json-example)

이 코드는 세 개의 경로를 설정하고 각 경로를 방문하면 \Query String Example\, \Form Data Example\\JSON Object Example\<의 메시지가 표시됩니다. /코드> 각각.

쿼리 인수 사용

쿼리 문자열에 추가하는 URL 인수는 웹 앱에 데이터를 전달하는 일반적인 방법입니다. 웹을 탐색하는 동안 이전에 쿼리 문자열을 접했을 것입니다.

쿼리 문자열은 다음과 유사합니다.

example.com?arg1=value1&arg2=value2

쿼리 문자열은 물음표(?) 문자 다음에 시작됩니다.

example.com?arg1=value1&arg2=value2

그리고 앰퍼샌드(&) 문자로 구분된 키-값 쌍이 있습니다.

example.com?arg1=value1&arg2=value2

각 쌍에 대해 키 다음에는 등호(=) 문자와 값이 옵니다.

arg1 : value1
arg2 : value2

쿼리 문자열은 사용자가 조치를 취할 필요가 없는 데이터를 전달하는 데 유용합니다. 앱 어딘가에 쿼리 문자열을 생성하고 URL에 추가하여 사용자가 요청할 때 데이터가 자동으로 전달되도록 할 수 있습니다. 쿼리 문자열은 메서드로 GET이 있는 양식에서 생성할 수도 있습니다.

query-example 경로에 쿼리 문자열을 추가해 보겠습니다. 이 가상의 예에서는 화면에 표시될 프로그래밍 언어의 이름을 제공합니다. language 키와 Python 값을 만듭니다.

http://127.0.0.1:5000/query-example?language=Python

앱을 실행하고 해당 URL로 이동하면 여전히 \Query String Example\ 메시지가 표시되는 것을 볼 수 있습니다.

쿼리 인수를 처리하는 부분을 프로그래밍해야 합니다. 이 코드는 request.args.get(language) 또는 request.args[language]를 사용하여 language 키에서 읽습니다.

request.args.get(language)를 호출하면 language 키가 URL에 없으면 애플리케이션이 계속 실행됩니다. 이 경우 메서드의 결과는 None이 됩니다.

request.args[language]를 호출하면 URL에 language 키가 없으면 앱이 400 오류를 반환합니다.

쿼리 문자열을 처리할 때 request.args.get()을 사용하여 앱이 실패하지 않도록 하는 것이 좋습니다.

language 키를 읽고 출력으로 표시해 봅시다.

다음 코드를 사용하여 app.py에서 query-example 경로를 수정합니다.

@app.route('/query-example')
def query_example():
    # if key doesn't exist, returns None
    language = request.args.get('language')

    return '''<h1>The language value is: {}</h1>'''.format(language)

그런 다음 앱을 실행하고 다음 URL로 이동합니다.

http://127.0.0.1:5000/query-example?language=Python

브라우저에 다음 메시지가 표시되어야 합니다.

Output
The language value is: Python

URL의 인수는 언어 변수에 할당된 다음 브라우저로 반환됩니다.

더 많은 쿼리 문자열 매개 변수를 추가하려면 앰퍼샌드와 새 키-값 쌍을 URL 끝에 추가할 수 있습니다. framework 키와 Flask 값을 만듭니다.

http://127.0.0.1:5000/query-example?language=Python&framework=Flask

더 많은 것을 원한다면 앰퍼샌드와 키-값 쌍을 계속 추가하세요. \website\ 키와 \DigitalOcean\ 값을 생성합니다.

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean

이러한 값에 액세스하려면 여전히 request.args.get() 또는 request.args[]를 사용합니다. 누락된 키가 있을 때 어떤 일이 발생하는지 보여주기 위해 두 가지를 모두 사용하겠습니다. query_example 경로를 수정하여 결과 값을 변수에 할당한 다음 표시합니다.

@app.route('/query-example')
def query_example():
    # if key doesn't exist, returns None
    language = request.args.get('language')

    # if key doesn't exist, returns a 400, bad request error
    framework = request.args['framework']

    # if key doesn't exist, returns None
    website = request.args.get('website')

    return '''
              <h1>The language value is: {}</h1>
              <h1>The framework value is: {}</h1>
              <h1>The website value is: {}'''.format(language, framework, website)

그런 다음 앱을 실행하고 다음 URL로 이동합니다.

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean

브라우저에 다음 메시지가 표시되어야 합니다.

Output
The language value is: Python The framework value is: Flask The website value is: DigitalOcean

URL에서 language 키를 제거합니다.

http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean

언어에 대한 값이 제공되지 않으면 브라우저는 없음과 함께 다음 메시지를 표시해야 합니다.

Output
The language value is: None The framework value is: Flask The website value is: DigitalOcean

URL에서 framework 키를 제거합니다.

http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean

브라우저는 framework에 대한 값을 예상하기 때문에 오류가 발생해야 합니다.

Output
werkzeug.exceptions.BadRequestKeyError werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'framework'

이제 쿼리 문자열 처리를 이해했습니다. 다음 유형의 수신 데이터를 계속 살펴보겠습니다.

양식 데이터 사용

양식 데이터는 경로에 대한 POST 요청으로 전송된 양식에서 가져옵니다. 따라서 URL에서 데이터를 보는 대신(양식이 GET 요청과 함께 제출되는 경우 제외) 양식 데이터가 백그라운드에서 앱으로 전달됩니다. 전달되는 양식 데이터를 쉽게 볼 수 없더라도 앱은 여전히 읽을 수 있습니다.

이를 시연하려면 app.py에서 form-example 경로를 수정하여 GET 및 POST 요청을 모두 수락하고 양식을 반환합니다.

# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    return '''
              <form method="POST">
                  <div><label>Language: <input type="text" name="language"></label></div>
                  <div><label>Framework: <input type="text" name="framework"></label></div>
                  <input type="submit" value="Submit">
              </form>'''

그런 다음 앱을 실행하고 다음 URL로 이동합니다.

http://127.0.0.1:5000/form-example

브라우저는 두 개의 입력 필드(언어프레임워크용)와 제출 버튼이 있는 양식을 표시해야 합니다.

이 양식에 대해 알아야 할 가장 중요한 점은 양식을 생성한 동일한 경로에 대해 POST 요청을 수행한다는 것입니다. 앱에서 읽을 키는 모두 양식 입력의 name 속성에서 가져옵니다. 이 경우 언어프레임워크는 입력의 이름이므로 앱에서 액세스할 수 있습니다.

보기 기능 내에서 요청 방법이 GET인지 POST인지 확인해야 합니다. GET 요청인 경우 양식을 표시할 수 있습니다. 그렇지 않고 POST 요청인 경우 들어오는 데이터를 처리해야 합니다.

다음 코드를 사용하여 app.py에서 form-example 경로를 수정합니다.

# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    # handle the POST request
    if request.method == 'POST':
        language = request.form.get('language')
        framework = request.form.get('framework')
        return '''
                  <h1>The language value is: {}</h1>
                  <h1>The framework value is: {}</h1>'''.format(language, framework)

    # otherwise handle the GET request
    return '''
           <form method="POST">
               <div><label>Language: <input type="text" name="language"></label></div>
               <div><label>Framework: <input type="text" name="framework"></label></div>
               <input type="submit" value="Submit">
           </form>'''

그런 다음 앱을 실행하고 다음 URL로 이동합니다.

http://127.0.0.1:5000/form-example

언어 필드를 Python 값으로 채우고 프레임워크 필드를 Flask 값으로 채웁니다. 그런 다음 제출을 누릅니다.

브라우저에 다음 메시지가 표시되어야 합니다.

Output
The language value is: Python The framework value is: Flask

이제 양식 데이터 처리를 이해했습니다. 다음 유형의 수신 데이터를 계속 살펴보겠습니다.

JSON 데이터 사용

JSON 데이터는 일반적으로 경로를 호출하는 프로세스에 의해 구성됩니다.

예제 JSON 개체는 다음과 같습니다.

{
    "language" : "Python",
    "framework" : "Flask",
    "website" : "Scotch",
    "version_info" : {
        "python" : "3.9.0",
        "flask" : "1.1.2"
    },
    "examples" : ["query", "form", "json"],
    "boolean_test" : true
}

이 구조를 사용하면 쿼리 문자열 및 양식 데이터와 달리 훨씬 더 복잡한 데이터를 전달할 수 있습니다. 이 예에서는 중첩된 JSON 개체와 항목 배열을 볼 수 있습니다. Flask는 이 형식의 데이터를 처리할 수 있습니다.

POST 요청을 수락하고 GET과 같은 다른 요청을 무시하도록 app.py에서 form-example 경로를 수정합니다.

@app.route('/json-example', methods=['POST'])
def json_example():
    return 'JSON Object Example'

쿼리 문자열 및 양식 데이터에 사용되는 웹 브라우저와 달리 이 문서의 목적상 JSON 개체를 보내려면 Postman을 사용하여 사용자 지정 요청을 URL로 보냅니다.

참고: Postman 인터페이스에서 요청을 탐색하는 데 도움이 필요한 경우 공식 문서를 참조하세요.

Postman에서 URL을 추가하고 유형을 POST로 변경합니다. 본문 탭에서 원시로 변경하고 드롭다운에서 JSON을 선택합니다.

이러한 설정은 Postman이 JSON 데이터를 제대로 보낼 수 있고 Flask 앱이 JSON을 수신하고 있음을 이해하는 데 필요합니다.

POST http://127.0.0.1:5000/json-example
Body
raw JSON

다음으로 이전 JSON 예제를 텍스트 입력에 복사합니다.

요청을 보내면 응답으로 \JSON Object Example\을 받아야 합니다. 이는 상당히 반기후적이지만 JSON 데이터 응답을 처리하기 위한 코드가 아직 작성되지 않았기 때문에 예상됩니다.

데이터를 읽으려면 Flask가 JSON 데이터를 Python 데이터 구조로 변환하는 방법을 이해해야 합니다.

  • 객체인 모든 것은 Python dict로 변환됩니다. JSON의 {\key\ : \value\}는 Python에서 값을 반환하는 somedict[key]에 해당합니다.
  • JSON의 배열은 Python의 목록으로 변환됩니다. 구문이 동일하므로 예시 목록은 다음과 같습니다. [1,2,3,4,5]
  • JSON 개체의 따옴표 안에 있는 값은 Python에서 문자열이 됩니다.
  • 부울 truefalse는 Python에서 TrueFalse가 됩니다.
  • 마지막으로 따옴표가 없는 숫자는 Python에서 숫자가 됩니다.

이제 들어오는 JSON 데이터를 읽는 코드를 작성해 보겠습니다.

먼저 request.get_json()을 사용하여 JSON 개체의 모든 것을 변수에 할당해 보겠습니다.

request.get_json()은 JSON 개체를 Python 데이터로 변환합니다. 들어오는 요청 데이터를 변수에 할당하고 json-example 경로를 다음과 같이 변경하여 반환합니다.

# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = request_data['language']
    framework = request_data['framework']

    # two keys are needed because of the nested object
    python_version = request_data['version_info']['python']

    # an index is needed because of the array
    example = request_data['examples'][0]

    boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

최상위 수준이 아닌 요소에 액세스하는 방법에 유의하십시오. [version][python]은 중첩 개체를 입력하고 있기 때문에 사용됩니다. 그리고 [examples][0]는 예제 배열의 0번째 인덱스에 액세스하는 데 사용됩니다.

요청과 함께 전송된 JSON 객체에 보기 기능에서 액세스할 수 있는 키가 없으면 요청이 실패합니다. 키가 없을 때 실패하지 않으려면 키에 액세스하기 전에 키가 있는지 확인해야 합니다.

# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = None
    framework = None
    python_version = None
    example = None
    boolean_test = None

    if request_data:
        if 'language' in request_data:
            language = request_data['language']

        if 'framework' in request_data:
            framework = request_data['framework']

        if 'version_info' in request_data:
            if 'python' in request_data['version_info']:
                python_version = request_data['version_info']['python']

        if 'examples' in request_data:
            if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                example = request_data['examples'][0]

        if 'boolean_test' in request_data:
            boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

앱을 실행하고 Postman을 사용하여 예제 JSON 요청을 제출합니다. 응답에서 다음과 같은 결과를 얻게 됩니다.

Output
The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false

이제 JSON 개체 처리를 이해했습니다.

결론

이 문서에서는 쿼리 문자열, 양식 데이터 또는 JSON 개체를 허용하는 세 가지 경로로 Flask 애플리케이션을 빌드했습니다.

또한 모든 접근 방식은 키가 없을 때 정상적으로 실패하는 것에 대한 반복적인 고려 사항을 해결해야 했습니다.

경고: 이 기사에서 다루지 않은 한 가지 주제는 사용자 입력을 삭제하는 것이었습니다. 사용자 입력을 삭제하면 응용 프로그램에서 읽은 데이터로 인해 예기치 않은 오류가 발생하거나 보안 조치가 우회되지 않습니다.

Flask에 대해 자세히 알아보려면 Flask 주제 페이지에서 연습 및 프로그래밍 프로젝트를 확인하세요.