Python、Requestsを使ったファイルアップロード
基本的な使い方
import requests
url = 'http://test.com/api/image/'
file = {'upload_file': open('test.png', 'rb')}
res = requests.post(url, files=file)
すごく簡単です。強いて注意点を挙げるならば、
- URLを間違えないこと
- 名前を間違えないこと(
upload_file
の部分) requests.post()
のfiles引数を使うこと
でしょうか。
Djangoで受け取る
Djangoで受け取る場合のサンプルコードです。
models.py
に、ImageField
を持つシンプルなモデルを定義しています。
from django.db import models
class Photo(models.Model):
"""写真"""
file = models.ImageField('ファイル')
views.py
です。
from django.contrib.sites.shortcuts import get_current_site
from django.http import HttpResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from .models import Photo
@require_POST
@csrf_exempt
def upload(request):
"""/upload で呼び出される。"""
# アップロードされたファイルを保存する。
upload_file = request.FILES['file']
photo = Photo(file=upload_file)
photo.save()
# ファイルにアクセスするためのURLを作成する。
current_site = get_current_site(request)
domain = current_site.domain
download_url = '{0}://{1}{2}'.format(
request.scheme,
domain,
photo.file.url,
)
# URLを文字列として返す。
return HttpResponse(download_url, content_type="text/plain")
@require_POST
は、POSTメソッドだけ受け付けるデコレータです。よく使うやつですね。
@csrf_exempt
ですが、通常POSTメソッドでは{% csrf_token %}
で発行されるトークンも一緒に送信する必要があります。これはCSRFという攻撃を防ぐためのものですが、今回のようにちょっとしたAPIとして公開したい場合は邪魔になったり、対策が面倒なこともあります。そのような場合にこのデコレータをつけることで、トークンが不要になり簡単に利用できるようになります。
URLの作成処理ですが、これはイディオムとして覚える価値のある処理だと個人的には思います。サイト内のURLをフルパスで作成する場合は大体このような処理をすることになります。
# ファイルにアクセスするためのURLを作成する。
current_site = get_current_site(request)
domain = current_site.domain
download_url = '{0}://{1}{2}'.format(
request.scheme,
domain,
photo.file.url,
)
そして、requestsでのアップロードを行うスクリプトupload.py
です。最初に紹介した内容とほぼ同じです。こちらはコメントを見れば何となくわかると思います。
import requests
# Djangoのuploadビューが呼ばれるURL
url = 'http://127.0.0.1:8000/upload/'
# ビュー内でのrequest.FILES['file']の'file'に対応
file = {'file': open('sample.png', 'rb')}
# 送信する。
res = requests.post(url, files=file)
# res.textに、画像にアクセスするためのURLが入っています。
print(res.text)
ソースコードのダウンロード
Githubに、ソースコードを置きました。READMEのとおり、クローンして実行すると試せます。