Signed URL¶
Generate a time-limited signed URL for a result asset stored in object storage (e.g., an annotated image or JSON output from a previous prediction). The URL grants temporary read access without requiring authentication on the client side.
POST /inference/assets/signed-url¶
Request¶
Content-Type: application/json
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
object_path |
string |
Yes | — | Path to the object in storage (e.g., results/output.json) |
expires_in |
integer |
No | 3600 |
URL expiry time in seconds |
Response¶
| Field | Type | Description |
|---|---|---|
object_path |
string |
The original object path |
signed_url |
string |
The temporary signed URL to access the asset |
expires_in |
integer |
Expiry duration in seconds |
{
"object_path": "results/abc123/output.json",
"signed_url": "https://storage.example.com/results/abc123/output.json?signature=...",
"expires_in": 3600
}
URL expiry
Signed URLs are valid only for the expires_in period. Request a new URL before expiry if you need continued access.
Code Examples¶
async function getSignedUrl(objectPath, expiresIn = 3600) {
const response = await fetch(
"https://sightapi.raku.so/api/v1/inference/assets/signed-url",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ object_path: objectPath, expires_in: expiresIn }),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail?.message ?? "Request failed");
}
return response.json();
}
// Usage
const { signed_url } = await getSignedUrl("results/abc123/output.json");
console.log("Download URL:", signed_url);
// Fetch the asset
const asset = await fetch(signed_url);
const data = await asset.json();
interface SignedUrlResponse {
object_path: string;
signed_url: string;
expires_in: number;
}
async function getSignedUrl(
objectPath: string,
expiresIn: number = 3600
): Promise<SignedUrlResponse> {
const response = await fetch(
"https://sightapi.raku.so/api/v1/inference/assets/signed-url",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ object_path: objectPath, expires_in: expiresIn }),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error((error.detail as { message: string })?.message ?? "Request failed");
}
return response.json() as Promise<SignedUrlResponse>;
}
// Usage
const { signed_url } = await getSignedUrl("results/abc123/output.json");
console.log("Download URL:", signed_url);
import httpx
from dataclasses import dataclass
@dataclass
class SignedUrlResponse:
object_path: str
signed_url: str
expires_in: int
def get_signed_url(object_path: str, expires_in: int = 3600) -> SignedUrlResponse:
with httpx.Client() as client:
response = client.post(
"https://sightapi.raku.so/api/v1/inference/assets/signed-url",
json={"object_path": object_path, "expires_in": expires_in},
)
response.raise_for_status()
data = response.json()
return SignedUrlResponse(**data)
# Usage
result = get_signed_url("results/abc123/output.json")
print("Download URL:", result.signed_url)
# Fetch the asset
with httpx.Client() as client:
asset = client.get(result.signed_url)
print(asset.json())
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
public record SignedUrlResponse(
[property: JsonPropertyName("object_path")] string ObjectPath,
[property: JsonPropertyName("signed_url")] string SignedUrl,
[property: JsonPropertyName("expires_in")] int ExpiresIn);
public class RakuSightClient
{
private static readonly HttpClient Http = new();
public static async Task<SignedUrlResponse> GetSignedUrlAsync(
string objectPath, int expiresIn = 3600)
{
var payload = new { object_path = objectPath, expires_in = expiresIn };
var response = await Http.PostAsJsonAsync(
"https://sightapi.raku.so/api/v1/inference/assets/signed-url",
payload);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<SignedUrlResponse>()
?? throw new InvalidOperationException("Empty response");
}
}
// Usage
var result = await RakuSightClient.GetSignedUrlAsync("results/abc123/output.json");
Console.WriteLine($"Download URL: {result.SignedUrl}");
// Fetch the asset via the signed URL
var asset = await new HttpClient().GetStringAsync(result.SignedUrl);
Console.WriteLine(asset);
import java.net.http.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class RakuSightClient {
private static final HttpClient CLIENT = HttpClient.newHttpClient();
private static final ObjectMapper MAPPER = new ObjectMapper();
public static JsonNode getSignedUrl(String objectPath, int expiresIn) throws Exception {
String body = String.format(
"{\"object_path\":\"%s\",\"expires_in\":%d}",
objectPath, expiresIn
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://sightapi.raku.so/api/v1/inference/assets/signed-url"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = CLIENT.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Request failed: " + response.body());
}
return MAPPER.readTree(response.body());
}
public static void main(String[] args) throws Exception {
JsonNode result = getSignedUrl("results/abc123/output.json", 3600);
String signedUrl = result.get("signed_url").asText();
System.out.println("Download URL: " + signedUrl);
// Fetch the asset
HttpRequest assetRequest = HttpRequest.newBuilder()
.uri(URI.create(signedUrl))
.GET()
.build();
HttpResponse<String> asset = CLIENT.send(
assetRequest, HttpResponse.BodyHandlers.ofString());
System.out.println(asset.body());
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type SignedUrlRequest struct {
ObjectPath string `json:"object_path"`
ExpiresIn int `json:"expires_in"`
}
type SignedUrlResponse struct {
ObjectPath string `json:"object_path"`
SignedURL string `json:"signed_url"`
ExpiresIn int `json:"expires_in"`
}
func getSignedUrl(objectPath string, expiresIn int) (*SignedUrlResponse, error) {
if expiresIn == 0 {
expiresIn = 3600
}
payload, _ := json.Marshal(SignedUrlRequest{
ObjectPath: objectPath,
ExpiresIn: expiresIn,
})
resp, err := http.Post(
"https://sightapi.raku.so/api/v1/inference/assets/signed-url",
"application/json",
bytes.NewReader(payload),
)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result SignedUrlResponse
json.NewDecoder(resp.Body).Decode(&result)
return &result, nil
}
func main() {
result, err := getSignedUrl("results/abc123/output.json", 3600)
if err != nil {
panic(err)
}
fmt.Println("Download URL:", result.SignedURL)
// Fetch the asset via signed URL
assetResp, _ := http.Get(result.SignedURL)
defer assetResp.Body.Close()
var asset map[string]any
json.NewDecoder(assetResp.Body).Decode(&asset)
fmt.Println(asset)
}