replicate / replicate-swift Goto Github PK
View Code? Open in Web Editor NEWSwift client for Replicate
Home Page: https://replicate.com
License: Apache License 2.0
Swift client for Replicate
Home Page: https://replicate.com
License: Apache License 2.0
In readme there is a security warning that says:
"Don't store secrets in code or any other resources bundled with your app. Instead, fetch them from CloudKit or another server and store them in the keychain."
It might create the false impression that simply storing the token in a secure space is enough to protect it from common vulnerabilities. However, the token is passed as a header in network requests and can be easily intercepted using a proxy app. I suggest warning developers that a safer approach is to avoid storing the token on the client side. Instead, they should communicate through their own backend, which securely stores the token and handles requests to Replicate. This way, the security aspect of communication with their backend remains the developer's responsibility.
Hi there! I’ve recently started playing with Replicate in SwiftUI and this library has been super helpful.
In my previous custom implementation of the Replicate HTTP API, I was doing some manual polling to get a stream of updates in predictions:
// Illustrative pseudocode
Task {
while prediction.completedAt == nil {
do {
try await Task.sleep(nanoseconds: 1_000_000_000)
prediction = try await fetchPrediction(prediction.id)
} catch {
print(error)
}
}
}
// 1 second
print(prediction.output) // ["Hello", "!", " "]
// 2 seconds
print(prediction.output) // ["Hello", "!", " ", "As", " ", "a", " ", "helpful", ...]
It'd be great if this library included a polling/streaming method alongside the wait
method, especially for chat-like models.
Fetching model prompthero/openjourney
(https://replicate.com/prompthero/openjourney) fails with this error:
dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "default_example", intValue: nil), CodingKeys(stringValue: "started_at", intValue: nil)], debugDescription: "Invalid date: 2022-11-15T02:17:27Z", underlyingError: nil))
The culprit:
private extension JSONDecoder.DateDecodingStrategy {
static let iso8601WithFractionalSeconds = custom { decoder in
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withFullDate,
.withFullTime,
.withFractionalSeconds]
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
guard let date = formatter.date(from: string) else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
}
return date
}
}
Hi,
Thank you so much for this amazing lib!
I was able to successfully reproduce your example at https://replicate.com/docs/get-started/swiftui. In the next steps section, you suggested we can concat a super resolution model after the stable diffusion model. I was wondering if you could show some code snippet on how to modify the example for this please. I found a hard time to implement it in a nice way. What I tried was something like below. The problem is that SuperResolutionView would be redrawn too many times. What we need is to only draw it once.
...
case .succeeded:
if let url = prediction.output?.first {
SuperResolutionView(url)
}
...
Best,
Jeff
Hi. I tried to use 2 model but I cannot reach these result:
stability-ai/stable-diffusion:
The result is: https://replicate.delivery/mgxm/50fcac81-865d-499e-81ac-49de0cb79264/out-0.png
but I cannot open it in a website or parse it to imageview. The error is: This site can’t be reachedreplicate. Delivery refused to connect.
meta/musicgen:
I got the result audio url: https://replicate.delivery/pbxt/F7Eg1oM138pGNJpeb0N9d2602RfS4jBSEIAXUHPfQNl2nzhjA/out.wav
but I cannot play it in safari or avplayer in iphone.
Any idea? Thanks
Sometimes it takes minutes to start a prediction, so it's nice to have this information so we can update the UI to give users some hint on the progress. Thanks!
Hi!
I'm trying to post an image (Swift code) to input of API and it's not working, can anyone help with updated documentation or Swift code example?
This is the code i'm using:
if let data = predictionImage?.jpegData(compressionQuality: 1.0) {
let mimeType = "image/jpeg"
attr["image"] = "\(data.uriEncoded(mimeType: mimeType))"
}
BR,
Hezi.
Hi all,
I forked the repo and tried to run the command listed in the README and cannot get it to run. Are there any extra installations required? I have a valid API token from Replicate (I have been able to run predictions). I am using openai/whisper, so my command looks like so:
REPLICATE_API_TOKEN=############## \ generate-replicate-model openai/whisper
...and I get an error stating "zsh: command not found: generate-replicate-model"
I am attempting to run the command from within the root directory of the repository.
Extra info: macOS 12.6, M1 processor
I'm struggling a bit with the output in this example:
let output = try await replicate.run(
"yorickvp/llava-13b:2facb4a474a0462c15041b78b1ad70952ea46b5ec6ad29583c0b29dbd4249591",
["prompt": "Describe this image", "image": "base64 image etc."]
)
Printing the output works fine and it show the words as an array with strings, but if I'm trying to do something with the output it is complaining that "type 'Value?' has no member X". For example
output.joined(separator: ", ")
will complain about "Value of type 'Value?' has no member 'joined'". What is the right way of handling output?
I aware defining a model is probably a better approach, but I'm using this to learn swift, so I'm trying to do it a bit step by step 🥲
Hey, I'm sorry to disturb you all, I wanted to use this client in my swift app that's being developed and I wasn't successful in adding the library to the project dependencies - when I add is through this github, it shows about 17 errors when building, most of them talking about a method not being available in iOS lower than 13 or 15, even though the target iOS version is 15, am I doing something wrong or does anyone have an idea what could I try?
thanks in advance
I have a problem using prediction.cancel and prediction.wait in a View that contains EnvironmentObjects:
struct PromptView: View {
@EnvironmentObject private var controller: ImageController
@EnvironmentObject private var generator: ImageProducer
@EnvironmentObject private var focusCon: GenerateImageFocusController
@EnvironmentObject private var store: ProjectStore
@State var prediction: Difussion.Prediction? = nil
let client: Replicate.Client = Replicate.Client(token: "exampleToken")
func generate() async throws {
prediction = try await Difussion.predict(with: client,
input: .init(prompt: "Example Prompt"))
try await prediction?.wait(with: client)
}
func cancel() async throws {
try await prediction?.cancel(with: client)
}
var body: some View {
VStack(alignment: .leading, spacing: 6) {
Text("Example")
}
}
}
Here is the error:
But if I delete the EnvironmentObjects The view seems to work:
Do you know what should I do to fix this issue? Since I need these environment objects in the view.
Thanks in advance.
/// Create a prediction using a deployment
///
/// - Parameters:
/// - owner:
/// The name of the deployment owner.
/// - name:
/// The name of the deployment.
/// - input:
/// The input depends on what model you are running.
///
/// To see the available inputs,
/// click the "Run with API" tab on the model you are running.
/// For example, stability-ai/stable-diffusion
/// takes prompt
as an input.
/// - webhook:
/// A webhook that is called when the prediction has completed.
///
/// It will be a POST
request where
/// the request body is the same as
/// the response body of the get prediction endpoint.
/// If there are network problems,
/// we will retry the webhook a few times,
/// so make sure it can be safely called more than once.
/// - stream:
/// Whether to stream the prediction output.
/// By default, this is false
.
public func createPrediction<Input: Codable, Output: Codable>(
_ type: Prediction<Input, Output>.Type = AnyPrediction.self,
deployment id: Deployment.ID,
input: Input,
webhook: Webhook? = nil,
stream: Bool = false
)
For folks just starting out, it may not be obvious how to add this library to their Xcode project. We should update the README to be more explicit about what steps you need to take. Here, we can pull in information from the "Build an app with SwiftUI" tutorial.
First of all, thank you for this great repo!
I'm using the following code to create a prediction:
let prediction = try await replicate.createPrediction(version: modelVersion ?? "",
input: ["prompt": text,
"num_inference_steps" : 50],
wait: true)
Benchmarking against the actual inference time in Replicate itself (Web GUI), it seems like the iOS client is slower. I wonder if maybe it's related to the retry policy when the wait: true
is set? Maybe the re-tries are too slow? Or it should be the same as using a webhook?
I tried to use the library with Hermes model available on Replicate and I get "is NOT allowed to set HSTS for main doc (null)" error. Any idea what the issue is?
Not sure how this should be handled, but an error I came across today:
Erorr valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "default_example", intValue: nil), CodingKeys(stringValue: "version", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))
This happens in, for example, this replicate: https://replicate.com/dannypostma/cog-visual-qr
The replicate doesn't contain a 'default_example' field, which looks to be expected in the Swift package:
{
"info": {
"title": "Cog",
"version": "0.1.0"
},
"paths": {
"/": {
"get": {
"summary": "Root",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"title": "Response Root Get"
}
}
},
"description": "Successful Response"
}
},
"operationId": "root__get"
}
},
"/shutdown": {
"post": {
"summary": "Start Shutdown",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"title": "Response Start Shutdown Shutdown Post"
}
}
},
"description": "Successful Response"
}
},
"operationId": "start_shutdown_shutdown_post"
}
},
"/predictions": {
"post": {
"summary": "Predict",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PredictionResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"parameters": [
{
"in": "header",
"name": "prefer",
"schema": {
"type": "string",
"title": "Prefer"
},
"required": false
}
],
"description": "Run a single prediction on the model",
"operationId": "predict_predictions_post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PredictionRequest"
}
}
}
}
}
},
"/health-check": {
"get": {
"summary": "Healthcheck",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"title": "Response Healthcheck Health Check Get"
}
}
},
"description": "Successful Response"
}
},
"operationId": "healthcheck_health_check_get"
}
},
"/predictions/{prediction_id}": {
"put": {
"summary": "Predict Idempotent",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PredictionResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"parameters": [
{
"in": "path",
"name": "prediction_id",
"schema": {
"type": "string",
"title": "Prediction ID"
},
"required": true
},
{
"in": "header",
"name": "prefer",
"schema": {
"type": "string",
"title": "Prefer"
},
"required": false
}
],
"description": "Run a single prediction on the model (idempotent creation).",
"operationId": "predict_idempotent_predictions__prediction_id__put",
"requestBody": {
"content": {
"application/json": {
"schema": {
"allOf": [
{
"$ref": "#/components/schemas/PredictionRequest"
}
],
"title": "Prediction Request"
}
}
},
"required": true
}
}
},
"/predictions/{prediction_id}/cancel": {
"post": {
"summary": "Cancel",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"title": "Response Cancel Predictions Prediction Id Cancel Post"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"parameters": [
{
"in": "path",
"name": "prediction_id",
"schema": {
"type": "string",
"title": "Prediction ID"
},
"required": true
}
],
"description": "Cancel a running prediction",
"operationId": "cancel_predictions__prediction_id__cancel_post"
}
}
},
"openapi": "3.0.2",
"components": {
"schemas": {
"Input": {
"type": "object",
"title": "Input",
"properties": {
"seed": {
"type": "integer",
"title": "Seed",
"default": 1594771627,
"x-order": 6
},
"prompt": {
"type": "string",
"title": "Prompt",
"default": "Gorgeous romantic sunset, cliffside onlooking the beautiful city of new york, warm colors, in the style of hiroshi nagai, very detailed, 8 0 s",
"x-order": 1
},
"strength": {
"type": "number",
"title": "Strength",
"default": 0.8,
"x-order": 5
},
"init_image": {
"type": "string",
"title": "Init Image",
"format": "uri",
"x-order": 8,
"description": "Input image"
},
"guidance_scale": {
"type": "number",
"title": "Guidance Scale",
"default": 20,
"x-order": 3
},
"negative_prompt": {
"type": "string",
"title": "Negative Prompt",
"default": "ugly, disfigured, low quality, blurry, nsfw",
"x-order": 2
},
"qr_code_content": {
"type": "string",
"title": "Qr Code Content",
"default": "https://www.headshotpro.com/",
"x-order": 0
},
"num_inference_steps": {
"type": "integer",
"title": "Num Inference Steps",
"default": 40,
"x-order": 7
},
"controlnet_conditioning_scale": {
"type": "number",
"title": "Controlnet Conditioning Scale",
"default": 2,
"x-order": 4
}
}
},
"Output": {
"type": "string",
"title": "Output",
"format": "uri"
},
"Status": {
"enum": [
"starting",
"processing",
"succeeded",
"canceled",
"failed"
],
"type": "string",
"title": "Status",
"description": "An enumeration."
},
"WebhookEvent": {
"enum": [
"start",
"output",
"logs",
"completed"
],
"type": "string",
"title": "WebhookEvent",
"description": "An enumeration."
},
"ValidationError": {
"type": "object",
"title": "ValidationError",
"required": [
"loc",
"msg",
"type"
],
"properties": {
"loc": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
}
},
"PredictionRequest": {
"type": "object",
"title": "PredictionRequest",
"properties": {
"id": {
"type": "string",
"title": "Id"
},
"input": {
"$ref": "#/components/schemas/Input"
},
"webhook": {
"type": "string",
"title": "Webhook",
"format": "uri",
"maxLength": 65536,
"minLength": 1
},
"created_at": {
"type": "string",
"title": "Created At",
"format": "date-time"
},
"output_file_prefix": {
"type": "string",
"title": "Output File Prefix"
},
"webhook_events_filter": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookEvent"
},
"default": [
"start",
"logs",
"completed",
"output"
],
"uniqueItems": true
}
}
},
"PredictionResponse": {
"type": "object",
"title": "PredictionResponse",
"properties": {
"id": {
"type": "string",
"title": "Id"
},
"logs": {
"type": "string",
"title": "Logs",
"default": ""
},
"error": {
"type": "string",
"title": "Error"
},
"input": {
"$ref": "#/components/schemas/Input"
},
"output": {
"$ref": "#/components/schemas/Output"
},
"status": {
"$ref": "#/components/schemas/Status"
},
"metrics": {
"type": "object",
"title": "Metrics"
},
"version": {
"type": "string",
"title": "Version"
},
"created_at": {
"type": "string",
"title": "Created At",
"format": "date-time"
},
"started_at": {
"type": "string",
"title": "Started At",
"format": "date-time"
},
"completed_at": {
"type": "string",
"title": "Completed At",
"format": "date-time"
}
}
},
"HTTPValidationError": {
"type": "object",
"title": "HTTPValidationError",
"properties": {
"detail": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"title": "Detail"
}
}
}
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.