+{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":"solid-file-python-getting-start.ipynb","provenance":[],"collapsed_sections":["G9cxkAlJ2JQg","ZT7ihHfG4MaF"]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","metadata":{"id":"G9cxkAlJ2JQg"},"source":["# About\n","`solid-file-python` is a Python library for creating and managing files and folders in Solid pods. "]},{"cell_type":"markdown","metadata":{"id":"0dFnOUF73iJ4"},"source":["# Start using"]},{"cell_type":"markdown","metadata":{"id":"ZT7ihHfG4MaF"},"source":["## Preparation\n","\n","### Get a Pod\n","You can get a free Pod either from [solidcommunity.net](https://solidcommunity.net/) or [Inrupt Pod Spaces](https://signup.pod.inrupt.com/).\n","\n","### Make sure your Pod is publicly accessible.\n","We assume the Pod we touch in the following examples is publicly accessible. To use `solid-file-python` with private resources, follow instructions in [access private resources](#Advanced-usage).\n","\n","To make your Pod public accessible, go to your Pod administration console:\n","\n","#### solidcommunity.net\n","1. Login admin console: https://[username].solidcommunity.net/\n","2. Click the **lock** icon on the menu bar.\n","3. Move and make sure **Everyone** (the globe icon) to/in the **Owners** section (as shown in the screenshot below.)\n","\n","\n","### Inrupt Pod Spaces \n","1. Login admin console: https://podbrowser.inrupt.com/login\n","2. Click the **FOLDER DETAILS** button on the menu bar.\n","3. On the sidebar, expand the **Sharing** section.\n","4. Click **EDIT EDITORS**.\n","5. Add and make sure **Anyone** is listed in **Editors** section. (as shown in the screenshot below.)\n",""]},{"cell_type":"markdown","metadata":{"id":"puw5ID0EA5mx"},"source":["## Install \n","You can obtain solid-file from Python Package Index using the following identifier: `solid-file`, and install it as a usual Python package."]},{"cell_type":"code","metadata":{"id":"apf2CcNFxyMX"},"source":["!pip install solid-file==0.1.1\n"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"swi8soBLBNyX"},"source":["## Usage example\n","We currently support basic folder and file CURD operations. Please check all available operations [here](https://github.com/twonote/solid-file-python/blob/master/src/solid/solid_api.py)."]},{"cell_type":"markdown","metadata":{"id":"g1HtBAEcC6-f"},"source":["### Import and init"]},{"cell_type":"code","metadata":{"id":"LEDYxYUYC8Gp"},"source":["from solid.solid_api import SolidAPI\n","api = SolidAPI()"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"qWe9gKFAPCRW"},"source":["Configure for demostration:"]},{"cell_type":"code","metadata":{"id":"lfStjLjrPJfO"},"source":["POD_ENDPOINT = 'https://pod.inrupt.com/petertc/' # Pod to demostrate. Replace it with yours.\n","\n","folder_name = 'testfolder' \n","subfolder_name = 'subfolder'\n","file_name = 'test.md'"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"0AvsH25TOu3t"},"source":["Init vars for demostration:"]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"b-V77_UZOswN","executionInfo":{"status":"ok","timestamp":1625717368074,"user_tz":-480,"elapsed":292,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"12c47796-ceeb-466d-c29d-00833786f8b3"},"source":["import uuid\n","import io\n","\n","body = '#hello Solid!'\n","f = io.BytesIO(body.encode('UTF-8'))\n","\n","def gen_random_str() -> str:\n"," return uuid.uuid4().hex\n","\n","base_url = POD_ENDPOINT + 'playground-' + gen_random_str() + '/'\n","folder_url = base_url + folder_name + '/'\n","subfolder_url = folder_url + subfolder_name + '/'\n","file_url = folder_url + file_name\n","\n","print(f'base_url:{base_url}')\n","print(f'folder_url:{folder_url}')\n","print(f'subfolder_url:{subfolder_url}')\n","print(f'file_url:{file_url}')"],"execution_count":null,"outputs":[{"output_type":"stream","text":["base_url:https://pod.inrupt.com/petertc/playground-36c59a28b0dc444fbd8ec03bd844bb03/\n","folder_url:https://pod.inrupt.com/petertc/playground-36c59a28b0dc444fbd8ec03bd844bb03/testfolder/\n","subfolder_url:https://pod.inrupt.com/petertc/playground-36c59a28b0dc444fbd8ec03bd844bb03/testfolder/subfolder/\n","file_url:https://pod.inrupt.com/petertc/playground-36c59a28b0dc444fbd8ec03bd844bb03/testfolder/test.md\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"BqBFVO2NDpeS"},"source":["### Check item exists"]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"bNJ3v4dTDsLF","executionInfo":{"status":"ok","timestamp":1625717372761,"user_tz":-480,"elapsed":713,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"718719a0-6591-4bf2-eb5a-549ca548db24"},"source":["api.item_exists(folder_url)"],"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["False"]},"metadata":{"tags":[]},"execution_count":47}]},{"cell_type":"markdown","metadata":{"id":"PNz06C9fKpGl"},"source":["### Create folder"]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"scmzQGJhKrRU","executionInfo":{"status":"ok","timestamp":1625717376734,"user_tz":-480,"elapsed":2813,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"2ae7e618-7a92-4360-8e75-cb7a2de423ac"},"source":["api.create_folder(folder_url)\n","api.item_exists(folder_url)"],"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["True"]},"metadata":{"tags":[]},"execution_count":48}]},{"cell_type":"markdown","metadata":{"id":"Pagkk7PZK9-E"},"source":["### List items in the folder\n","`SolidAPI.read_folder()` returns a `FolderData` instance in which you can get information about the folder, includes name, URL, parent folder, and items in the folder. "]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"CCNM_1IfLCvx","executionInfo":{"status":"ok","timestamp":1625717379325,"user_tz":-480,"elapsed":721,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"bb27a925-f9da-467d-d5a0-e23986622262"},"source":["empty_folder = api.read_folder(folder_url)\n","\n","print(f'Folder name: {empty_folder.name}')\n","print(f'Folder url: {empty_folder.url}')\n","print(f'Parent: {empty_folder.parent}')\n","print(f'Subfolders in the folder: {empty_folder.folders}')\n","print(f'Files in the folder: {empty_folder.files}')\n"],"execution_count":null,"outputs":[{"output_type":"stream","text":["Folder name: testfolder\n","Folder url: https://pod.inrupt.com/petertc/playground-36c59a28b0dc444fbd8ec03bd844bb03/testfolder/\n","Parent: https://pod.inrupt.com/petertc/playground-36c59a28b0dc444fbd8ec03bd844bb03/\n","Subfolders in the folder: []\n","Files in the folder: []\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"2epJ7iDEMJSz"},"source":["### Add a subfolder to the folder\n","We can see the subfolder while listing the folder after the subfolder is created. "]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"LPL0viCEMOzz","executionInfo":{"status":"ok","timestamp":1625717396240,"user_tz":-480,"elapsed":2167,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"d2f05404-7304-4a35-e0b2-28fefb341390"},"source":["api.create_folder(subfolder_url)\n","folder_data = api.read_folder(folder_url)\n","print(f'Subfolders in the folder: {list(map(lambda x: x.name, folder_data.folders))}')\n"],"execution_count":null,"outputs":[{"output_type":"stream","text":["Subfolders in the folder: ['subfolder']\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"6ieXDwalOcCw"},"source":["### Add a file to the folder\n","We can see the file while listing the folder after the file is uploaded. "]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"480U7B_xOend","executionInfo":{"status":"ok","timestamp":1625717398816,"user_tz":-480,"elapsed":1106,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"f21ec4e7-b2e2-430b-d0c2-4ecb140adae4"},"source":["api.put_file(file_url, f, 'text/markdown')\n","folder_data = api.read_folder(folder_url)\n","print(f'Files in the folder: {list(map(lambda x: x.name, folder_data.files))}')"],"execution_count":null,"outputs":[{"output_type":"stream","text":["Files in the folder: ['test.md']\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"s6k3ErYDP8un"},"source":["### Get the file from Pod\n","Download the file we just upload and print its content."]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"uzJgmVQ_QAwL","executionInfo":{"status":"ok","timestamp":1625717401217,"user_tz":-480,"elapsed":829,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"e536e554-b0ed-4ff1-a8e9-a4fd0d1c905c"},"source":["resp = api.get(file_url)\n","print(resp.text)"],"execution_count":null,"outputs":[{"output_type":"stream","text":["#hello Solid!\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"7uiGZ9n5QJlF"},"source":["### Delete files and folders in the Pod\n","Items will not exist after deletion."]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"rfTzOdtfQMye","executionInfo":{"status":"ok","timestamp":1625717406132,"user_tz":-480,"elapsed":2513,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"e937a25e-3444-40a6-bcb5-87e3951536ac"},"source":["from httpx import HTTPStatusError\n","\n","try:\n"," api.delete(file_url)\n","except HTTPStatusError as e:\n"," if e.response.status_code != 404:\n"," raise e\n","\n","try:\n"," api.delete(subfolder_url)\n","except HTTPStatusError as e:\n"," if e.response.status_code != 404:\n"," raise e\n","\n","try:\n"," api.delete(folder_url)\n","except HTTPStatusError as e:\n"," if e.response.status_code != 404:\n"," raise e\n","\n","print(api.item_exists(file_url))\n","print(api.item_exists(file_url))\n","print(api.item_exists(file_url))"],"execution_count":null,"outputs":[{"output_type":"stream","text":["False\n","False\n","False\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"075Q40KK3RTd"},"source":["# Advanced usage\n","\n","## Access private resources\n","\n","Besides accessing public resources as shown in the above sections, you can use `solid-file-python` to access private resources in a Pod as well.\n","\n","Currently, `solid-file-python` has the capability to access private resources in Pods hosted by [solidcommunity.net](https://solidcommunity.net/) or provisioned by [Node Solid Server](https://github.com/solid/). We are planning to support ESS (Inrupt Pod Spaces) and CSS when related [issues](https://github.com/solid/node-solid-server/issues/1533) are solved.\n","\n","To access a private resource, firstly, prepare your identity provider, username and password:\n"]},{"cell_type":"code","metadata":{"id":"0o32jDpS9kpJ","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1628822816664,"user_tz":-480,"elapsed":20306,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"e4b21936-b18f-4b8a-c841-d8dcda37a116"},"source":["from getpass import getpass\n","\n","USERNAME = getpass('Plz enter your user name:')\n","PASSWORD = getpass('Plz enter your password:')\n","PRIVATE_RES = getpass('Plz enter your private resource for testing, e.g., https://petertc.solidcommunity.net/private/test.md:')\n","IDP = 'https://solidcommunity.net'\n","\n","### Read configs from a config file by following code snippet alternatively.\n","\n","# from google.colab import drive\n","# drive.mount('/content/drive')\n","\n","# import json\n","# configs = json.load(open('/content/drive/MyDrive/solid-file-python-config.json')) \n","# POD_ENDPOINT = configs['SOLID_ENDPOINT']\n","# IDP = configs['SOLID_IDP']\n","# USERNAME = configs['SOLID_USERNAME']\n","# PASSWORD = configs['SOLID_PASSWORD']\n","# PRIVATE_RES = configs['PRIVATE_RES']\n","\n","\n"],"execution_count":null,"outputs":[{"output_type":"stream","text":["Plz enter your user name:··········\n","Plz enter your password:··········\n","Plz enter your private resource for testing, e.g., https://petertc.solidcommunity.net/private/test.md:··········\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"tFoRVk-pajxr"},"source":[" Provide these information while initializing `SolidAPI`, as shown in the following example:"]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"N3nW_Y4yZDGE","executionInfo":{"status":"ok","timestamp":1628822821368,"user_tz":-480,"elapsed":965,"user":{"displayName":"Petertc Chu","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhlP3xPPjcL77baD7QMX2-CmrwChoLoAj9zIoCqaPM=s64","userId":"13069251498339694703"}},"outputId":"01c0fd25-a7b3-406d-b77b-d212c9d9f943"},"source":["from solid.auth import Auth\n","from solid.solid_api import SolidAPI\n","\n","auth = Auth()\n","api = SolidAPI(auth)\n","auth.login(IDP, USERNAME, PASSWORD)\n","resp = api.get(PRIVATE_RES)\n","print(resp.text)"],"execution_count":null,"outputs":[{"output_type":"stream","text":["# This is your markdown file\n","\n","Here be stuff!\n"],"name":"stdout"}]}]}
0 commit comments