Skip to content

Instantly share code, notes, and snippets.

@MustafaJafar
Last active February 29, 2024 16:54
Show Gist options
  • Save MustafaJafar/c35745d064e467e5483912091e0ad912 to your computer and use it in GitHub Desktop.
Save MustafaJafar/c35745d064e467e5483912091e0ad912 to your computer and use it in GitHub Desktop.
AYON REST API Tutorial
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "f48535f2-f5ea-4491-bf2b-582ea0e5c9e9",
"metadata": {},
"source": [
"# AYON REST API\n",
"This Jupyter Notebook is the appendix to an AYON Community guide. <br>\n",
"Find the full guide here [AYON REST API Guide](https://community.ynput.io/t/ayon-rest-api-guide/1268)"
]
},
{
"cell_type": "markdown",
"id": "a24ee57e-3083-45b7-87df-1fedae5b1195",
"metadata": {},
"source": [
"## Requirments"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "906e234a-5253-4a89-811d-679b3ef0f07a",
"metadata": {},
"outputs": [],
"source": [
"pip install ayon-python-api"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f07a731a-002b-438e-870b-acf0686ab57b",
"metadata": {},
"outputs": [],
"source": [
"pip install httpx"
]
},
{
"cell_type": "markdown",
"id": "1239aa22-e8ea-4bc7-8e1a-33bf72b04281",
"metadata": {},
"source": [
"## Helper Functions\n",
"I'll be using these functions to process the response of AYON Server."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "fddd6150-6fc1-45c0-8307-9a4aa793444b",
"metadata": {},
"outputs": [],
"source": [
"## Some Helper Functions\n",
"def get_projects_names(con):\n",
" projects = con.get_projects()\n",
" names = map(lambda b: b[\"name\"], projects)\n",
" return list(names)\n",
"\n",
"def get_bundle_names(con):\n",
" bundles = con.get_bundles()[\"bundles\"]\n",
" names = map(lambda b: b[\"name\"], bundles)\n",
" return list(names)\n",
"\n",
"def get_available_versions_of_addon(con, addon_name): \n",
" addons = con.get_addons_info()[\"addons\"]\n",
" core_addons = next(filter(lambda b: b[\"name\"]==addon_name, addons), {})\n",
" core_addons_version = list(core_addons.get(\"versions\", {}).keys())\n",
" return core_addons_version"
]
},
{
"cell_type": "markdown",
"id": "00bc2409-279d-43b2-acd5-ddaf75c300e1",
"metadata": {},
"source": [
"## AYON PYTHON API\n",
"`ayon-python-api` is Ynput's official library for accessing AYON's API. <br>\n",
"It uses `AYON_SERVER_URL` and `AYON_API_KEY` environment variables to connect with AYON Server."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "6e3a32be-1e03-462c-8d9a-739199ec7e47",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Current Projects: ['demo_Big_Episodic', 'demo_Big_Feature', 'demo_Commercial', 'Robo', 'RoboAyon', 'RoboPype', 'Test']\n",
"Available Bundles: ['AYON-CORE-0.2.0-2024-02-08', 'Dev-2023-12-20-01']\n",
"Available versions of Core addon: ['0.2.0', '0.3.0-dev.1']\n"
]
},
{
"data": {
"text/plain": [
"<function ayon_api._api.close_connection()>"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import os\n",
"os.environ[\"AYON_SERVER_URL\"] = \"<your-ayon-server-url>\"\n",
"os.environ[\"AYON_API_KEY\"] = \"<your-ayon-api-key>\"\n",
"\n",
"import ayon_api\n",
"con = ayon_api.get_server_api_connection()\n",
"\n",
"projects = get_projects_names(con)\n",
"print(\"Current Projects:\", projects)\n",
"bundles = get_bundle_names(con)\n",
"print(\"Available Bundles:\", bundles)\n",
"core_versions = get_available_versions_of_addon(con, \"core\")\n",
"print(\"Available versions of Core addon:\", core_versions)\n",
"ayon_api.close_connection\n"
]
},
{
"cell_type": "markdown",
"id": "79aef743-8abf-435d-bfa7-396ae1df9b14",
"metadata": {},
"source": [
"## Simple AYON Python API\n",
"\n",
"A simple AYON python API implementation. <br>\n",
"It was made for the purpose of learning. <br>\n",
"Also, there could be situations (e.g. in CI/CD workflows) where you'd prefere to implement the two requests you'd need isntead of downlaoding the whole `ayon-python-api` library."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4fc56e7c-e15f-4c6e-b301-9df45e3c90f2",
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"Many thanks to Danell, \n",
"This code was directly inspired by his community guide.\n",
"https://community.ynput.io/t/developing-with-ayons-rest-api/1237\n",
"\n",
"This code can:\n",
"- login\n",
"- get_projects\n",
"- get_bundles\n",
"- get_addons_info\n",
"- delete_addon_version\n",
"- upload_addon_zip_url\n",
"- upload_addon_zip_file\n",
"\"\"\"\n",
"\n",
"import httpx\n",
"\n",
"\n",
"class SimpleAyonRestCommands:\n",
" def __init__(self, ayon_server_url, username, password):\n",
" self.ayon_server_url = ayon_server_url\n",
" self.credentials = {\n",
" \"name\": username,\n",
" \"password\":password\n",
" }\n",
" self.headers = {}\n",
" self.ayon_login()\n",
" \n",
" def ayon_login(self):\n",
" req = f\"{self.ayon_server_url}/api/auth/login\"\n",
" response = httpx.post(\n",
" req,\n",
" json=self.credentials,\n",
" )\n",
" self.token = response.json().get(\"token\")\n",
" self.headers[\"Authorization\"] = f\"Bearer {self.token}\"\n",
"\n",
" def get_projects(self):\n",
" req = f\"{self.ayon_server_url}/api/projects\"\n",
" response = httpx.get(\n",
" req,\n",
" headers=self.headers\n",
" )\n",
" return response.json().get(\"projects\")\n",
" \n",
" def get_bundles(self):\n",
" req = f\"{self.ayon_server_url}/api/bundles\"\n",
" response = httpx.get(\n",
" req,\n",
" params={\n",
" \"archived\": False \n",
" },\n",
" headers=self.headers\n",
" )\n",
" return response.json()\n",
" \n",
" def get_addons_info(self):\n",
" req = f\"{self.ayon_server_url}/api/addons\"\n",
" response = httpx.get(\n",
" req,\n",
" headers=self.headers\n",
" )\n",
" return response.json()\n",
"\n",
" def delete_addon_version(self, addon_name, addon_version): \n",
" req = f\"{self.ayon_server_url}/api/addons/{addon_name}/{addon_version}\"\n",
" response = httpx.delete(\n",
" req,\n",
" params={\n",
" \"purge\" : True\n",
" },\n",
" headers=self.headers\n",
" )\n",
" return response.json()\n",
" \n",
" def upload_addon_zip_url(self, addon_url, addon_name, addon_version):\n",
" req = f\"{self.ayon_server_url}/api/addons/install\"\n",
" response = httpx.post(\n",
" req,\n",
" params = {\n",
" \"url\" : addon_url,\n",
" \"addonName\": addon_name,\n",
" \"addonVersion\" :addon_version\n",
" },\n",
" headers=self.headers\n",
" )\n",
" return response.json()\n",
"\n",
" def upload_addon_zip_file(self, addon_filepath):\n",
" chunk_size = 1024 * 1024\n",
" req = f\"{self.ayon_server_url}/api/addons/install\"\n",
" \n",
" with open(addon_filepath, \"rb\") as stream:\n",
" response = httpx.post(\n",
" req, \n",
" data=self.upload_chunks_iter(stream, chunk_size),\n",
" headers=self.headers\n",
" )\n",
" response.raise_for_status() \n",
" return response.json()\n",
"\n",
" @staticmethod\n",
" def upload_chunks_iter(file_stream, chunk_size):\n",
" while True:\n",
" chunk = file_stream.read(chunk_size)\n",
" if not chunk:\n",
" break\n",
" yield chunk\n",
" "
]
},
{
"cell_type": "markdown",
"id": "f392c851-020a-4977-b81e-d93f919b86b7",
"metadata": {},
"source": [
"## Simple AYON Python API\n",
"It uses `username`, `password` and `ayon_Server_url` to connect with AYON Server."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "6eb2bc6e-bbe7-40b2-b3d5-e156fed928cf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Current Projects: ['demo_Big_Episodic', 'demo_Big_Feature', 'demo_Commercial', 'Robo', 'RoboAyon', 'RoboPype', 'Test']\n",
"Available Bundles: ['AYON-CORE-0.2.0-2024-02-08', 'Dev-2023-12-20-01']\n",
"Available versions of Core addon: ['0.2.0', '0.3.0-dev.1']\n"
]
}
],
"source": [
"username = \"<your-user-name>\"\n",
"password = \"<your-password>\"\n",
"ayon_server_url = \"<your-ayon-server-url>\"\n",
"\n",
"con = SimpleAyonRestCommands(ayon_server_url, \n",
" username,\n",
" password)\n",
"\n",
"projects = get_projects_names(con)\n",
"print(\"Current Projects:\", projects)\n",
"bundles = get_bundle_names(con)\n",
"print(\"Available Bundles:\", bundles)\n",
"core_versions = get_available_versions_of_addon(con, \"core\")\n",
"print(\"Available versions of Core addon:\", core_versions)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment