Traffine I/O

日本語

2022-10-03

AWS Chaliceにおけるmultipart/form-dataの処理

はじめに

この記事では、AWS Chaliceを使用してmultipart/form-dataを受信し処理する方法について、リクエストの処理、データの解析、ファイルとフォームフィールドの抽出を含めて説明します。

フォーム送信用のルートの作成

まず、 app.pyファイルに新しいルートを作成して、フォーム送信を処理するようにします。このルートは、 POSTリクエストを受け取り、コンテンツの種類がmultipart/form-dataであることを想定しています。

app.py
app = Chalice(app_name='my_chalice_app')

@app.route('/submit-form', methods=['POST'], content_types=['multipart/form-data'])
def submit_form():
    pass

CGIライブラリを使用してマルチパートデータを解析

次に、 submit_form()関数を変更して、 CGIライブラリを使用して受信したマルチパートフォームデータを解析する必要があります。これを行うには、 FieldStorageインスタンスを作成し、 app.current_request.raw_bodyとリクエストのコンテンツタイプを渡す必要があります。

app.py
from io import BytesIO

def submit_form():
    content_type = app.current_request.headers['content-type']
    content_length = int(app.current_request.headers['content-length'])
    raw_body = app.current_request.raw_body
    environ = {
        'REQUEST_METHOD': 'POST',
        'CONTENT_TYPE': content_type,
        'CONTENT_LENGTH': content_length,
        'wsgi.input': BytesIO(raw_body),
    }
    form_data = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ, keep_blank_values=True)

フォームデータとファイルの抽出

フォームデータが解析されたら、 form_dataオブジェクトを使用して送信されたフィールドとファイルにアクセスできます。例えば、 descriptionという名前のテキストフィールドの値を取得するには、次のようにします。

app.py
description = form_data.getvalue('description')

アップロードされたファイルにアクセスするには、 form_data['file_field']構文を使用できます。例えば、フィールド名がfileの下にアップロードされたファイルを取得するには、次のコードを使用できます。

app.py
uploaded_file = form_data['file']
filename = uploaded_file.filename
file_content = uploaded_file.file.read()

エラー処理とバリデーション

アプリケーションがエラーやエッジケースを正しく処理するためには、処理する前に送信されたフォームデータをバリデーションする必要があります。例えば、必須フィールドが欠落しているか、ファイルサイズがある程度の制限を超えているかどうかを確認できます。

pp.py
def validate_form_data(form_data):
    if 'description' not in form_data:
        raise BadRequestError('Missing description field.')
    if 'file' not in form_data:
        raise BadRequestError('Missing file field.')
    if len(form_data['file'].file.read()) > MAX_FILE_SIZE:
        raise BadRequestError('File size exceeds the allowed limit.')

def submit_form():
    # ... (previous code)
    validate_form_data(form_data)

忘れずに、 app.pyファイルの先頭で適切な値でMAX_FILE_SIZE定数を定義するようにしてください。

app.py
MAX_FILE_SIZE = 10 * 1024 * 1024  # 10 MB

これらの手順に従うことで、AWS ChaliceとCGIライブラリを使用してマルチパートフォームデータを受信し処理することができます。

全体のコード

以下に全体のコードを示します。

app.py
import cgi
import json
from io import BytesIO
from chalice import Chalice, BadRequestError

app = Chalice(app_name='my_chalice_app')
MAX_FILE_SIZE = 10 * 1024 * 1024  # 10 MB

@app.route('/submit-form', methods=['POST'], content_types=['multipart/form-data'])
def submit_form():
    content_type = app.current_request.headers['content-type']
    content_length = int(app.current_request.headers['content-length'])
    raw_body = app.current_request.raw_body

    environ = {
        'REQUEST_METHOD': 'POST',
        'CONTENT_TYPE': content_type,
        'CONTENT_LENGTH': content_length,
        'wsgi.input': BytesIO(raw_body),
    }

    form_data = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ, keep_blank_values=True)
    validate_form_data(form_data)

    description = form_data.getvalue('description')
    uploaded_file = form_data['file']
    filename = uploaded_file.filename
    file_content = uploaded_file.file.read()

    # Process and handle the form data and uploaded file as needed
    # ...

    return {'status': 'success'}

def validate_form_data(form_data):
    if 'description' not in form_data:
        raise BadRequestError('Missing description field.')
    if 'file' not in form_data:
        raise BadRequestError('Missing file field.')
    if len(form_data['file'].file.read()) > MAX_FILE_SIZE:
        raise BadRequestError('File size exceeds the allowed limit.')

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!