Работа с REST API Яндекс.Диска через Python Requests

Работа с REST API Яндекс.Диска через Python Requests

Автор: Рамис | Статьи 15 июля 2021

Из этой статьи вы узнаете как работать с REST API Яндекс.Диском через Python используя HTTP запросы (ранее мы делали с помощью готовой библиотеки yadisk). Создадим небольшую программу для быстрой загрузки файлов прямо с проводника Windows.

Яндекс не ободряет когда его сервис используют только как хранилище для резервных копий.

Создать приложение и получить токен

Зарегистрируем приложение на oauth.yandex.ru и назовем его к примеру Backup1, укажем платформу "Веб-сервисы" (воспользуемся URL для разработки), и разрешим API полный доступ к Диску.

Создать приложение Yandex API Создать приложение Yandex API Создать приложение Yandex API

В ответ мы должны получить информацию о новом приложение, сейчас нас интересует его ID

Создать приложение Yandex API

Что бы получить отладочный токен перейдем по ссылке ниже, заменив ID приложения на свой

https://oauth.yandex.ru/authorize?response_type=token&client_id=<ID приложения>

Токен готов.

REST API Яндекс.Диск

Теперь можно потренироваться на полигоне.

Вы можете оценить, как работает API Яндекс.Диска, отправляя запросы из удобного интерфейса.

API Яндекс.Диск

Для примера создадим папку, укажем ее имя и нажмем кнопку попробовать

API Яндекс.Диск

Заходим на Яндекс Диск, и видим что папка появилась.

API Яндекс.Диск

Так же попробуем удалить нашу ранее созданную папку, укажем ее имя и нажмем кнопку попробовать

API Яндекс.Диск

Таким способом вы можете проверить работу всех функций.

HTTP Python

Воспользуемся параметрами запроса из полигона, и с помощью библиотеки requests повторить все на Python.

Установим requests

pip install requests

Импортирует библиотеку, укажем заголовок запроса, url, и token

import requests

URL = 'https://cloud-api.yandex.net/v1/disk/resources'
TOKEN = 'AQAAAAAz55vbAAc-fohhPDQSvU5kroy21-HguNA'
headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': f'OAuth {TOKEN}'}

Напишем две функции для нашей будущей программы

Создать папку

def create_folder(path):
    """Создание папки. \n path: Путь к создаваемой папке."""
    requests.put(f'{URL}?path={path}', headers=headers)

Создаст папку hello world и API

create_folder('hello world')
create_folder('hello world/api')

Загрузить файл

def upload_file(loadfile, savefile, replace=False):
    """Загрузка файла.
    savefile: Путь к файлу на Диске
    loadfile: Путь к загружаемому файлу
    replace: true or false Замена файла на Диске"""
    res = requests.get(f'{URL}/upload?path={savefile}&overwrite={replace}', headers=headers).json()
    with open(loadfile, 'rb') as f:
        try:
            requests.put(res['href'], files={'file':f})
        except KeyError:
            print(res)

Загрузит файл images.rar в папку hello world

upload_file(r'C:\myFiles\images.rar', 'hello world/images.rar')

Программа для загрузки файлов

Сейчас можно приступить к разработке самой программы, назовем ее backup.py

import os
import requests
from datetime import datetime
from progress.bar import Bar

URL = 'https://cloud-api.yandex.net/v1/disk/resources'
TOKEN = 'AQAAAAAz55vbAAc-fohhPDQSvU5kroy21-HguNA'
headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': f'OAuth {TOKEN}'}

def create_folder(path):
    """Создание папки. \n path: Путь к создаваемой папке."""
    requests.put(f'{URL}?path={path}', headers=headers)

def upload_file(loadfile, savefile, replace=False):
    """Загрузка файла.
    savefile: Путь к файлу на Диске
    loadfile: Путь к загружаемому файлу
    replace: true or false Замена файла на Диске"""
    res = requests.get(f'{URL}/upload?path={savefile}&overwrite={replace}', headers=headers).json()
    with open(loadfile, 'rb') as f:
        try:
            requests.put(res['href'], files={'file':f})
        except KeyError:
            print(res)

def backup(savepath, loadpath):
    """Загрузка папки на Диск. \n savepath: Путь к папке на Диске для сохранения \n loadpath: Путь к загружаемой папке"""
    date_folder = '{0}_{1}'.format(loadpath.split('\\')[-1], datetime.now().strftime("%Y.%m.%d-%H.%M.%S"))
    create_folder(savepath)
    for address, _, files in os.walk(loadpath):
        create_folder('{0}/{1}/{2}'.format(savepath, date_folder, address.replace(loadpath, "")[1:].replace("\\", "/")))
        bar = Bar('Loading', fill='X', max=len(files))
        for file in files:
            bar.next()
            upload_file('{0}\{1}'.format(address, file),\
                        '{0}/{1}{2}/{3}'.format(savepath, date_folder, address.replace(loadpath, "").replace("\\", "/"), file))
    bar.finish()


if __name__ == '__main__':
    #backup('Backup', r'C:\Files\backup')
    backup('Backup', os.getcwd())

Программа готова, добавим новую системную переменную

системная переменная

Теперь мы может загружать наши файлы из проводника используя переменную %backup%

API Яндекс.Диск python

Комментарии

pro100bro
@pro100bro
01 января 2023

Вами было представлено не совсем корректное использование блока try/except. Если при GET запросе по каким-то причинам возникла ошибка, то уже до попадания в try/except, в переменной 'res' будет отсутствовать ключ 'href', то есть ссылка на загрузку. В этом случае мы можем использовать простой 'if', для проверки ответа от Яндекс диска: if 'href' not in response.keys(): print(f"Got an error: {res['error']}") else: with open(loadfile, 'rb') as f: requests.put(response['href'], files={'file': f})

Ответить
Рамис
@ramas
02 января 2023

@pro100bro, честно, я не помню почему я решил обернуть этот запрос в конструкцию try/except. Вы правы, правильнее было бы использовать условия if:

if res.get("href"):
    ...

Ответить
Markdown
Войти