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

Ability to stream function responses #252

Closed
tmcgann opened this issue Feb 28, 2024 · 0 comments · Fixed by #346
Closed

Ability to stream function responses #252

tmcgann opened this issue Feb 28, 2024 · 0 comments · Fixed by #346
Labels
enhancement New feature or request

Comments

@tmcgann
Copy link

tmcgann commented Feb 28, 2024

Feature request

Is your feature request related to a problem? Please describe.

Want to stream function responses. Use case: stream chat completions from AI provider.

Describe the solution you'd like

Would love to augment the FunctionsClient to be able to stream data from a function response. Rough example of solution:

/// Implement the StreamResponseHandler protocol to handle the streamed data.
/// You could append received data chunks to a buffer, process data as it arrives, 
/// or update the UI (updates would be dispatched on the main thread).
protocol StreamResponseHandler {
    func didReceive(data: Data)
    func didCompleteWithError(_ error: Error?)
}

class StreamDataTaskHandler: NSObject, URLSessionDataDelegate {
    let streamHandler: StreamResponseHandler

    init(streamHandler: StreamResponseHandler) {
        self.streamHandler = streamHandler
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        // Forward the received data to the stream handler
        streamHandler.didReceive(data: data)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        // Notify the stream handler about completion or error
        streamHandler.didCompleteWithError(error)
    }
}

extension FunctionsClient {
    public func invokeWithStream(
        _ functionName: String,
        options: FunctionInvokeOptions = .init(),
        streamHandler: StreamResponseHandler
    ) async throws {
        // Setup URLSession with StreamDataTaskHandler as delegate
        let delegate = StreamDataTaskHandler(streamHandler: streamHandler)
        let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)
        
        // Rest of the setup similar to `rawInvoke`, but use the session with delegate
        let url = self.url.appendingPathComponent(functionName)
        var urlRequest = URLRequest(url: url)
        urlRequest.allHTTPHeaderFields = options.headers.merging(headers) { invoke, _ in invoke }
        urlRequest.httpMethod = (options.method ?? .post).rawValue
        urlRequest.httpBody = options.body
        
        // Start the data task
        let task = session.dataTask(with: urlRequest)
        task.resume()
        
        // Ensure to keep the session and delegate alive as long as needed
        // This may require storing references in the FunctionsClient or managing lifecycle appropriately
    }
}

Describe alternatives you've considered

Make the request to the function outside of supabase-swift.

Additional context

Open to alternatives, especially if this is somehow already supported and I missed it.

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

Successfully merging a pull request may close this issue.

1 participant