diff --git a/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx index 9a1f712f859..7738ed521d9 100644 --- a/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/HomeMenu.tsx @@ -94,6 +94,12 @@ const home = [ href: '/reference/dart/introduction', level: 'reference_dart', }, + { + label: 'Python', + icon: '/img/icons/menu/reference-python', + href: '/reference/python/introduction', + level: 'reference_python', + }, { label: 'Tools Reference', }, diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index d29480462cd..cf295e8f333 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -788,6 +788,13 @@ export const reference_dart_v1 = { parent: '/reference', } +export const reference_python_v2 = { + icon: 'reference-python', + title: 'Python', + url: '/guides/reference/python', + parent: '/reference', +} + export const reference_cli = { icon: 'reference-cli', title: 'Supabase CLI', diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx index cfb4d87b143..65d0ec61e07 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx @@ -11,6 +11,9 @@ import spec_js_v1 from '~/../../spec/supabase_js_v1.yml' assert { type: 'yml' } import spec_dart_v1 from '~/../../spec/supabase_dart_v1.yml' assert { type: 'yml' } // @ts-expect-error import spec_dart_v0 from '~/../../spec/supabase_dart_v0.yml' assert { type: 'yml' } +// @ts-expect-error +import spec_python_v2 from '~/../../spec/supabase_py_v2.yml' assert { type: 'yml' } + // import { gen_v3 } from '~/lib/refGenerator/helpers' import apiCommonSections from '~/../../spec/common-api-sections.json' import cliCommonSections from '~/../../spec/common-cli-sections.json' @@ -47,6 +50,7 @@ export type RefIdOptions = | 'reference_javascript_v2' | 'reference_dart_v0' | 'reference_dart_v1' + | 'reference_python_v2' | 'reference_cli' | 'reference_api' | 'reference_self_hosting_auth' @@ -56,6 +60,7 @@ export type RefIdOptions = export type RefKeyOptions = | 'javascript' | 'dart' + | 'python' | 'cli' | 'api' | 'self-hosting-auth' @@ -65,16 +70,6 @@ export type RefKeyOptions = const NavigationMenu = () => { const router = useRouter() - let version = '' - - if (router.asPath.includes('v1')) { - version = '_v1' - } - - if (router.asPath.includes('v0')) { - version = '_v0' - } - function handleRouteChange(url: string) { switch (url) { case `/docs`: @@ -126,6 +121,10 @@ const NavigationMenu = () => { case url.includes(`/docs/reference/dart`) && url: menuState.setMenuLevelId('reference_dart_v1') break + // puthon v2 (latest) + case url.includes(`/docs/reference/python`) && url: + menuState.setMenuLevelId('reference_python_v2') + break case url.includes(`/docs/reference/cli`) && url: menuState.setMenuLevelId('reference_cli') break @@ -175,6 +174,7 @@ const NavigationMenu = () => { const isReference_Javascript_V2 = 'reference_javascript_v2' === level const isReference_Dart_V0 = 'reference_dart_v0' === level const isReference_Dart_V1 = 'reference_dart_v1' === level + const isReference_Python_V2 = 'reference_python_v2' === level const isReference_Cli = 'reference_cli' === level const isReference_Api = 'reference_api' === level const isReference_Self_Hosting_Auth = 'reference_self_hosting_auth' === level @@ -229,6 +229,14 @@ const NavigationMenu = () => { lib="dart" spec={spec_dart_v1} /> + {/* // Tools */} = ({ active, spec, }) => { + const filteredSections = commonSections.filter((section) => { + return !section.excludes?.includes(id) + }) + return (
= ({ !active ? 'opacity-0 invisible absolute h-0 overflow-hidden' : '', ].join(' ')} > - +
) } diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx index 123a34e27ad..690615b4a13 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenuRefListItems.tsx @@ -179,7 +179,7 @@ const Content: React.FC = ({ id, lib, commonSections, sp if (!sections) console.error('no common sections imported') const menu = NavItems[id] - + console.log(menu) const databaseFunctions = find(sections, { title: 'Database' }) ? find(sections, { title: 'Database' }).items : [] diff --git a/apps/docs/docs/ref/python/introduction.mdx b/apps/docs/docs/ref/python/introduction.mdx new file mode 100644 index 00000000000..cf0a9f0ee4f --- /dev/null +++ b/apps/docs/docs/ref/python/introduction.mdx @@ -0,0 +1,21 @@ +--- +id: introduction +title: Introduction +hideTitle: true +--- + +
+ +
+

Python Client Library

+

@supabase-community/supabase-py

+
+
+ +
+ This reference documents every object and method available in the + [supabase-py](https://github.com/supabase-community/supabase-py) library from the Supabase + community. You can useĀ `supabase-py` to interact with your Postgres database, listen to database + changes, invoke Deno Edge Functions, build login and user management functionality, and manage + large files. +
diff --git a/apps/docs/docs/ref/python/release-notes.mdx b/apps/docs/docs/ref/python/release-notes.mdx new file mode 100644 index 00000000000..1deb6705f7e --- /dev/null +++ b/apps/docs/docs/ref/python/release-notes.mdx @@ -0,0 +1,10 @@ +--- +id: release-notes +title: Release Notes +--- + +The community is actively working on the library and we will be upgrading the Authentication library, `gotrue-py`, to mirror the Supabase-js v2 lib. + +## Storage Transformations + +We currently support [image transformations](https://supabase.com/docs/guides/storage/image-transformations) in our storage library. diff --git a/apps/docs/layouts/SiteLayout.tsx b/apps/docs/layouts/SiteLayout.tsx index eb017378efd..d0eec9c2fbf 100644 --- a/apps/docs/layouts/SiteLayout.tsx +++ b/apps/docs/layouts/SiteLayout.tsx @@ -71,6 +71,10 @@ const levelsData = { icon: '/docs/img/icons/menu/reference-dart', name: 'Dart Reference v0.0', }, + reference_python_v2: { + icon: '/docs/img/icons/menu/reference-python', + name: 'Python Reference v2.0', + }, reference_cli: { icon: '/docs/img/icons/menu/reference-cli', name: 'CLI Reference', diff --git a/apps/docs/pages/reference/python/[...slug].tsx b/apps/docs/pages/reference/python/[...slug].tsx new file mode 100644 index 00000000000..a93ce7bcf52 --- /dev/null +++ b/apps/docs/pages/reference/python/[...slug].tsx @@ -0,0 +1,30 @@ +import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json' +import typeSpec from '~/../../spec/enrichments/tsdoc_v2/combined.json' +// @ts-expect-error +import spec from '~/../../spec/supabase_py_v2.yml' assert { type: 'yml' } +import RefSectionHandler from '~/components/reference/RefSectionHandler' +import { flattenSections } from '~/lib/helpers' +import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths' +import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps' + +const sections = flattenSections(clientLibsCommonSections) + +export default function PyReference(props) { + return ( + + ) +} + +export async function getStaticProps() { + return handleRefStaticProps(sections, '/python') +} + +export function getStaticPaths() { + return handleRefGetStaticPaths() +} diff --git a/apps/docs/pages/reference/python/crawlers/[...slug].tsx b/apps/docs/pages/reference/python/crawlers/[...slug].tsx new file mode 100644 index 00000000000..593da6371f7 --- /dev/null +++ b/apps/docs/pages/reference/python/crawlers/[...slug].tsx @@ -0,0 +1,44 @@ +import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json' +import typeSpec from '~/../../spec/enrichments/tsdoc_v2/combined.json' +// @ts-expect-error +import spec from '~/../../spec/supabase_py_v2.yml' assert { type: 'yml' } +import RefSectionHandler from '~/components/reference/RefSectionHandler' +import { flattenSections } from '~/lib/helpers' +import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths' +import handleRefStaticProps from '~/lib/mdx/handleRefStaticProps' +import { useRouter } from 'next/router' +import RefSEO from '~/components/reference/RefSEO' + +const sections = flattenSections(clientLibsCommonSections) + +export default function PyReference(props) { + const router = useRouter() + const slug = router.query.slug[0] + const filteredSection = sections.filter((section) => section.id === slug) + + const pageTitle = filteredSection[0]?.title + ? `${filteredSection[0]?.title} | Supabase` + : 'Supabase' + + return ( + <> + + + + + ) +} + +export async function getStaticProps() { + return handleRefStaticProps(sections, '/python') +} + +export function getStaticPaths() { + return handleRefGetStaticPaths() +} diff --git a/apps/docs/public/img/icons/menu/reference-dart-light.svg b/apps/docs/public/img/icons/menu/reference-dart-light.svg index 245516d78f7..178f51a5b88 100644 --- a/apps/docs/public/img/icons/menu/reference-dart-light.svg +++ b/apps/docs/public/img/icons/menu/reference-dart-light.svg @@ -1,9 +1,9 @@ - - + + - - - + + + diff --git a/apps/docs/public/img/icons/menu/reference-dart.svg b/apps/docs/public/img/icons/menu/reference-dart.svg index b3fea918042..33f9ad24a27 100644 --- a/apps/docs/public/img/icons/menu/reference-dart.svg +++ b/apps/docs/public/img/icons/menu/reference-dart.svg @@ -1,9 +1,9 @@ - - + + - - - + + + diff --git a/apps/docs/public/img/icons/menu/reference-javascript-light.svg b/apps/docs/public/img/icons/menu/reference-javascript-light.svg index 1417f5a8038..a11845dff91 100644 --- a/apps/docs/public/img/icons/menu/reference-javascript-light.svg +++ b/apps/docs/public/img/icons/menu/reference-javascript-light.svg @@ -1,9 +1,9 @@ - - + + - - - + + + diff --git a/apps/docs/public/img/icons/menu/reference-javascript.svg b/apps/docs/public/img/icons/menu/reference-javascript.svg index dff8905edb5..f8ce1de0403 100644 --- a/apps/docs/public/img/icons/menu/reference-javascript.svg +++ b/apps/docs/public/img/icons/menu/reference-javascript.svg @@ -1,9 +1,9 @@ - - + + - - - + + + diff --git a/apps/docs/public/img/icons/menu/reference-python-light.svg b/apps/docs/public/img/icons/menu/reference-python-light.svg new file mode 100644 index 00000000000..1ac57aae572 --- /dev/null +++ b/apps/docs/public/img/icons/menu/reference-python-light.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/docs/public/img/icons/menu/reference-python.svg b/apps/docs/public/img/icons/menu/reference-python.svg new file mode 100644 index 00000000000..4ca064b0b73 --- /dev/null +++ b/apps/docs/public/img/icons/menu/reference-python.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/spec/common-client-libs-sections.json b/spec/common-client-libs-sections.json index 8f4dc1f62d0..732d85b169b 100644 --- a/spec/common-client-libs-sections.json +++ b/spec/common-client-libs-sections.json @@ -9,7 +9,8 @@ "title": "Installing", "id": "installing", "slug": "installing", - "type": "markdown" + "type": "markdown", + "excludes": ["reference_javascript_v1", "reference_dart_v0", "reference_python_v2"] }, { "title": "Initializing", @@ -21,13 +22,20 @@ "title": "Typescript Support", "id": "typescript-support", "slug": "typescript-support", - "type": "markdown" + "type": "markdown", + "excludes": [ + "reference_javascript_v1", + "reference_dart_v0", + "reference_dart_v1", + "reference_python_v2" + ] }, { "title": "Upgrade guide", "id": "upgrade-guide", "slug": "upgrade-guide", - "type": "markdown" + "type": "markdown", + "excludes": ["reference_javascript_v2", "reference_dart_v1", "reference_python_v2"] }, { "title": "Database", diff --git a/spec/supabase_py_v2.yml b/spec/supabase_py_v2.yml new file mode 100644 index 00000000000..8a1fe642367 --- /dev/null +++ b/spec/supabase_py_v2.yml @@ -0,0 +1,401 @@ +openref: 0.1 + +info: + id: reference/supabase-py + title: Supabase Client + description: | + + Supabase Python(Community). + + definition: ../../spec/enrichments/tsdoc_v2/combined.json + specUrl: https://github.com/supabase/supabase/edit/master/spec/supabase_py_v2.yml + slugPrefix: '/' + libraries: + - name: 'Python' + id: 'py' + version: '0.0.1' + +functions: + - id: initializing + $ref: '@supabase/supabase-js.index.SupabaseClient.constructor' + description: | + You can initialize a new Supabase client using the `create_client()` method. + + The Supabase client is your entrypoint to the rest of the Supabase functionality + and is the easiest way to interact with everything we offer within the Supabase ecosystem. + + examples: + - id: create-client + name: create_client() + code: | + ``` + import os + from supabase import create_client, Client + + url: str = os.environ.get("SUPABASE_URL") + key: str = os.environ.get("SUPABASE_KEY") + supabase: Client = create_client(url, key) + ``` + - id: with-timeout-option + name: With timeout option + code: | + ``` + import os + from supabase import create_client, Client + + url: str = os.environ.get("SUPABASE_URL") + key: str = os.environ.get("SUPABASE_KEY") + supabase: Client = create_client(url, key, options={'timeout': 10}) + ``` + + - id: sign-up + title: 'sign_up()' + $ref: '@supabase/gotrue-js.GoTrueClient.signUp' + notes: | + - By default, the user needs to verify their email address before logging in. To turn this off, disable **Confirm email** in [your project](https://app.supabase.com/project/_/auth/providers). + - **Confirm email** determines if users need to confirm their email address after signing up. + - If **Confirm email** is enabled, a `user` is returned but `session` is null. + - If **Confirm email** is disabled, both a `user` and a `session` are returned. + - By default, when the user confirms their email address, they are redirected to the [`SITE_URL`](https://supabase.com/docs/reference/auth/config#site_url). You can modify your `SITE_URL` or add additional redirect URLs in [your project](https://app.supabase.com/project/_/auth/url-configuration). + - If signUp() is called for an existing confirmed user: + - If **Confirm email** is enabled in [your project](https://app.supabase.com/project/_/auth/providers), an obfuscated/fake user object is returned. + - If **Confirm email** is disabled, the error message, `User already registered` is returned. + - To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/javascript/auth-getuser). + examples: + - id: signup + name: Sign up + code: | + ``` + res = supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', + }) + ``` + - id: sign-up-with-additional-user-metadata + name: Sign up with additional user metadata + code: | + ``` + res = supabase.auth.signUp({ + email: 'example@email.com', + password: 'example-password', + options: { + data: { + first_name: 'John', + age: 27, + } + } + }) + ``` + - id: sign-out + title: 'sign_out()' + $ref: '@supabase/gotrue-js.GoTrueClient.signOut' + notes: | + - In order to use the `signOut()` method, the user needs to be signed in first. + examples: + - id: sign-out + name: Sign out + code: | + ``` + res = supabase.auth.sign_out() + ``` + - id: verify-otp + title: 'verify_otp()' + $ref: '@supabase/gotrue-js.GoTrueClient.verifyOtp' + notes: | + - The `verifyOtp` method takes in different verification types. If a phone number is used, the type can either be `sms` or `phone_change`. If an email address is used, the type can be one of the following: `signup`, `magiclink`, `recovery`, `invite` or `email_change`. + - The verification type used should be determined based on the corresponding auth method called before `verifyOtp` to sign up / sign-in a user. + examples: + - id: verify-sms-one-time-password + name: Verify SMS One-Time Password (OTP) + code: | + ``` + res = supabase.auth.verify_otp(phone, token) + ``` + + - id: get-session + title: 'get_session_from_url' + $ref: '@supabase/gotrue-js.GoTrueClient.getSession' + examples: + - id: get-session + name: Get the session data from URL + code: | + ``` + res = supabase.auth.get_session_from_url(url) + ``` + + - id: set-session + title: 'set_session()' + $ref: '@supabase/gotrue-js.GoTrueClient.setSession' + notes: | + - `setSession()` takes in a refresh token and uses it to get a new session. + - The refresh token can only be used once to obtain a new session. + - [Refresh token rotation](/docs/reference/auth/config#refresh_token_rotation_enabled) is enabled by default on all projects to guard against replay attacks. + - You can configure the [`REFRESH_TOKEN_REUSE_INTERVAL`](https://supabase.com/docs/reference/auth/config#refresh_token_reuse_interval) which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues. + - If you are using React Native, you will need to install a Buffer polyfill via a library such as [rn-nodeify](https://github.com/tradle/rn-nodeify) to properly use the library. + examples: + - id: set-session + name: Refresh the session + description: Sets the session data from refresh_token and returns current session or an error if the refresh_token is invalid. + code: | + ``` + res = supabase.auth.set_session(refresh_token) + ``` + - id: refresh-session + title: 'refresh_ession()' + $ref: '@supabase/gotrue-js.GoTrueClient.refreshSession' + notes: | + - This method will refresh the session whether the current one is expired or not. + - Both examples destructure `user` and `session` from `data`. This is not required; so `const { data, error } =` is also valid. + examples: + - id: refresh-session + name: Refresh session using the current session + code: | + ``` + res = supabase.auth.refresh_session() + ``` + - id: select + title: 'Fetch data: select()' + $ref: '@supabase/postgrest-js.PostgrestQueryBuilder.select' + notes: | + - By default, Supabase projects return a maximum of 1,000 rows. This setting can be changed in your project's [API settings](https://app.supabase.com/project/_/settings/api). It's recommended that you keep it low to limit the payload size of accidental or malicious requests. + - `apikey` is a reserved keyword if you're using the [Supabase Platform](/docs/guides/platform) and [should be avoided as a column name](https://github.com/supabase/supabase/issues/5465). + examples: + - id: getting-your-data + name: Getting your data + code: | + ``` + r = supabase + .from('countries') + .select("*") + ``` + - id: selecting-specific-columns + name: Selecting specific columns + code: | + ``` + r = await supabase + .from('countries') + .select('name') + ``` + + - id: invoke + title: 'invoke()' + description: | + Invoke a Supabase Function. + $ref: '@supabase/functions-js.F' + notes: | + - Requires an Authorization header. + - When you pass in a body to your function, we automatically attach the Content-Type header for `Blob`, `ArrayBuffer`, `File`, `FormData` and `String`. If it doesn't match any of these types we assume the payload is `json`, serialise it and attach the `Content-Type` header as `application/json`. You can override this behaviour by passing in a `Content-Type` header of your own. + examples: + - id: invoke-function + name: Basic invocation + description: + code: | + ``` + func = supabase.functions() + @asyncio.coroutine + async def test_func(loop): + resp = await func.invoke("hello-world",invoke_options={'body':{}}) + return resp + + loop = asyncio.get_event_loop() + resp = loop.run_until_complete(test_func(loop)) + loop.close() + ``` + + - id: list-buckets + title: 'list_buckets()' + $ref: '@supabase/storage-js.packages/StorageBucketApi.default.listBuckets' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: `select` + - `objects` table permissions: none + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: list-buckets + name: List buckets + code: | + ``` + res = supabase.storage().list_buckets() + ``` + + - id: get-bucket + title: 'get_bucket()' + $ref: '@supabase/storage-js.packages/StorageBucketApi.default.getBucket' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: `select` + - `objects` table permissions: none + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: get-bucket + name: Get bucket + code: | + ``` + res = supabase.storage().get_bucket(name) + ``` + + - id: create-bucket + title: 'create_bucket()' + $ref: '@supabase/storage-js.packages/StorageBucketApi.default.createBucket' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: `insert` + - `objects` table permissions: none + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: create-bucket + name: Create bucket + code: | + ``` + res = supabase.storage().create_bucket(name) + ``` + + - id: empty-bucket + title: 'empty_bucket()' + $ref: '@supabase/storage-js.packages/StorageBucketApi.default.emptyBucket' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: `select` + - `objects` table permissions: `select` and `delete` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: empty-bucket + name: Empty bucket + code: | + ``` + res = supabase.storage().empty_bucket(name) + ``` + - id: delete-bucket + title: 'delete_bucket()' + $ref: '@supabase/storage-js.packages/StorageBucketApi.default.deleteBucket' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: `select` and `delete` + - `objects` table permissions: none + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: delete-bucket + name: Delete bucket + code: | + ``` + res = supabase.storage().delete_bucket(name) + ``` + + - id: from-upload + title: 'from_.upload()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.upload' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: `insert` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: upload-file + name: Upload file using filepath + code: | + ``` + with open(source, 'rb+') as f: + res = supabase.storage().from_('bucket').upload(destination, os.path.abspath(source)) + ``` + - id: from-move + title: 'from_.move()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.move' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: `update` and `select` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: move-file + name: Move file + code: | + ``` + res = supabase.storage().from_(bucket).move('public/avatar1.png', 'private/avatar2.png') + ``` + + - id: from-create-signed-url + title: 'from_.create_signed_url()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: `select` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: create-signed-url + name: Create Signed URL + code: | + ``` + res = supabase.storage().from_(bucket_name).create_signed_url(filepath, expiry_duration) + ``` + + - id: from-get-public-url + title: 'from_.get_public_url()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl' + notes: | + - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/javascript/storage-updatebucket) or by going to Storage on [app.supabase.com](https://app.supabase.com), clicking the overflow menu on a bucket and choosing "Make public" + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: none + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: get-public-url + name: Returns the URL for an asset in a public bucket + code: | + ``` + res = supabase.storage().from_(bucket_name).get_public_url('test/avatar1.jpg') + ``` + + - id: from-download + title: 'from_.download()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.download' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: `select` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: download-file + name: Download file + code: | + ``` + with open(destination, 'wb+') as f: + res = supabase.storage().from_(bucket_name).download(source) + f.write(res) + ``` + + - id: from-remove + title: 'from_.remove()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.remove' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: `delete` and `select` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: delete-file + name: Delete file + code: | + ``` + res = supabase.storage().from_('test').remove('test.jpg') + ``` + - id: from-list + title: 'from_.list()' + $ref: '@supabase/storage-js.packages/StorageFileApi.default.list' + notes: | + - RLS policy permissions required: + - `buckets` table permissions: none + - `objects` table permissions: `select` + - Refer to the [Storage guide](/docs/guides/storage#access-control) on how access control works + examples: + - id: list-files + name: List files in a bucket + code: | + ``` + res = supabase.storage().from_('test').list() + ``` + - id: subscribe + title: on().subscribe() + $ref: '@supabase/realtime-js.RealtimeChannel.on' + notes: | + - We are implementing this feature at the moment. If you have queries feel free to open an issue on the [realtime-py](https://github.com/supabase-community) repository.