🤖

DrupalのJSON:APIを用いて、ユーザ名とパスワードでデータ登録を行う

2025/03/01に公開

概要

過去に、DrupalのJSON:APIを用いて、Pythonによるデータ登録を行う記事を執筆しました。

以下は、Basic認証を用いた方法です。

https://zenn.dev/nakamura196/articles/1cc654fc266d17

また以下は、API Keyを用いた方法です。

https://zenn.dev/nakamura196/articles/8aa4e4e83f56bd

これらに加えて、通常のログインによる登録を行うことができたので、備忘録です。

コード

以下の通りです。ログインやCSRFトークンを取得した上で、コンテンツを登録します。

import requests
import json
import os
from dotenv import load_dotenv

class ApiClient:
    def __init__(self):
        load_dotenv(override=True)

        # DrupalサイトのURL(例)
        self.DRUPAL_BASE_URL = os.getenv("DRUPAL_BASE_URL")  

        # エンドポイント(JSON:API)
        # self.JSONAPI_ENDPOINT = f"{self.DRUPAL_BASE_URL}/jsonapi/node/article"

        # 認証情報(Basic認証)
        self.USERNAME = os.getenv("USERNAME")
        self.PASSWORD = os.getenv("PASSWORD")

    def login(self):
        # ログインリクエスト
        login_url = f"{self.DRUPAL_BASE_URL}/user/login?_format=json"

        login_response = requests.post(
            login_url,
            json={"name": self.USERNAME, "pass": self.PASSWORD},
            headers={"Content-Type": "application/json"}
        )

        if login_response.status_code == 200:
            self.session_cookies = login_response.cookies

    def get_csrf_token(self):
        # CSRFトークンを取得
        csrf_token_response = requests.get(
            f"{self.DRUPAL_BASE_URL}/session/token",
            cookies=self.session_cookies  # ここでログインセッションを渡す
        )

        if csrf_token_response.status_code == 200:
            # return csrf_token_response.text
            # self.csrf_token = csrf_token_response.text
            self.headers = {
                "Content-Type": "application/vnd.api+json",
                "Accept": "application/vnd.api+json",
                "X-CSRF-Token": csrf_token_response.text,
            }
        else:
            # raise Exception(f"CSRFトークン取得失敗: {csrf_token_response.status_code} {csrf_token_response.text}")
            self.csrf_token = None

    def create_content(self, data: dict):
        # 記事作成リクエスト
        url = f"{self.DRUPAL_BASE_URL}/jsonapi/{data['data']['type'].replace('--', '/')}"
        response = requests.post(
            # self.JSONAPI_ENDPOINT,
            url,
            headers=self.headers,
            cookies=self.session_cookies,
            json=data
        )

        if response.status_code == 201:
            print("コンテンツが作成されました!")
        else:
            print("エラー:", response.status_code, response.text)

これにより、以下で、コンテンツを登録することができました。

apliClient = ApiClient()
apliClient.login()
apliClient.get_csrf_token()

# 記事データ
data = {
    "data": {
        "type": "node--article",
        "attributes": {
            "title": "新しい記事のタイトル",
            "body": {
                "value": "記事の本文です。",
                "format": "plain_text"
            }
        }
    }
}

apliClient.create_content(data)

まとめ

誤っている点もあるかもしれませんが、参考になりましたら幸いです。

Discussion