Pythonで本格的なAPIサーバを作ろうとすると「Django REST Framework」が真っ先に思い浮かぶと思いますが、簡易的にAPIレスポンスが欲しい時もあると思います。
ここでは、ローカルホスト上でPythonから、認証・CRUD無しでhttpレスポンスを返す方法を2つ紹介します。
注意事項
下記方法ではCSRFの対策を行なっていません。
本番環境で使用する際には、他の方法で正しい(想定したサイトの想定したユーザーから受け取った)リクエストかどうかを検証する必要があります。
Python WSGI を使う方法
一番簡易的に使えるのは、Pythonの標準インターフェイスであるWSGI(Web Server Gateway Interface)を使う方法です。
WSGIの詳細について、調べれば詳しい記載が出てくると思いますが、今回は簡単にPOSTされたデータを返すAPIサーバを例に挙げます。
from wsgiref.simple_server import make_server
import json
def app(environ, start_response):
# POST dataの取得
query = environ['wsgi.input'].read(int(environ.get('CONTENT_LENGTH', 0))).decode('utf-8')
# レスポンスヘッダの作成
status = "200 OK"
headers = [
("Content-type", "application/json; charset=utf-8"),
("Access-Control-Allow-Origin", "*"),
]
if query == "":
# POSTが空だった時の処理
response_json = {"message": "Data not sent."}
else:
# JSONをPythonの辞書型に変換
loaded_query = json.loads(query)
# JSONの中身を記述
response_json = {
"message": "This is response data!",
"query_data": loaded_query,
}
start_response(status, headers)
return [json.dumps(response_json).encode("utf-8")]
with make_server("", 8000, app) as httpd:
print("Serving on port 8000...")
httpd.serve_forever()
一つのターミナルでサーバを起動します。
$ python test_api.py
>> Serving on port 8000...
上とは別のターミナルを起動し、挙動を確認します。
$ curl -X POST -H "Content-TyGET application/json" -d '{"data":"hoge"}' localhost:8000
>> {"message": "This is response data!", "query_data": {"data": "hoge"}}
これでWGISを利用した、簡易的なAPIサーバの完成です。
Djangoを使う方法
PythonのWebフレームワークであるDjangoを使い、APIレスポンスを返す views.py
を作成することで実現することもできます。
WSGIを直接操作した場合に比べて、環境構築が必要ですが、DjangoがWSGIをラップしてくれているので、データ操作が簡単なメリットがあります。
またDjangoの場合、デフォルトでCSRFの検証を行うため、APIのレスポンスサーバとしてこれを無効にする処理を書かないと、エラーになってしまうので注意が必要です。
$ mkdir 作業フォルダ
$ cd 作業フォルダ
$ django-admin startproject config .
$ python manage.py startapp api
from django.contrib import admin
from django.urls import path, include #"include"を追加
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')), #追加
]
下記ファイルを追加
from django.urls import path
from . import views
app_name = 'api'
urlpatterns = [
path('', views.index, name='api'),
]
下記ファイルを編集
from django.views.decorators.csrf import csrf_exempt
from django.http.response import JsonResponse
import json
@csrf_exempt
def index(request):
# GET時の処理
if request.method == 'GET':
return JsonResponse({"message": "This is GET respons."})
# POST dataの取得
if request.body == b"":
return JsonResponse({"message": "Data not sent."})
query = request.body.decode("utf-8")
# JSONをPythonの辞書型に変換
loaded_query = json.loads(query)
# JSONの中身を記述
response_json = {
"message": "This is response data!",
"query_data": loaded_query,
}
# JSONに変換して戻す
return JsonResponse(response_json)
一つのターミナルでサーバを起動します。
$ python manage.py runserver
>> Django version 3.x.x, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
上とは別のターミナルを起動し、挙動を確認します。
$ curl -X POST -H "Content-TyGET application/json" -d '{"data":"foo"}' localhost:8000/api/
>> {"message": "This is response data!", "query_data": {"data": "foo"}}
これでDjangoを利用した、簡易的なAPIサーバの完成です。