search
LoginSignup
46

More than 5 years have passed since last update.

posted at

Pythonのrequestsを利用してmultipart/form-dataのFormにファイルアップロードする方法

1. はじめに

前回の記事で予告した通り、今回はHTTPクライアントライブラリであるrequestsを利用したmultipart/form-dataによるファイルアップロードの方法について説明したいと思います。

2. ソースコード

multipartFileUploadApp.py
# -*- coding: utf-8 -*-
import requests

# ★ポイント1
XLSX_MIMETYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

# <form action="/data/upload" method="post" enctype="multipart/form-data">
#   <input type="file" name="uploadFile"/>
#   <input type="submit" value="submit"/>
# </form>

# main
if __name__ == "__main__":

    # ★ポイント2
    fileName = 'demo01.xlsx'
    fileDataBinary = open(fileName, 'rb').read()
    files = {'uploadFile': (fileName, fileDataBinary, XLSX_MIMETYPE)}

    # ★ポイント3
    url = 'http://localhost:3000/data/upload'
    response = requests.post(url, files=files)

    print(response.status_code)
    print(response.content)

★ポイント1
ファイルをアップロードする場合、ファイルフォーマットをサーバに知らせるため、MIMEタイプ(コンテントタイプ)を利用するのが一般的です。
サンプルでアップロードするxlsxのMIMEタイプは「2007 Office system ファイル形式の MIME タイプをサーバーで登録する」を参考にしました。

★ポイント2
今回の記事の最大ポイントです。といっても特別なことはなくrequestsの公式ガイドラインにしっかりと書かれています。
アップロードファイルの情報をタプルで定義するだけです。タプルの内容は以下の通りです。

  • 第1引数 : アップロードファイルのファイル名
  • 第2引数 : アップロードファイルのファイルデータ
  • 第3引数 : アップロードファイルのMIMEタイプ

一般的に1つのFormに複数の<input type="file">を定義することができます。requestsではアップロードファイルの情報をDictで定義し、複数のファイルに対応します。Dictのキーと値は以下の通りです。

  • キー : Formの<input type="file">のname属性の値
  • 値 : アップロードファイルのタプル

★ポイント3
requestspost()でHTTPリクエストを発行します。この際、filesパラメータに★ポイント2で定義したアップロードファイルのDictを設定します。これだけでmaltipart/form-dataによるファイルアップロードが実現できます。

3. サーバでHTTPリクエストヘッダを確認してみる

サーバでHTTPリクエストヘッダを確認
127.0.0.1 - - [26/Dec/2017 19:48:00] "POST /data/json/upload HTTP/1.1" 200 -
Content-Length: 9309
User-Agent: python-requests/2.18.3
Connection: keep-alive
Host: localhost:3000
Accept: */*
Content-Type: multipart/form-data; boundary=61a154f4eef94f87ac7062e266cc000a
Accept-Encoding: gzip, deflate

コンテントタイプがmultipart/form-dataになっていることが分かるかと思います。
Content-Lengthrequestsが自動で設定してくれるのでありがたいですね。

4. さいごに

今回はrequestsを利用したmaltipart/form-dataによるファイルアップロードについて説明しました。前回はRest API(json形式)によるファイルアップロードについて説明しました。
Web APIによるファイルアップロードについては、ほとんどのケースでmaltipart/form-dataかRest API(json形式)のどちらかで実現できるかと思います。
次回はFlaskにおけるファイルアップロードについて説明する予定です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
46