Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.
Знакомство с веб-API Simple-Server
Перед началом работы с любым API необходимо в первую очередь ознакомиться с его документацией. Это позволит узнать, какие функции и методы доступны, каким образом можно отправлять запросы (описание конечных точек), и какие коды ответов могут быть получены от API.
Обратившись к документации веб-API Simple-Server, мы увидим, что все запросы выполняются с использованием HTTP-протокола и все ответы возвращаются в виде JSON, поддерживаются методы GET, POST, PUT, DELETE и PATCH.
Также в документации описаны возможные коды ответов. Коды ответов можно разделить на 3 группы:
- 2** — означает «успех». Запрос был выполнен корректно, в теле ответа содержится информация, если это было предусмотрено.
- 4** - означает, что в запросе допущена ошибка. Ошибка не связана с работой сервера, а возникает именно из-за некорректно выполненного запроса.
- 5** — ошибка сервера. Ошибка может возникнуть, если на сервере возникли какие-то проблемы. При возникновении ошибки стоит подождать некоторое время. Если ошибка не пропадает, стоит обратиться в поддержку с подробным описанием того, как воспроизвести проблему.
Отдельно стоит отметить 429 код ответа — он может возникнуть, если было выполнено более 20 запросов в секунду.
Стоит упомянуть, что как и у многих других сервисов, у Simple-Server есть «оболочка» над веб-API — Simple-Server CLI. Этот инструмент позволяет создавать и настраивать облачные серверы, хранилища данных и прочие облачных ресурсы средствами командной строки.
Приступим к созданию проекта. Создайте директорию TWAPI:
Перейдите в новый каталог:
Создайте виртуальное окружение Python:
Виртуальное окружение в Python используется для изоляции проектов и их зависимостей, обеспечивая чистоту кода и избегая конфликтов между библиотеками разных версий.
Активируйте виртуальное окружение:
source ./venv/bin/activateУстановим библиотеку requests:
Перед началом работы с веб-API, нам необходимо получить токен. Токен — это специальный ключ, который используется для аутентификации и авторизации пользователя при доступе к ресурсам. Он обеспечивает безопасность, контроль доступа и идентификацию запросов, позволяя серверу определить, какие действия и данные может выполнять или получать конкретный пользователь или приложение.
Для создания токена переходим во вкладку «API и Terrafrom» в панели управления аккаунтом.
Нажимаем «Создать». Вводим имя токена, при необходимости меняем срок действия токена. Галочку с «Удалять сервисы по API без кода в Телеграме» можно не снимать.
После нажатия на кнопку «Выпустить» появится возможность скопировать токен. На данном этапе его стоит сохранить в каком-либо файле, так как после закрытия окна увидеть токен вновь не удастся. Временно сохранить токен можно в файл token.txt, выполнив команду в директории проекта:
echo 'скопированный_токен' > token.txtВАЖНО: Если стороннее лицо завладеет вашим токеном, ему будут доступны любые операции с вашим аккаунтом. Поэтому, если вы собираетесь загружать проект, например, в публичный репозиторий github, файл token.txt необходимо добавить в .gitignore.
Выполнив настройку среды и получив токен для работы с веб-API, создадим файл main.py в директории проекта. В файле выполним подключение библиотек requests и json:
import requests
import jsonЭти инструкции подключают библиотеки, облегчающие выполнение HTTP-запросов к серверу и работу с форматом JSON.
Следующим шагом объявим необходимые переменные:
token = 'токен_полученный_ранее'
api_url_base = 'https://simple-server.tech/'ВАЖНО: В «боевых» проектах не стоит указывать токен в коде скрипта. Чувствительные данные не должны храниться в коде скрипта, так как это создает риск утечки данных в случае доступа к исходному коду или его случайной публикации. Для подключения токена лучше использовать переменные окружения. В рамках этой статьи токен будет указан в коде скрипта для упрощения демонстрации.
Переменная api_url_base хранит в себе URl, одинаковый для всех конечных точек API.
Далее настроим HTTP-заголовки, следуя документации:
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
}Заголовок Content-Type указывает серверу на то, что в теле запроса передаются данные в формате JSON. Заголовок Authorization должен содержать в себе токен. Его можно было бы указать строкой в заголовке, но тогда код становится нечитаемым и неподдерживаемым.
import requests
import json
token = 'токен_полученный_ранее'
api_url_base = 'https://simple-server.tech/'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
}На этом подготовительный этап завершен, и мы можем приступить к выполнению запросов.
Получение информации о балансе аккаунта
Обратимся к документации и увидим, что для получения платежной информации необходимо отправить GET-запрос к `https://simple-server.tech/ Из документации также узнаем, что при корректном запросе код ответа будет 200.
Реализуем функцию для получения платежной информации аккаунта:
def get_finances_info():
api_url = f'{api_url_base}account/finances'
response = requests.get(api_url, headers=headers)
if response.status_code == 200:
print('Платежная информация:')
for key, value in json.loads(response.content.decode('utf-8'))['finances'].items():
print(key, value)
else:
print (f'Ошибка {response.status_code}')- В
api_urlпри помощи f-строк мы объединилиapi_url_base, объявленную ранее, сaccount/finances. В результате мы получили путь к конечной точке API. - Далее, в переменную
responseмы сохраняем результат выполнения GET-запроса. При выполнении запроса также были переданы заголовки, сохраненные в переменнойheaders. - При помощи конструкции
if response.status_code == 200:проверяем код ответа, и если он равен 200 (код состояния, который мы должны получить при успешном обращении), выводим строку«Платежная информация»:. - Строка
json.loads(response.content.decode('utf-8'))['finances']декодирует JSON-ответ от сервера (response.content) из байтового формата в текстовый формат с кодировкой UTF-8, а затем извлекает словарь с ключом'finances'из этого JSON-ответа. - Далее, с помощью цикла
for key, value in ...перебираются элементы этого словаря и выводятся на экран ключи и соответствующие им значения. - В случае, если код состояния ответа не равен 200, выполняется блок
else, и на экран выводится сообщение об ошибке, содержащее код состояния ответа.
Вызовем нашу функцию, добавив в конце main.py
Итоговый листинг main.py:
import requests
import json
token = 'токен_полученный_ранее'
api_url_base = 'https://simple-server.tech/'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
}
def get_finances_info():
api_url = f'{api_url_base}account/finances'
response = requests.get(api_url, headers=headers)
if response.status_code == 200:
print('Платежная информация:')
for key, value in json.loads(response.content.decode('utf-8'))['finances'].items():
print(key, value)
else:
print (f'Ошибка {response.status_code}')
get_finances_info()В результате выполнения скрипта в терминале получим вывод:
Платежная информация:
balance 149.49
currency RUB
discount_end_date_at None
discount_percent 0
hourly_cost 0
hourly_fee 0
monthly_cost 0
monthly_fee 0
total_paid 767
hours_left None
autopay_card_info NoneДобавление SSH-ключа в панель управления аккаунтом
В следующем примере опишем добавление SSH-ключа в панель управления при помощи веб-API. Вновь обращаемся к документации.
Видим, что добавление выполняется при помощи POST-запроса к конечной точке https://simple-server.tech/ В теле запроса необходимо передать сам ключ, имя и параметр is_default`. При успешном добавлении возвращается код состояния 201.
Приступим к написанию функции:
def add_ssh_key():
api_url = f'{api_url_base}ssh-keys'
ssh_key_path = '/home/user/.ssh/id_rsa.pub'
try:
with open(ssh_key_path, 'r') as file:
ssh_key = file.read()
data = {
'body': ssh_key,
'is_default': False,
'name': 'My SSH key'
}
json_data = json.dumps(data)
response = requests.post(api_url, headers=headers, data=json_data)
if response.status_code == 201:
print('Ключ успешно добавлен! \nДанные ключа:')
for key, value in json.loads(response.content.decode('utf-8'))['ssh_key'].items():
print(key, value)
else:
print(f'Возникла ошибка {response.status_code}')
except FileNotFoundError:
print(f'Файл {ssh_key_path} не найден.')
except Exception as e:
print(f'Произошла ошибка: {str(e)}')
add_ssh_key()- В переменной
ssh_key_pathуказываем путь к SSH-ключу (если у вас нет ключа, сгенерировать его можно командойssh-keygen -t rsa). - В блоке
tryвыполняются следующие действия:
* Открывается файл SSH-ключа в режиме чтения;
* Считывается содержимое файла в переменную `ssh_key`;
* Создается словарь data, который содержит сам ключ, флаг `is_default` и имя ключа;
* Данные преобразуются в JSON-формат с помощью `json.dumps()`;
* Выполняется HTTP POST-запрос к API с указанием заголовков и JSON-данных;
* Если ответ имеет статус код 201 (Created), то выводится сообщение об успешном добавлении и данные о ключе;
* В противном случае выводится сообщение об ошибке с указанием статус кода;-
В блоке
exceptобрабатываются исключения, такие какFileNotFoundError(если файл с ключом не найден) и общие исключенияException, выводя соответствующие сообщения об ошибках. -
Вызываем функцию при помощи
add_ssh_key(). -
Открывается файл SSH-ключа в режиме чтения;
-
Считывается содержимое файла в переменную
ssh_key; -
Создается словарь data, который содержит сам ключ, флаг
is_defaultи имя ключа; -
Данные преобразуются в JSON-формат с помощью
json.dumps(); -
Выполняется HTTP POST-запрос к API с указанием заголовков и JSON-данных;
-
Если ответ имеет статус код 201 (Created), то выводится сообщение об успешном добавлении и данные о ключе;
-
В противном случае выводится сообщение об ошибке с указанием статус кода;
Полный листинг main.py (код из этого раздела не связан с функцией, созданной в предыщем разделе, поэтому в листинге не указан. Вызов get_finances_info() из прошлой главы можно закомментировать, добавив # перед вызовом):
Запускаем скрипт командой python3 main.py. В терминале видим, что ключ успешно добавлен, также получаем информацию о добавленном ключе:
Ключ успешно добавлен!
Данные ключа:
id 111235
body ssh-rsa "тут указан ключ"
created_at 2023-09-21T00:45:00.000Z
expired_at None
is_default False
name My SSH key
used_by []В панели управления переходим в раздел «SSH-ключи» и видим, что ключ действительно добавлен:
Изменение имени SSH-ключа
Рассмотрим еще один метод API, который использует PATCH для изменения имени SSH-ключа. В этом примере нам понадобится id добавленного ранее ключа, который мы получили в результате выполнения прошлой функции.
def change_ssh_key_name(key_id):
api_url = f'{api_url_base}ssh-keys/{key_id}'
data = {
'name': 'Changed Name'
}
json_data = json.dumps(data)
response = requests.patch(api_url, headers=headers, data=json_data)
if response.status_code == 200:
print('Имя успешно изменено! \nДанные ключа:')
for key, value in json.loads(response.content.decode('utf-8'))['ssh_key'].items():
print(key, value)
else:
print(f'Возникла ошибка {response.status_code}')
change_ssh_key_name(111235)В этом примере мы создаем функцию change_ssh_key_name, принимающую параметр key_id, значение которого используется при формировании api_url. Метод PATCH подразумевает частичное обновление информации, поэтому в словаре data мы не указываем все параметры, что использовались при добавлении ключа, а только те, что хотим изменить.
При запуске скрипта мы получим подобный вывод:
Имя успешно изменено!
Данные ключа:
id 111235
body ssh-rsa "тут указан ключ"
created_at 2023-09-21T02:08:39.000Z
expired_at None
is_default False
name Changed Name
used_by []Откроем раздел «SSH-ключи» и убедимся, что имя действительно изменено:
В этом руководстве на примере взаимодействия с веб-API Simple-Server мы рассмотрели, как при помощи Python можно работать с API. Используя примеры из статьи, вам не составит труда переписать функции для выполнения запросов к другим конечным точкам, описанных в документации. Также мы описали общий алгоритм, благодаря которому работа с API Simple-Server или других сервисов не вызовет у вас проблем.
- Исследование документации:
* Первым шагом является поиск документации по API нужного сервиса. Это может быть официальная документация на веб-сайте провайдера или другие ресурсы, предоставляющие информацию о взаимодействии с API.
* Ознакомьтесь с основами взаимодействия, включая формат запросов и ответов, доступные методы и ожидаемые данные.- Аутентификация:
* Если для работы с API требуется аутентификация, получите необходимые учетные данные или токен.- Создание запросов:
* Используя данные из документации, создайте HTTP-запросы.
* Укажите необходимые параметры запроса: метод (GET, POST, PUT, DELETE, PATCH), заголовки, тело запроса (если необходимо)- Обработка ошибок:
* Предусмотрите обработку ошибок. Это может включать в себя проверку статус-кодов ответов (например, 200 - успешно, 4xx - клиентская ошибка, 5xx - серверная ошибка) и обработку исключений.-
Первым шагом является поиск документации по API нужного сервиса. Это может быть официальная документация на веб-сайте провайдера или другие ресурсы, предоставляющие информацию о взаимодействии с API.
-
Ознакомьтесь с основами взаимодействия, включая формат запросов и ответов, доступные методы и ожидаемые данные.
-
Если для работы с API требуется аутентификация, получите необходимые учетные данные или токен.
-
Используя данные из документации, создайте HTTP-запросы.
-
Укажите необходимые параметры запроса: метод (GET, POST, PUT, DELETE, PATCH), заголовки, тело запроса (если необходимо)
-
Предусмотрите обработку ошибок. Это может включать в себя проверку статус-кодов ответов (например, 200 - успешно, 4xx - клиентская ошибка, 5xx - серверная ошибка) и обработку исключений.
Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.