Search code examples
c#unity-game-enginehttpwebrequest

Change Output Of API Request?


I'm trying to use Replicate to send a text prompt and get a point cloud in return (to hopefully convert into a model) and bring into Unity. I got the request calling in Unity, but there seems to be two different output formats, "animation" and "json_file". Animation is a useless animated GIF, so I don't need it. I believe the JSON file contains the coordinates as well as the colour data (it may be a bit of a pain to stich a model together out of this, but one problem at a time), but I don't know how to access it.

I tried setting a header for output and output_type as json_file on both the second callback and the initial request, but it still just seems to return a single output, which is a rotating animated GIF of the model.

I read through the docs, and can't really find anything on how to change the output. It does say "the response can be multiple outputs" but it's only ever returning one, even if I try waiting for a bit. The API on the Replicate website seems to show the output_type as animation but I'm not sure how I can change this. There's options on the website, but I need to change it directly through the API call.

Here's the script I'm using to call it,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Prompt
{
    public string prompt;
}

public class PostResponse
{

    public string completed_at;
    public string created_at;
    public string error;
    public string id;
    public Prompt input;
    public string logs;
    public string metrics;
    public Output[] output;
    public string started_at;
    public string status;
    public string version;

}

public class Output
{
    public string output;
}

public class ReplicateAPI : MonoBehaviour
{
    private string API_ENDPOINT = "https://api.replicate.com/v1/predictions";
    private string REPLICATE_API_TOKEN = "r8_DhOE6C7LuA7edPvLh7Io0ukwbmXCLEY450vc3";

    private void Start()
    {
        StartCoroutine(Predict());
    }

    IEnumerator Predict()
    {
        string requestData = "{\"version\": \"1a4da7adf0bc84cd786c1df41c02db3097d899f5c159f5fd5814a11117bdf02b\", \"input\": {\"prompt\": \"big funny colourful sofa\"}}}";

        UnityWebRequest request = UnityWebRequest.Put(API_ENDPOINT, requestData);
        request.method = "POST";
        request.SetRequestHeader("Authorization", "Token " + REPLICATE_API_TOKEN);
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("output", "json_file");

        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
        {
            Debug.LogError("Error " + request.responseCode + ": " + request.error);
        }
        else
        {
            Debug.Log(request.downloadHandler.text);
            PostResponse response = JsonUtility.FromJson<PostResponse>(request.downloadHandler.text);

            StartCoroutine(GetResult(response.id));
        }
    }

    IEnumerator GetResult(string id)
    {
        yield return new WaitForSeconds(5);
        UnityWebRequest request = UnityWebRequest.Get(API_ENDPOINT +"/" + id);
        request.SetRequestHeader("Authorization", "Token " + REPLICATE_API_TOKEN);
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("output", "json_file");

        PointEResponse pointEResponse = new PointEResponse();

        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
        {
            Debug.LogError("Error " + request.responseCode + ": " + request.error);
            yield break;
        }
        else
        {
            pointEResponse = JsonUtility.FromJson<PointEResponse>(request.downloadHandler.text);
   
            Debug.Log(request.downloadHandler.text);
        }

        if (pointEResponse.status != "succeeded" || pointEResponse.output.Length == 0) StartCoroutine(GetResult(id));
        else 
        {
            print("We got something!" + pointEResponse.output[0]);

        }
    }
}

I've tried contacting Replicate twice but never received any response.

Any help would be appreciated, thanks!


Solution

  • I think you should encode the output_format argument into the request data, since it is aligned with the prompt argument in your first link.

    var prompt = "big funny colourful sofa";
    
    string requestData = $@"{{
        ""version"": ""1a4da7adf0bc84cd786c1df41c02db3097d899f5c159f5fd5814a11117bdf02b"",
        ""input"": {{
            ""prompt"": ""{prompt}"",
            ""output_format"": ""json_file""
        }}
    }}";