Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Invoking Edge Functions Returning a server-sent events in client library. #67

Closed
david-fischer opened this issue Jun 9, 2023 · 19 comments
Labels
enhancement New feature or request

Comments

@david-fischer
Copy link

david-fischer commented Jun 9, 2023

Is your feature request related to a problem? Please describe.
Yes. Currently, there seems to be no possibility to invoke an Edge Function that returns a server-sent events using the client library.

Describe the solution you'd like
I would like to see the implementation of an additional function, which could return a Stream of server-sent events instead of standard promise.

Describe alternatives you've considered
One alternative I considered was to simply await the full result. However, this would leave the user waiting for a long period, which is not an ideal user experience.

Additional context
The motivation is a project, where we are looking to implement a ChatGPT interface within our Flutter application, and we need to stream the response of the API call to OpenAI to the user in real-time.

Implementing this functionality on the backend as an Edge Function was straightforward enough - I followed the tutorial on Streaming Data in Edge Functions by Supabase (https://www.youtube.com/watch?v=9N66JBRLNYU).

@david-fischer david-fischer added the enhancement New feature or request label Jun 9, 2023
@dshukertjr
Copy link
Member

@david-fischer
We actually will not support this on our client library, but there are third party packages such as flutter_client_sse that you can use to get data as stream.

Here is an javascript implementation sample that might help!
https://github.com/orgs/supabase/discussions/13124#discussioncomment-5596708

@dshukertjr dshukertjr closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2023
@david-fischer
Copy link
Author

Hello @dshukertjr,
thanks for the quick reply and the guidance regarding the implementation!

Definetly, implementing calling the edge-function and get the data as stream would be another possibility, that I did not explicitly state in my issue. Generally, this is something I would be very happy to avoid, as I basically have to duplicate logic from the SupabaseClient, introducing a further coupling to specifics in the API, authentication, etc... into our codebase.

Is there any place, where Supabase users can upvote feature-requests to maybe influence your roadmap? I feel like specifically with chatGPT, this seems like a very common use-case that greatly improves the end-user experience!

Thanks and kind regards,
David

@dshukertjr
Copy link
Member

@david-fischer We don't really have a single source of truth for the community to upvote on feature requests, but I can pass the feedback to the functions team internally.

@dshukertjr dshukertjr changed the title Support for Invoking Edge Functions Returning a Stream in supabase-flutter Support for Invoking Edge Functions Returning a Stream in client library. Jun 21, 2023
@dshukertjr
Copy link
Member

dshukertjr commented Jun 21, 2023

Let me transfer this issue to js repo so that more people can see this and comment on it.

@dshukertjr dshukertjr reopened this Jun 21, 2023
@dshukertjr dshukertjr changed the title Support for Invoking Edge Functions Returning a Stream in client library. Support for Invoking Edge Functions Returning a server-sent events in client library. Jun 21, 2023
@dshukertjr dshukertjr transferred this issue from supabase/supabase-flutter Jun 21, 2023
@dshukertjr dshukertjr transferred this issue from supabase/functions-js Jun 21, 2023
@kangmingtay kangmingtay transferred this issue from supabase/supabase-js Aug 24, 2023
@soulofmischief
Copy link
Contributor

soulofmischief commented Dec 14, 2023

I made a PR for this months ago here, it's two lines and enables SSE in the library: #74

@dshukertjr why wouldn't functions-js support this? Please consider reviewing and merging my PR, all it does is directly return the response on detecting a response type of text/event-stream. It's worked just fine for me.

@dshukertjr
Copy link
Member

@laktek Would you be able to take a look at this issue and this PR?
#74

@soulofmischief
Copy link
Contributor

Thanks so much!

@david-fischer in the meantime you should be able to get the same result outside of the client with minimal coupling by using the following pattern:

const response = await fetch( FUNCTION_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': supabase.auth.headers.Authorization
    },
    body: JSON.stringify(body)
  })

@soulofmischief
Copy link
Contributor

soulofmischief commented Jan 7, 2024

The recommended way of getting the user/client in edge functions

const supabase = createClient(
    Deno.env.get( 'SUPABASE_URL' ) ?? '',
    Deno.env.get( 'SUPABASE_ANON_KEY' ) ?? '',
    {
      auth: { persistSession: false },
      global: { headers: { Authorization: authorization }}
    }
  )
  
const { data: { user }} = supabase.auth.getUser()

fails when using fetch in the way outlined in my above comment. It succeeds when using supabase.functions.invoke().

As a result, I'm currently having to fork and patch functions-js locally for this functionality, any news on whether this will be supported upstream?

@nietsmmar
Copy link

Any news about this? We would really appreciate to be able to get streams from our edge functions in flutter.

@nietsmmar
Copy link

Here is an javascript implementation sample that might help! https://github.com/orgs/supabase/discussions/13124#discussioncomment-5596708

@dshukertjr this library doesn't work on web. I am really a bit confused on why this feature is not on the roadmap. It is such an obvious thing as Edge functions are built to stream data. And now with LLM's being everywhere many dev's want to be able to read from these streams. Is there any update on this issue?

Thanks for all your good work!

@nietsmmar
Copy link

@soulofmischief I used code similar to yours now

const response = await fetch( FUNCTION_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': supabase.auth.headers.Authorization
    },
    body: JSON.stringify(body)
  })

Before I initialized it like this:

await Supabase.initialize(
  url: config.api.url,
  anonKey: config.api.anonKey,
);

and use:
Supabase.instance.client.auth.headers['Authorization']

but I am having the problem that when my app is open for some time, it seems that my JWT expires and when I trigger the Edge-Function again, I get Invalid JWT as a response.

What do I have to do to make sure, that the auth.headers are renewed?

@nietsmmar
Copy link

nietsmmar commented Mar 2, 2024

@dshukertjr @laktek as the flutter_sse library does not work in web I had to use a hacky fork of it, and combine it with the fetch_client library. This is currently the only way to implement streaming in flutter web for supabase edge functions. Auth ist broken and not working correctly.

And now I am running into error handling issues because of this, as the AutoreconnectHandler from flutter_sse fork is preventing me from correctly handling errors.

This is really a mess. I am just starting to duplicate logic from the SupabaseClient just because there is no option to use streaming directly.

I really like supabase but I really don't understand why this basic feature is not provided. Please put this on your roadmap.

@soulofmischief
Copy link
Contributor

soulofmischief commented Apr 14, 2024

@nietsmmar

This is really a mess. I am just starting to duplicate logic from the SupabaseClient just because there is no option to use streaming directly.

Yes, it's quite a cumbersome experience.

As of now I'm just live-patching the module with yarn using the following patch:

diff --git a/dist/main/FunctionsClient.js b/dist/main/FunctionsClient.js
index 834b25ee53b9a1a39560090bf77fe0a47e8d9563..c1dd7343456fd6c493bb37706b35577afb40d569 100644
--- a/dist/main/FunctionsClient.js
+++ b/dist/main/FunctionsClient.js
@@ -88,6 +88,9 @@ class FunctionsClient {
                 else if (responseType === 'application/octet-stream') {
                     data = yield response.blob();
                 }
+                else if (responseType === 'text/event-stream') {
+                    data = response.body;
+                }
                 else if (responseType === 'multipart/form-data') {
                     data = yield response.formData();
                 }
diff --git a/dist/module/FunctionsClient.js b/dist/module/FunctionsClient.js
index 18f313203fafb581e46405312390496a7f7d8dd5..a9edf858a47a576c40213951217e08cafdbe5429 100644
--- a/dist/module/FunctionsClient.js
+++ b/dist/module/FunctionsClient.js
@@ -85,6 +85,9 @@ export class FunctionsClient {
                 else if (responseType === 'application/octet-stream') {
                     data = yield response.blob();
                 }
+                else if (responseType === 'text/event-stream') {
+                    data = response.body;
+                }
                 else if (responseType === 'multipart/form-data') {
                     data = yield response.formData();
                 }

I really like supabase but I really don't understand why this basic feature is not provided. Please put this on your roadmap.

@dshukertjr @laktek Again this issue is solved in PR #74, in just two lines of code. It has been sitting open for almost 6 months now, please review and merge it. The lack of activity or triage in this repo is increasingly concerning, such basic functionality should not be neglected when the problem has been solved.

@laktek
Copy link
Contributor

laktek commented Apr 14, 2024

@soulofmischief Sorry, I missed that PR. I merged it and will release it today or tomorrow to superbase-js.

Thanks for the contribution.

@laktek
Copy link
Contributor

laktek commented Apr 15, 2024

@soulofmischief This change should be included in supabase-js > 2.42.4

@laktek laktek closed this as completed Apr 15, 2024
@nietsmmar
Copy link

@laktek will this also be merged into supabase-flutter?

@laktek
Copy link
Contributor

laktek commented Apr 15, 2024

@laktek will this also be merged into supabase-flutter?

@dshukertjr can you handle the flutter change?

@grdsdev
Copy link

grdsdev commented Apr 19, 2024

PR for supabase-swift supabase/supabase-swift#346

@dshukertjr
Copy link
Member

@nietsmmar For the Flutter library, let's use this issue to track it. supabase/supabase-flutter#894

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants