Я обнаружил, что редактирование full_description
репозитория DockerHub можно сделать с помощью JavaScript API , и подумал, что это было бы забавным предлогом для изучения пакета requests
для python. JavaScript API определенно работает, например, используя этот простой образ докера .
API JS в основном делает
- Отправьте запрос
POST
на https://hub.docker.com/v2/users/login
с именем пользователя и паролем. Сервер отвечает token
.
- Отправьте
PATCH
запрос на определенный https://hub.docker.com/v2/repositories/{user or org}/{repo}
, убедившись, что заголовок имеет Authorization: JWT {token}
, и в этом случае с телом содержимого {"full_description":"...value..."}
.
Что беспокоит, так это то, что запрос PATCH
на стороне python получает ответ 200 от сервера (если вы намеренно установили неверный токен авторизации, вы получите отказ, как и ожидалось). Но его ответ на самом деле содержит текущую информацию (а не пропатченную информацию).
Единственные "открытия", которые я сделал:
Если вы добавите отладочный журнал , есть 301. Но это тот же URL для стороны javascript, так что это не имеет значения?
send: b'{"full_description": "TEST"}'
reply: 'HTTP/1.1 301 MOVED PERMANENTLY\r\n'
Маркер, полученный с помощью POST
в requests
, такой же, как если бы я GET
- auth.docker.io
, как описано в Получение токена на предъявителя раздел здесь . В частности , я не указал пароль (только что сделал curl -X GET ...
). Это не так. Они разные, я не знаю, как я думал, что они были одинаковыми.
Этот второй заставляет меня чувствовать, что я пропускаю шаг. Как мне нужно расшифровать токен или что-то? Я не знаю, что еще с этим делать, особенно ответ 200
от PATCH
, несмотря на отсутствие изменений.
код:
import json
from textwrap import indent
import requests
if __name__ == "__main__":
username = "<< SET THIS VALUE >>"
password = "<< SET THIS VALUE >>"
repo = "<< SET THIS VALUE >>"
base_url = "https://hub.docker.com/v2"
login_url = f"{base_url}/users/login"
repo_url = f"{base_url}/repositories/{username}/{repo}"
# NOTE: if I use a `with requests.Session()`, then I'll get
# CSRF Failed: CSRF token missing or incorrect
# Because I think that csrftoken is only valid for login page (?)
# Get login token and create authorization header
print("==> Logging into DockerHub")
tok_req = requests.post(login_url, json={"username": username, "password": password})
token = tok_req.json()["token"]
headers = {"Authorization": f"JWT {token}"}
print(f"==> Sending PATCH request to {repo_url}")
payload = {"full_description": "TEST"}
patch_req = requests.patch(repo_url, headers=headers, json=payload)
print(f" Response (status code: {patch_req.status_code}):")
print(indent(json.dumps(patch_req.json(), indent=2), " "))