Introduction ============ YaDisk is a Yandex.Disk REST API client library. Installation ************ :code:`yadisk` supports multiple HTTP client libraries and has both synchronous and asynchronous API. The following HTTP client libraries are currently supported: * :code:`requests` (used by default for synchronous API) * :code:`httpx` (both synchronous and asynchronous, used by default for asynchronous API) * :code:`aiohttp` (asynchronous only) * :code:`pycurl` (synchronous only) For synchronous API (installs :code:`requests`): .. code:: bash pip install yadisk[sync-defaults] For asynchronous API (installs :code:`aiofiles` and :code:`httpx`): .. code:: bash pip install yadisk[async-defaults] Alternatively, you can manually choose which optional libraries to install: .. code:: bash # For use with pycurl pip install yadisk[pycurl] # For use with aiohttp, will also install aiofiles pip install yadisk[async-files,aiohttp] Links to Official Yandex.Disk REST API Docs ******************************************* | `Official Yandex.Disk REST API Docs `__ | `Polygon `__ Examples ******** Synchronous API --------------- .. code:: python import yadisk client = yadisk.Client(token="") # or # client = yadisk.Client("", "", "") # You can either use the with statement or manually call client.close() later with client: # Check if the token is valid print(client.check_token()) # Get disk information print(client.get_disk_info()) # Print files and directories at "/some/path" print(list(client.listdir("/some/path"))) # Upload "file_to_upload.txt" to "/destination.txt" client.upload("file_to_upload.txt", "/destination.txt") # Same thing with open("file_to_upload.txt", "rb") as f: client.upload(f, "/destination.txt") # Download "/some-file-to-download.txt" to "downloaded.txt" client.download("/some-file-to-download.txt", "downloaded.txt") # Permanently remove "/file-to-remove" client.remove("/file-to-remove", permanently=True) # Create a new directory at "/test-dir" print(client.mkdir("/test-dir")) Receiving token with confirmation code ###################################### .. code:: python import sys import yadisk def main(): with yadisk.Client("application-id>", "") as client: url = client.get_code_url() print(f"Go to the following url: {url}") code = input("Enter the confirmation code: ") try: response = client.get_token(code) except yadisk.exceptions.BadRequestError: print("Bad code") return client.token = response.access_token if client.check_token(): print("Sucessfully received token!") else: print("Something went wrong. Not sure how though...") main() Recursive upload ################ .. code:: python import posixpath import os import yadisk def recursive_upload(client: yadisk.Client, from_dir: str, to_dir: str): for root, dirs, files in os.walk(from_dir): p = root.split(from_dir)[1].strip(os.path.sep) dir_path = posixpath.join(to_dir, p) try: client.mkdir(dir_path) except yadisk.exceptions.PathExistsError: pass for file in files: file_path = posixpath.join(dir_path, file) p_sys = p.replace("/", os.path.sep) in_path = os.path.join(from_dir, p_sys, file) try: client.upload(in_path, file_path) except yadisk.exceptions.PathExistsError: pass client = yadisk.Client(token="") to_dir = "/test" from_dir = "/home/ubuntu" recursive_upload(client, from_dir, to_dir) Setting custom properties of files ################################## .. code:: python import yadisk def main(): with yadisk.Client(token="") as client: path = input("Enter a path to patch: ") properties = {"speed_of_light": 299792458, "speed_of_light_units": "meters per second", "message_for_owner": "MWAHAHA! Your file has been patched by an evil script!"} meta = client.patch(path, properties) print("\nNew properties: ") for k, v in meta.custom_properties.items(): print(f"{k}: {repr(v)}") answer = input("\nWant to get rid of them? (y/[n]) ") if answer.lower() in ("y", "yes"): properties = {k: None for k in properties} client.patch(path, properties) print("Everything's back as usual") main() Emptying the trash bin ###################### .. code:: python import sys import yadisk def main(): answer = input("Are you sure about this? (y/[n]) ") if answer.lower() not in ("y", "yes"): print("Not going to do anything") return with yadisk.Client(token="") as client: print("Emptying the trash bin...") print("It might take a while...") client.remove_trash("/") print("Success!") main() Specifying HTTP client library ############################## .. code:: python import yadisk # Will use httpx for making requests with yadisk.Client(token="", session="httpx") as client: print(client.check_token()) Asynchronous API ---------------- .. code:: python import yadisk import aiofiles client = yadisk.AsyncClient(token="") # or # client = yadisk.AsyncClient("", "", "") # You can either use the with statement or manually call client.close() later async with client: # Check if the token is valid print(await client.check_token()) # Get disk information print(await client.get_disk_info()) # Print files and directories at "/some/path" print([i async for i in client.listdir("/some/path")]) # Upload "file_to_upload.txt" to "/destination.txt" await client.upload("file_to_upload.txt", "/destination.txt") # Same thing async with aiofiles.open("file_to_upload.txt", "rb") as f: await client.upload(f, "/destination.txt") # Same thing but with regular files with open("file_to_upload.txt", "rb") as f: await client.upload(f, "/destination.txt") # Download "/some-file-to-download.txt" to "downloaded.txt" await client.download("/some-file-to-download.txt", "downloaded.txt") # Same thing async with aiofiles.open("downloaded.txt", "wb") as f: await client.download("/some-file-to-download.txt", f) # Permanently remove "/file-to-remove" await client.remove("/file-to-remove", permanently=True) # Create a new directory at "/test-dir" print(await client.mkdir("/test-dir")) Receiving token with confirmation code ###################################### .. code:: python import asyncio import sys import yadisk async def main(): async with yadisk.AsyncClient("application-id>", "") as client: url = client.get_code_url() print(f"Go to the following url: {url}") code = input("Enter the confirmation code: ") try: response = await client.get_token(code) except yadisk.exceptions.BadRequestError: print("Bad code") return client.token = response.access_token if await client.check_token(): print("Sucessfully received token!") else: print("Something went wrong. Not sure how though...") asyncio.run(main()) Recursive upload ################ .. code:: python import asyncio import posixpath import os import yadisk async def recursive_upload(from_dir: str, to_dir: str, n_parallel_requests: int = 5): async with yadisk.AsyncClient(token="") as client: async def upload_files(queue): while queue: in_path, out_path = queue.pop(0) print(f"Uploading {in_path} -> {out_path}") try: await client.upload(in_path, out_path) except yadisk.exceptions.PathExistsError: print(f"{out_path} already exists") async def create_dirs(queue): while queue: path = queue.pop(0) print(f"Creating directory {path}") try: await client.mkdir(path) except yadisk.exceptions.PathExistsError: print(f"{path} already exists") mkdir_queue = [] upload_queue = [] print(f"Creating directory {to_dir}") try: await client.mkdir(to_dir) except yadisk.exceptions.PathExistsError: print(f"{to_dir} already exists") for root, dirs, files in os.walk(from_dir): rel_dir_path = root.split(from_dir)[1].strip(os.path.sep) rel_dir_path = rel_dir_path.replace(os.path.sep, "/") dir_path = posixpath.join(to_dir, rel_dir_path) for dirname in dirs: mkdir_queue.append(posixpath.join(dir_path, dirname)) for filename in files: out_path = posixpath.join(dir_path, filename) rel_dir_path_sys = rel_dir_path.replace("/", os.path.sep) in_path = os.path.join(from_dir, rel_dir_path_sys, filename) upload_queue.append((in_path, out_path)) tasks = [upload_files(upload_queue) for i in range(n_parallel_requests)] tasks.extend(create_dirs(mkdir_queue) for i in range(n_parallel_requests)) await asyncio.gather(*tasks) from_dir = input("Directory to upload: ") to_dir = input("Destination directory: ") asyncio.run(recursive_upload(from_dir, to_dir, 5)) Setting custom properties of files ################################## .. code:: python import asyncio import yadisk async def main(): async with yadisk.AsyncClient(token="") as client: path = input("Enter a path to patch: ") properties = {"speed_of_light": 299792458, "speed_of_light_units": "meters per second", "message_for_owner": "MWAHAHA! Your file has been patched by an evil script!"} meta = await client.patch(path, properties) print("\nNew properties: ") for k, v in meta.custom_properties.items(): print(f"{k}: {repr(v)}") answer = input("\nWant to get rid of them? (y/[n]) ") if answer.lower() in ("y", "yes"): properties = {k: None for k in properties} await client.patch(path, properties) print("Everything's back as usual") asyncio.run(main()) Emptying the trash bin ###################### .. code:: python import asyncio import sys import yadisk async def main(): answer = input("Are you sure about this? (y/[n]) ") if answer not in ("y", "yes"): print("Not going to do anything") return async with yadisk.AsyncClient(token="") as client: print("Emptying the trash bin...") print("It might take a while...") await client.remove_trash("/") print("Success!") asyncio.run(main()) Specifying HTTP client library ############################## .. code:: python import yadisk # Will use aiohttp for making requests async with yadisk.AsyncClient(token="", session="aiohttp") as client: print(await client.check_token())