Pythonのrequestsを利用してRest API(json形式)でファイルダウンロードする方法

More than 1 year has passed since last update.


1. はじめに

PythonのHTTPクライアントライブラリであるrequestsを利用して、json形式のデータを送受信するRest APIでファイルダウンロードを行う方法について説明したいと思います。

ポイントはbase64でascii文字列をデコードしてバイナリデータを取得することです。

なお、アップロードについては「Pythonのrequestsを利用してRest API(json形式)にファイルアップロードする方法」を参照ください。


2. ソースコード


jsonFileDownloadDemo.py

# -*- coding: utf-8 -*-

import requests
import base64
import os
from datetime import datetime

# ★ポイント1
# ex) set DOWNLOAD_SAVE_DIR=C:/Temp/flaskDownloadSaveDir
DOWNLOAD_SAVE_DIR = os.getenv("DOWNLOAD_SAVE_DIR")

# main
# json with base64 encoding
# {
# 'fileName': 'ファイル名',
# 'contentType': 'mimetype',
# 'contentData': 'バイナリデータをbase64でエンコードしたascii文字列'
# }
if __name__ == "__main__":

# ★ポイント2
url = 'http://localhost:3000/download/json'
response = requests.get(url)

# ★ポイント3
downloadData = response.json()
fileName = downloadData['fileName']
contentType = downloadData['contentType']
contentDataAscii = downloadData['contentData']

# ★ポイント4
contentData = base64.b64decode(contentDataAscii)

# ★ポイント5
saveFileName = datetime.now().strftime("%Y%m%d_%H%M%S_") + fileName
saveFilePath = os.path.join(DOWNLOAD_SAVE_DIR, saveFileName)
with open(saveFilePath, 'wb') as saveFile:
saveFile.write(contentData)


★ポイント1

サンプルではダウンロードしたファイルを保存するディレクトリを環境変数から取得できるようにしました。

★ポイント2

requestsget()でRest APIのURLにアクセスします。特別なことはありません。

★ポイント3

json()で受信したデータをjsonとしてアクセスします。

この時点ではファイルデータは単なるascii文字列になっているため、こちらも特別なことはありません。


  • fileNameフィールド : ダウンロードファイルのファイル名

  • contentTypeフィールド : ダウンロードファイルのMIMEタイプ

  • contentDataフィールド : ダウンロードファイルのファイルデータ

(注意)

APIの仕様としてそのように定義しているだけです。

★ポイント4

今回の記事の最大ポイントです。jsonではバイナリデータを設定できないため、base64でエンコードしたascii文字列で送られてきます。

base64.b64decode()を利用してバイナリデータにデコードします。

★ポイント5

★ポイント4で取得したバイナリデータをファイルとして保存します。普通のファイル保存の処理です。

サンプルでは★ポイント1で取得したディレクトリに、年月日時分秒のプレフィックスを付与して保存しています。


3. さいごに

今回はrequestsRest API(json形式)におけるファイルダウンロードの方法について説明しました。

ポイントはbase64でデコードするだけなので、特に難しいところはなかったと思います。

jsonのデシリアライズやbase64のデコードが発生するため、データサイズの大きなファイルのダウンロードは控えるようにした方がよいでしょう。