🤖
DrupalのJSON:APIを用いて、ユーザ名とパスワードでデータ登録を行う
概要
過去に、DrupalのJSON:APIを用いて、Pythonによるデータ登録を行う記事を執筆しました。
以下は、Basic認証を用いた方法です。
また以下は、API Keyを用いた方法です。
これらに加えて、通常のログインによる登録を行うことができたので、備忘録です。
コード
以下の通りです。ログインや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