0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonで認証・CRUD無しの簡易APIサーバを作る方法

Last updated at Posted at 2021-11-25

Pythonで本格的なAPIサーバを作ろうとすると「Django REST Framework」が真っ先に思い浮かぶと思いますが、簡易的にAPIレスポンスが欲しい時もあると思います。

ここでは、ローカルホスト上でPythonから、認証・CRUD無しでhttpレスポンスを返す方法を2つ紹介します。

注意事項

下記方法ではCSRFの対策を行なっていません。
本番環境で使用する際には、他の方法で正しい(想定したサイトの想定したユーザーから受け取った)リクエストかどうかを検証する必要があります。

Python WSGI を使う方法

一番簡易的に使えるのは、Pythonの標準インターフェイスであるWSGI(Web Server Gateway Interface)を使う方法です。

WSGIの詳細について、調べれば詳しい記載が出てくると思いますが、今回は簡単にPOSTされたデータを返すAPIサーバを例に挙げます。

test_api.py
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()

一つのターミナルでサーバを起動します。

shell-1
$ python test_api.py 
>> Serving on port 8000...

上とは別のターミナルを起動し、挙動を確認します。

shell-2
$ 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のレスポンスサーバとしてこれを無効にする処理を書かないと、エラーになってしまうので注意が必要です。

shell
$ mkdir 作業フォルダ
$ cd 作業フォルダ
$ django-admin startproject config .
$ python manage.py startapp api
config/urls.py
from django.contrib import admin
from django.urls import path, include #"include"を追加

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')), #追加
]

下記ファイルを追加

api/urls.py
from django.urls import path
from . import views

app_name = 'api'
urlpatterns = [
    path('', views.index, name='api'),   
]

下記ファイルを編集

api/views.py
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)

一つのターミナルでサーバを起動します。

shell-1
$ 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.

上とは別のターミナルを起動し、挙動を確認します。

shell-2
$ 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サーバの完成です。

0
0
0

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
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?