From f26894a6ff0b7f03b26c4c4252506da31f0e1921 Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Mon, 14 Oct 2024 17:44:45 -0400 Subject: [PATCH 1/7] add draft --- .gitignore | 3 + runner/app/main.py | 8 + runner/app/pipelines/sketch_to_image.py | 83 + runner/app/routes/sketch_to_image.py | 72 + runner/dl_checkpoints.sh | 3 + runner/gateway.openapi.yaml | 40 +- runner/gen_openapi.py | 2 + runner/openapi.yaml | 40 +- worker/docker.go | 1 + worker/multipart.go | 32 + worker/runner.gen.go | 1914 ----------------------- worker/worker.go | 53 + 12 files changed, 335 insertions(+), 1916 deletions(-) create mode 100644 runner/app/pipelines/sketch_to_image.py create mode 100644 runner/app/routes/sketch_to_image.py diff --git a/.gitignore b/.gitignore index 0a9429b0..0ced8f70 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ checkpoints # IDE .vscode *.code-workspace + +# Python +runner/.venv diff --git a/runner/app/main.py b/runner/app/main.py index 147a0c21..231eaffd 100644 --- a/runner/app/main.py +++ b/runner/app/main.py @@ -54,6 +54,10 @@ def load_pipeline(pipeline: str, model_id: str) -> any: from app.pipelines.segment_anything_2 import SegmentAnything2Pipeline return SegmentAnything2Pipeline(model_id) + case "sketch-to-image": + from app.pipelines.sketch_to_image import SketchToImagePipeline + + return SketchToImagePipeline(model_id) case _: raise EnvironmentError( f"{pipeline} is not a valid pipeline for model {model_id}" @@ -88,6 +92,10 @@ def load_route(pipeline: str) -> any: from app.routes import segment_anything_2 return segment_anything_2.router + case "sketch-to-image": + from app.routes import sketch_to_image + + return sketch_to_image.router case _: raise EnvironmentError(f"{pipeline} is not a valid pipeline") diff --git a/runner/app/pipelines/sketch_to_image.py b/runner/app/pipelines/sketch_to_image.py new file mode 100644 index 00000000..af402787 --- /dev/null +++ b/runner/app/pipelines/sketch_to_image.py @@ -0,0 +1,83 @@ +import logging +import os +from enum import Enum +from typing import List, Optional, Tuple + +import PIL +import torch +from app.pipelines.base import Pipeline +from app.pipelines.utils import ( + LoraLoader, + SafetyChecker, + get_model_dir, + get_torch_device, + is_lightning_model, + is_turbo_model, +) +from diffusers import ( + AutoencoderKL, + ControlNetModel, + EulerAncestralDiscreteScheduler, + StableDiffusionXLControlNetPipeline, +) +from huggingface_hub import file_download, hf_hub_download +from PIL import ImageFile +from safetensors.torch import load_file + +ImageFile.LOAD_TRUNCATED_IMAGES = True + +logger = logging.getLogger(__name__) + + +class ModelName(Enum): + """Enumeration mapping model names to their corresponding IDs.""" + + SCRIBBLE_SDXL = "xinsir/controlnet-scribble-sdxl-1.0" + + @classmethod + def list(cls): + """Return a list of all model IDs.""" + return list(map(lambda c: c.value, cls)) + + +class SketchToImagePipeline(Pipeline): + def __init__(self, model_id: str): + self.model_id = model_id + kwargs = {"cache_dir": get_model_dir()} + + torch_device = get_torch_device() + folder_name = file_download.repo_folder_name( + repo_id=model_id, repo_type="model" + ) + folder_path = os.path.join(get_model_dir(), folder_name) + + eulera_scheduler = EulerAncestralDiscreteScheduler.from_pretrained( + "stabilityai/stable-diffusion-xl-base-1.0", + subfolder="scheduler" + ) + controlnet = ControlNetModel.from_pretrained( + self.model_id, + torch_dtype=torch.float16 + ) + vae = AutoencoderKL.from_pretrained( + "madebyollin/sdxl-vae-fp16-fix", + torch_dtype=torch.float16 + ) + self.ldm = StableDiffusionXLControlNetPipeline.from_pretrained( + "stabilityai/stable-diffusion-xl-base-1.0", + controlnet=controlnet, + vae=vae, + safety_checker=None, + torch_dtype=torch.float16, + scheduler=eulera_scheduler, + ).to(torch_device) + + def __call__( + self, prompt: str, image: PIL.Image, **kwargs + ) -> List[PIL.Image]: + output = self.ldm(prompt, image=image, **kwargs) + + return output.images + + def __str__(self) -> str: + return f"SketchToImagePipeline model_id={self.model_id}" diff --git a/runner/app/routes/sketch_to_image.py b/runner/app/routes/sketch_to_image.py new file mode 100644 index 00000000..963812cc --- /dev/null +++ b/runner/app/routes/sketch_to_image.py @@ -0,0 +1,72 @@ +import logging +import os +from typing import Annotated + +from fastapi import APIRouter, Depends, File, Form, UploadFile, status +from fastapi.responses import JSONResponse +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer + +from app.dependencies import get_pipeline +from app.pipelines.base import Pipeline +from app.pipelines.utils.audio import AudioConversionError +from app.routes.util import HTTPError, TextResponse, file_exceeds_max_size, http_error + +router = APIRouter() + +logger = logging.getLogger(__name__) + +RESPONSES = { + status.HTTP_200_OK: { + "content": { + "application/json": {} + }, + }, + status.HTTP_400_BAD_REQUEST: {"model": HTTPError}, + status.HTTP_401_UNAUTHORIZED: {"model": HTTPError}, + status.HTTP_413_REQUEST_ENTITY_TOO_LARGE: {"model": HTTPError}, + status.HTTP_500_INTERNAL_SERVER_ERROR: {"model": HTTPError}, +} + + +def handle_pipeline_error(e: Exception) -> JSONResponse: + """Handles exceptions raised during audio processing. + + Args: + e: The exception raised during audio processing. + + Returns: + A JSONResponse with the appropriate error message and status code. + """ + logger.error(f"Audio processing error: {str(e)}") # Log the detailed error + if "Soundfile is either not in the correct format or is malformed" in str( + e + ) or isinstance(e, AudioConversionError): + status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE + error_message = "Unsupported audio format or malformed file." + else: + status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + error_message = "Internal server error during audio processing." + + return JSONResponse( + status_code=status_code, + content=http_error(error_message), + ) + + +@router.post( + "/sketch-to-image", + response_model=TextResponse, + responses=RESPONSES, + description="Transform sketch to image.", + operation_id="genSketchToImage", + summary="Sketch To Image", + tags=["generate"], +) +@router.post( + "/sketch-to-image/", + response_model=TextResponse, + responses=RESPONSES, + include_in_schema=False, +) +async def sketch_to_image(): + pass \ No newline at end of file diff --git a/runner/dl_checkpoints.sh b/runner/dl_checkpoints.sh index 4b91e3d8..8de48106 100755 --- a/runner/dl_checkpoints.sh +++ b/runner/dl_checkpoints.sh @@ -35,6 +35,9 @@ function download_beta_models() { # Download audio-to-text models. huggingface-cli download openai/whisper-large-v3 --include "*.safetensors" "*.json" --cache-dir models + # Download sketch-to-image models. + huggingface-cli download xinsir/controlnet-scribble-sdxl-1.0 --include "*.safetensors" "*.json" --cache-dir models + printf "\nDownloading token-gated models...\n" # Download image-to-video models (token-gated). diff --git a/runner/gateway.openapi.yaml b/runner/gateway.openapi.yaml index db86753a..904bf5c9 100644 --- a/runner/gateway.openapi.yaml +++ b/runner/gateway.openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.1.0 info: title: Livepeer AI Runner description: An application to run AI pipelines - version: v0.5.0 + version: '' servers: - url: https://dream-gateway.livepeer.cloud description: Livepeer Cloud Community Gateway @@ -303,6 +303,44 @@ paths: security: - HTTPBearer: [] x-speakeasy-name-override: segmentAnything2 + /sketch-to-image: + post: + tags: + - generate + summary: Sketch To Image + description: Transform sketch to image. + operationId: genSketchToImage + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/TextResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '413': + description: Request Entity Too Large + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' components: schemas: APIError: diff --git a/runner/gen_openapi.py b/runner/gen_openapi.py index f8b9c613..5ce26362 100644 --- a/runner/gen_openapi.py +++ b/runner/gen_openapi.py @@ -12,6 +12,7 @@ segment_anything_2, text_to_image, upscale, + sketch_to_image, ) from fastapi.openapi.utils import get_openapi import subprocess @@ -123,6 +124,7 @@ def write_openapi(fname: str, entrypoint: str = "runner", version: str = "0.0.0" app.include_router(upscale.router) app.include_router(audio_to_text.router) app.include_router(segment_anything_2.router) + app.include_router(sketch_to_image.router) logger.info(f"Generating OpenAPI schema for '{entrypoint}' entrypoint...") openapi = get_openapi( diff --git a/runner/openapi.yaml b/runner/openapi.yaml index f25b3d02..42e8f877 100644 --- a/runner/openapi.yaml +++ b/runner/openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.1.0 info: title: Livepeer AI Runner description: An application to run AI pipelines - version: v0.5.0 + version: '' servers: - url: https://dream-gateway.livepeer.cloud description: Livepeer Cloud Community Gateway @@ -314,6 +314,44 @@ paths: security: - HTTPBearer: [] x-speakeasy-name-override: segmentAnything2 + /sketch-to-image: + post: + tags: + - generate + summary: Sketch To Image + description: Transform sketch to image. + operationId: genSketchToImage + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/TextResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '413': + description: Request Entity Too Large + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' components: schemas: APIError: diff --git a/worker/docker.go b/worker/docker.go index f42c0e49..786c0991 100644 --- a/worker/docker.go +++ b/worker/docker.go @@ -37,6 +37,7 @@ var containerHostPorts = map[string]string{ "upscale": "8300", "audio-to-text": "8400", "segment-anything-2": "8500", + "sketch-to-image": "8800", } // Mapping for per pipeline container images. diff --git a/worker/multipart.go b/worker/multipart.go index 16bc425d..2acf8be7 100644 --- a/worker/multipart.go +++ b/worker/multipart.go @@ -313,3 +313,35 @@ func NewSegmentAnything2MultipartWriter(w io.Writer, req GenSegmentAnything2Mult return mw, nil } + +func NewSketchToImageMultipartWriter(w io.Writer, req SketchToImageMultipartRequestBody) (*multipart.Writer, error) { + mw := multipart.NewWriter(w) + writer, err := mw.CreateFormFile("audio", req.Audio.Filename()) + if err != nil { + return nil, err + } + audioSize := req.Audio.FileSize() + audioRdr, err := req.Audio.Reader() + if err != nil { + return nil, err + } + copied, err := io.Copy(writer, audioRdr) + if err != nil { + return nil, err + } + if copied != audioSize { + return nil, fmt.Errorf("failed to copy audio to multipart request audioBytes=%v copiedBytes=%v", audioSize, copied) + } + + if req.ModelId != nil { + if err := mw.WriteField("model_id", *req.ModelId); err != nil { + return nil, err + } + } + + if err := mw.Close(); err != nil { + return nil, err + } + + return mw, nil +} diff --git a/worker/runner.gen.go b/worker/runner.gen.go index a6b5c281..e69de29b 100644 --- a/worker/runner.gen.go +++ b/worker/runner.gen.go @@ -1,1914 +0,0 @@ -// Package worker provides primitives to interact with the openapi HTTP API. -// -// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. -package worker - -import ( - "bytes" - "compress/gzip" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "path" - "strings" - - "github.com/getkin/kin-openapi/openapi3" - "github.com/go-chi/chi/v5" - "github.com/oapi-codegen/runtime" - openapi_types "github.com/oapi-codegen/runtime/types" -) - -const ( - HTTPBearerScopes = "HTTPBearer.Scopes" -) - -// APIError API error response model. -type APIError struct { - // Msg The error message. - Msg string `json:"msg"` -} - -// BodyGenAudioToText defines model for Body_genAudioToText. -type BodyGenAudioToText struct { - // Audio Uploaded audio file to be transcribed. - Audio openapi_types.File `json:"audio"` - - // ModelId Hugging Face model ID used for transcription. - ModelId *string `json:"model_id,omitempty"` -} - -// BodyGenImageToImage defines model for Body_genImageToImage. -type BodyGenImageToImage struct { - // GuidanceScale Encourages model to generate images closely linked to the text prompt (higher values may reduce image quality). - GuidanceScale *float32 `json:"guidance_scale,omitempty"` - - // Image Uploaded image to modify with the pipeline. - Image openapi_types.File `json:"image"` - - // ImageGuidanceScale Degree to which the generated image is pushed towards the initial image. - ImageGuidanceScale *float32 `json:"image_guidance_scale,omitempty"` - - // Loras A LoRA (Low-Rank Adaptation) model and its corresponding weight for image generation. Example: { "latent-consistency/lcm-lora-sdxl": 1.0, "nerijs/pixel-art-xl": 1.2}. - Loras *string `json:"loras,omitempty"` - - // ModelId Hugging Face model ID used for image generation. - ModelId *string `json:"model_id,omitempty"` - - // NegativePrompt Text prompt(s) to guide what to exclude from image generation. Ignored if guidance_scale < 1. - NegativePrompt *string `json:"negative_prompt,omitempty"` - - // NumImagesPerPrompt Number of images to generate per prompt. - NumImagesPerPrompt *int `json:"num_images_per_prompt,omitempty"` - - // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. - NumInferenceSteps *int `json:"num_inference_steps,omitempty"` - - // Prompt Text prompt(s) to guide image generation. - Prompt string `json:"prompt"` - - // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. - SafetyCheck *bool `json:"safety_check,omitempty"` - - // Seed Seed for random number generation. - Seed *int `json:"seed,omitempty"` - - // Strength Degree of transformation applied to the reference image (0 to 1). - Strength *float32 `json:"strength,omitempty"` -} - -// BodyGenImageToVideo defines model for Body_genImageToVideo. -type BodyGenImageToVideo struct { - // Fps The frames per second of the generated video. - Fps *int `json:"fps,omitempty"` - - // Height The height in pixels of the generated video. - Height *int `json:"height,omitempty"` - - // Image Uploaded image to generate a video from. - Image openapi_types.File `json:"image"` - - // ModelId Hugging Face model ID used for video generation. - ModelId *string `json:"model_id,omitempty"` - - // MotionBucketId Used for conditioning the amount of motion for the generation. The higher the number the more motion will be in the video. - MotionBucketId *int `json:"motion_bucket_id,omitempty"` - - // NoiseAugStrength Amount of noise added to the conditioning image. Higher values reduce resemblance to the conditioning image and increase motion. - NoiseAugStrength *float32 `json:"noise_aug_strength,omitempty"` - - // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. - NumInferenceSteps *int `json:"num_inference_steps,omitempty"` - - // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. - SafetyCheck *bool `json:"safety_check,omitempty"` - - // Seed Seed for random number generation. - Seed *int `json:"seed,omitempty"` - - // Width The width in pixels of the generated video. - Width *int `json:"width,omitempty"` -} - -// BodyGenSegmentAnything2 defines model for Body_genSegmentAnything2. -type BodyGenSegmentAnything2 struct { - // Box A length 4 array given as a box prompt to the model, in XYXY format. - Box *string `json:"box,omitempty"` - - // Image Image to segment. - Image openapi_types.File `json:"image"` - - // MaskInput A low-resolution mask input to the model, typically from a previous prediction iteration, with the form 1xHxW (H=W=256 for SAM). - MaskInput *string `json:"mask_input,omitempty"` - - // ModelId Hugging Face model ID used for image generation. - ModelId *string `json:"model_id,omitempty"` - - // MultimaskOutput If true, the model will return three masks for ambiguous input prompts, often producing better masks than a single prediction. - MultimaskOutput *bool `json:"multimask_output,omitempty"` - - // NormalizeCoords If true, the point coordinates will be normalized to the range [0,1], with point_coords expected to be with respect to image dimensions. - NormalizeCoords *bool `json:"normalize_coords,omitempty"` - - // PointCoords Nx2 array of point prompts to the model, where each point is in (X,Y) in pixels. - PointCoords *string `json:"point_coords,omitempty"` - - // PointLabels Labels for the point prompts, where 1 indicates a foreground point and 0 indicates a background point. - PointLabels *string `json:"point_labels,omitempty"` - - // ReturnLogits If true, returns un-thresholded mask logits instead of a binary mask. - ReturnLogits *bool `json:"return_logits,omitempty"` -} - -// BodyGenUpscale defines model for Body_genUpscale. -type BodyGenUpscale struct { - // Image Uploaded image to modify with the pipeline. - Image openapi_types.File `json:"image"` - - // ModelId Hugging Face model ID used for upscaled image generation. - ModelId *string `json:"model_id,omitempty"` - - // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. - NumInferenceSteps *int `json:"num_inference_steps,omitempty"` - - // Prompt Text prompt(s) to guide upscaled image generation. - Prompt string `json:"prompt"` - - // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. - SafetyCheck *bool `json:"safety_check,omitempty"` - - // Seed Seed for random number generation. - Seed *int `json:"seed,omitempty"` -} - -// HTTPError HTTP error response model. -type HTTPError struct { - // Detail Detailed error information. - Detail APIError `json:"detail"` -} - -// HTTPValidationError defines model for HTTPValidationError. -type HTTPValidationError struct { - Detail *[]ValidationError `json:"detail,omitempty"` -} - -// HealthCheck defines model for HealthCheck. -type HealthCheck struct { - Status *string `json:"status,omitempty"` -} - -// ImageResponse Response model for image generation. -type ImageResponse struct { - // Images The generated images. - Images []Media `json:"images"` -} - -// MasksResponse Response model for object segmentation. -type MasksResponse struct { - // Logits The raw, unnormalized predictions (logits) for the masks. - Logits string `json:"logits"` - - // Masks The generated masks. - Masks string `json:"masks"` - - // Scores The model's confidence scores for each generated mask. - Scores string `json:"scores"` -} - -// Media A media object containing information about the generated media. -type Media struct { - // Nsfw Whether the media was flagged as NSFW. - Nsfw bool `json:"nsfw"` - - // Seed The seed used to generate the media. - Seed int `json:"seed"` - - // Url The URL where the media can be accessed. - Url string `json:"url"` -} - -// TextResponse Response model for text generation. -type TextResponse struct { - // Chunks The generated text chunks. - Chunks []Chunk `json:"chunks"` - - // Text The generated text. - Text string `json:"text"` -} - -// TextToImageParams defines model for TextToImageParams. -type TextToImageParams struct { - // GuidanceScale Encourages model to generate images closely linked to the text prompt (higher values may reduce image quality). - GuidanceScale *float32 `json:"guidance_scale,omitempty"` - - // Height The height in pixels of the generated image. - Height *int `json:"height,omitempty"` - - // Loras A LoRA (Low-Rank Adaptation) model and its corresponding weight for image generation. Example: { "latent-consistency/lcm-lora-sdxl": 1.0, "nerijs/pixel-art-xl": 1.2}. - Loras *string `json:"loras,omitempty"` - - // ModelId Hugging Face model ID used for image generation. - ModelId *string `json:"model_id,omitempty"` - - // NegativePrompt Text prompt(s) to guide what to exclude from image generation. Ignored if guidance_scale < 1. - NegativePrompt *string `json:"negative_prompt,omitempty"` - - // NumImagesPerPrompt Number of images to generate per prompt. - NumImagesPerPrompt *int `json:"num_images_per_prompt,omitempty"` - - // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. - NumInferenceSteps *int `json:"num_inference_steps,omitempty"` - - // Prompt Text prompt(s) to guide image generation. Separate multiple prompts with '|' if supported by the model. - Prompt string `json:"prompt"` - - // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. - SafetyCheck *bool `json:"safety_check,omitempty"` - - // Seed Seed for random number generation. - Seed *int `json:"seed,omitempty"` - - // Width The width in pixels of the generated image. - Width *int `json:"width,omitempty"` -} - -// ValidationError defines model for ValidationError. -type ValidationError struct { - Loc []ValidationError_Loc_Item `json:"loc"` - Msg string `json:"msg"` - Type string `json:"type"` -} - -// ValidationErrorLoc0 defines model for . -type ValidationErrorLoc0 = string - -// ValidationErrorLoc1 defines model for . -type ValidationErrorLoc1 = int - -// ValidationError_Loc_Item defines model for ValidationError.loc.Item. -type ValidationError_Loc_Item struct { - union json.RawMessage -} - -// VideoResponse Response model for video generation. -type VideoResponse struct { - // Frames The generated video frames. - Frames [][]Media `json:"frames"` -} - -// Chunk A chunk of text with a timestamp. -type Chunk struct { - // Text The text of the chunk. - Text string `json:"text"` - - // Timestamp The timestamp of the chunk. - Timestamp []interface{} `json:"timestamp"` -} - -// GenAudioToTextMultipartRequestBody defines body for GenAudioToText for multipart/form-data ContentType. -type GenAudioToTextMultipartRequestBody = BodyGenAudioToText - -// GenImageToImageMultipartRequestBody defines body for GenImageToImage for multipart/form-data ContentType. -type GenImageToImageMultipartRequestBody = BodyGenImageToImage - -// GenImageToVideoMultipartRequestBody defines body for GenImageToVideo for multipart/form-data ContentType. -type GenImageToVideoMultipartRequestBody = BodyGenImageToVideo - -// GenSegmentAnything2MultipartRequestBody defines body for GenSegmentAnything2 for multipart/form-data ContentType. -type GenSegmentAnything2MultipartRequestBody = BodyGenSegmentAnything2 - -// GenTextToImageJSONRequestBody defines body for GenTextToImage for application/json ContentType. -type GenTextToImageJSONRequestBody = TextToImageParams - -// GenUpscaleMultipartRequestBody defines body for GenUpscale for multipart/form-data ContentType. -type GenUpscaleMultipartRequestBody = BodyGenUpscale - -// AsValidationErrorLoc0 returns the union data inside the ValidationError_Loc_Item as a ValidationErrorLoc0 -func (t ValidationError_Loc_Item) AsValidationErrorLoc0() (ValidationErrorLoc0, error) { - var body ValidationErrorLoc0 - err := json.Unmarshal(t.union, &body) - return body, err -} - -// FromValidationErrorLoc0 overwrites any union data inside the ValidationError_Loc_Item as the provided ValidationErrorLoc0 -func (t *ValidationError_Loc_Item) FromValidationErrorLoc0(v ValidationErrorLoc0) error { - b, err := json.Marshal(v) - t.union = b - return err -} - -// MergeValidationErrorLoc0 performs a merge with any union data inside the ValidationError_Loc_Item, using the provided ValidationErrorLoc0 -func (t *ValidationError_Loc_Item) MergeValidationErrorLoc0(v ValidationErrorLoc0) error { - b, err := json.Marshal(v) - if err != nil { - return err - } - - merged, err := runtime.JSONMerge(t.union, b) - t.union = merged - return err -} - -// AsValidationErrorLoc1 returns the union data inside the ValidationError_Loc_Item as a ValidationErrorLoc1 -func (t ValidationError_Loc_Item) AsValidationErrorLoc1() (ValidationErrorLoc1, error) { - var body ValidationErrorLoc1 - err := json.Unmarshal(t.union, &body) - return body, err -} - -// FromValidationErrorLoc1 overwrites any union data inside the ValidationError_Loc_Item as the provided ValidationErrorLoc1 -func (t *ValidationError_Loc_Item) FromValidationErrorLoc1(v ValidationErrorLoc1) error { - b, err := json.Marshal(v) - t.union = b - return err -} - -// MergeValidationErrorLoc1 performs a merge with any union data inside the ValidationError_Loc_Item, using the provided ValidationErrorLoc1 -func (t *ValidationError_Loc_Item) MergeValidationErrorLoc1(v ValidationErrorLoc1) error { - b, err := json.Marshal(v) - if err != nil { - return err - } - - merged, err := runtime.JSONMerge(t.union, b) - t.union = merged - return err -} - -func (t ValidationError_Loc_Item) MarshalJSON() ([]byte, error) { - b, err := t.union.MarshalJSON() - return b, err -} - -func (t *ValidationError_Loc_Item) UnmarshalJSON(b []byte) error { - err := t.union.UnmarshalJSON(b) - return err -} - -// RequestEditorFn is the function signature for the RequestEditor callback function -type RequestEditorFn func(ctx context.Context, req *http.Request) error - -// Doer performs HTTP requests. -// -// The standard http.Client implements this interface. -type HttpRequestDoer interface { - Do(req *http.Request) (*http.Response, error) -} - -// Client which conforms to the OpenAPI3 specification for this service. -type Client struct { - // The endpoint of the server conforming to this interface, with scheme, - // https://api.deepmap.com for example. This can contain a path relative - // to the server, such as https://api.deepmap.com/dev-test, and all the - // paths in the swagger spec will be appended to the server. - Server string - - // Doer for performing requests, typically a *http.Client with any - // customized settings, such as certificate chains. - Client HttpRequestDoer - - // A list of callbacks for modifying requests which are generated before sending over - // the network. - RequestEditors []RequestEditorFn -} - -// ClientOption allows setting custom parameters during construction -type ClientOption func(*Client) error - -// Creates a new Client, with reasonable defaults -func NewClient(server string, opts ...ClientOption) (*Client, error) { - // create a client with sane default values - client := Client{ - Server: server, - } - // mutate client and add all optional params - for _, o := range opts { - if err := o(&client); err != nil { - return nil, err - } - } - // ensure the server URL always has a trailing slash - if !strings.HasSuffix(client.Server, "/") { - client.Server += "/" - } - // create httpClient, if not already present - if client.Client == nil { - client.Client = &http.Client{} - } - return &client, nil -} - -// WithHTTPClient allows overriding the default Doer, which is -// automatically created using http.Client. This is useful for tests. -func WithHTTPClient(doer HttpRequestDoer) ClientOption { - return func(c *Client) error { - c.Client = doer - return nil - } -} - -// WithRequestEditorFn allows setting up a callback function, which will be -// called right before sending the request. This can be used to mutate the request. -func WithRequestEditorFn(fn RequestEditorFn) ClientOption { - return func(c *Client) error { - c.RequestEditors = append(c.RequestEditors, fn) - return nil - } -} - -// The interface specification for the client above. -type ClientInterface interface { - // GenAudioToTextWithBody request with any body - GenAudioToTextWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - // Health request - Health(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) - - // GenImageToImageWithBody request with any body - GenImageToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - // GenImageToVideoWithBody request with any body - GenImageToVideoWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - // GenSegmentAnything2WithBody request with any body - GenSegmentAnything2WithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - // GenTextToImageWithBody request with any body - GenTextToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - GenTextToImage(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - - // GenUpscaleWithBody request with any body - GenUpscaleWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) -} - -func (c *Client) GenAudioToTextWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenAudioToTextRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) Health(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewHealthRequest(c.Server) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) GenImageToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenImageToImageRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) GenImageToVideoWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenImageToVideoRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) GenSegmentAnything2WithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenSegmentAnything2RequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) GenTextToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenTextToImageRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) GenTextToImage(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenTextToImageRequest(c.Server, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -func (c *Client) GenUpscaleWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewGenUpscaleRequestWithBody(c.Server, contentType, body) - if err != nil { - return nil, err - } - req = req.WithContext(ctx) - if err := c.applyEditors(ctx, req, reqEditors); err != nil { - return nil, err - } - return c.Client.Do(req) -} - -// NewGenAudioToTextRequestWithBody generates requests for GenAudioToText with any type of body -func NewGenAudioToTextRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/audio-to-text") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewHealthRequest generates requests for Health -func NewHealthRequest(server string) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/health") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("GET", queryURL.String(), nil) - if err != nil { - return nil, err - } - - return req, nil -} - -// NewGenImageToImageRequestWithBody generates requests for GenImageToImage with any type of body -func NewGenImageToImageRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/image-to-image") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewGenImageToVideoRequestWithBody generates requests for GenImageToVideo with any type of body -func NewGenImageToVideoRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/image-to-video") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewGenSegmentAnything2RequestWithBody generates requests for GenSegmentAnything2 with any type of body -func NewGenSegmentAnything2RequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/segment-anything-2") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewGenTextToImageRequest calls the generic GenTextToImage builder with application/json body -func NewGenTextToImageRequest(server string, body GenTextToImageJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewGenTextToImageRequestWithBody(server, "application/json", bodyReader) -} - -// NewGenTextToImageRequestWithBody generates requests for GenTextToImage with any type of body -func NewGenTextToImageRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/text-to-image") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -// NewGenUpscaleRequestWithBody generates requests for GenUpscale with any type of body -func NewGenUpscaleRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error - - serverURL, err := url.Parse(server) - if err != nil { - return nil, err - } - - operationPath := fmt.Sprintf("/upscale") - if operationPath[0] == '/' { - operationPath = "." + operationPath - } - - queryURL, err := serverURL.Parse(operationPath) - if err != nil { - return nil, err - } - - req, err := http.NewRequest("POST", queryURL.String(), body) - if err != nil { - return nil, err - } - - req.Header.Add("Content-Type", contentType) - - return req, nil -} - -func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { - for _, r := range c.RequestEditors { - if err := r(ctx, req); err != nil { - return err - } - } - for _, r := range additionalEditors { - if err := r(ctx, req); err != nil { - return err - } - } - return nil -} - -// ClientWithResponses builds on ClientInterface to offer response payloads -type ClientWithResponses struct { - ClientInterface -} - -// NewClientWithResponses creates a new ClientWithResponses, which wraps -// Client with return type handling -func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { - client, err := NewClient(server, opts...) - if err != nil { - return nil, err - } - return &ClientWithResponses{client}, nil -} - -// WithBaseURL overrides the baseURL. -func WithBaseURL(baseURL string) ClientOption { - return func(c *Client) error { - newBaseURL, err := url.Parse(baseURL) - if err != nil { - return err - } - c.Server = newBaseURL.String() - return nil - } -} - -// ClientWithResponsesInterface is the interface specification for the client with responses above. -type ClientWithResponsesInterface interface { - // GenAudioToTextWithBodyWithResponse request with any body - GenAudioToTextWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenAudioToTextResponse, error) - - // HealthWithResponse request - HealthWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*HealthResponse, error) - - // GenImageToImageWithBodyWithResponse request with any body - GenImageToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToImageResponse, error) - - // GenImageToVideoWithBodyWithResponse request with any body - GenImageToVideoWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToVideoResponse, error) - - // GenSegmentAnything2WithBodyWithResponse request with any body - GenSegmentAnything2WithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenSegmentAnything2Response, error) - - // GenTextToImageWithBodyWithResponse request with any body - GenTextToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) - - GenTextToImageWithResponse(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) - - // GenUpscaleWithBodyWithResponse request with any body - GenUpscaleWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenUpscaleResponse, error) -} - -type GenAudioToTextResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *TextResponse - JSON400 *HTTPError - JSON401 *HTTPError - JSON413 *HTTPError - JSON422 *HTTPValidationError - JSON500 *HTTPError -} - -// Status returns HTTPResponse.Status -func (r GenAudioToTextResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r GenAudioToTextResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type HealthResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *HealthCheck -} - -// Status returns HTTPResponse.Status -func (r HealthResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r HealthResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type GenImageToImageResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *ImageResponse - JSON400 *HTTPError - JSON401 *HTTPError - JSON422 *HTTPValidationError - JSON500 *HTTPError -} - -// Status returns HTTPResponse.Status -func (r GenImageToImageResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r GenImageToImageResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type GenImageToVideoResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *VideoResponse - JSON400 *HTTPError - JSON401 *HTTPError - JSON422 *HTTPValidationError - JSON500 *HTTPError -} - -// Status returns HTTPResponse.Status -func (r GenImageToVideoResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r GenImageToVideoResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type GenSegmentAnything2Response struct { - Body []byte - HTTPResponse *http.Response - JSON200 *MasksResponse - JSON400 *HTTPError - JSON401 *HTTPError - JSON422 *HTTPValidationError - JSON500 *HTTPError -} - -// Status returns HTTPResponse.Status -func (r GenSegmentAnything2Response) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r GenSegmentAnything2Response) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type GenTextToImageResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *ImageResponse - JSON400 *HTTPError - JSON401 *HTTPError - JSON422 *HTTPValidationError - JSON500 *HTTPError -} - -// Status returns HTTPResponse.Status -func (r GenTextToImageResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r GenTextToImageResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -type GenUpscaleResponse struct { - Body []byte - HTTPResponse *http.Response - JSON200 *ImageResponse - JSON400 *HTTPError - JSON401 *HTTPError - JSON422 *HTTPValidationError - JSON500 *HTTPError -} - -// Status returns HTTPResponse.Status -func (r GenUpscaleResponse) Status() string { - if r.HTTPResponse != nil { - return r.HTTPResponse.Status - } - return http.StatusText(0) -} - -// StatusCode returns HTTPResponse.StatusCode -func (r GenUpscaleResponse) StatusCode() int { - if r.HTTPResponse != nil { - return r.HTTPResponse.StatusCode - } - return 0 -} - -// GenAudioToTextWithBodyWithResponse request with arbitrary body returning *GenAudioToTextResponse -func (c *ClientWithResponses) GenAudioToTextWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenAudioToTextResponse, error) { - rsp, err := c.GenAudioToTextWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenAudioToTextResponse(rsp) -} - -// HealthWithResponse request returning *HealthResponse -func (c *ClientWithResponses) HealthWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*HealthResponse, error) { - rsp, err := c.Health(ctx, reqEditors...) - if err != nil { - return nil, err - } - return ParseHealthResponse(rsp) -} - -// GenImageToImageWithBodyWithResponse request with arbitrary body returning *GenImageToImageResponse -func (c *ClientWithResponses) GenImageToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToImageResponse, error) { - rsp, err := c.GenImageToImageWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenImageToImageResponse(rsp) -} - -// GenImageToVideoWithBodyWithResponse request with arbitrary body returning *GenImageToVideoResponse -func (c *ClientWithResponses) GenImageToVideoWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToVideoResponse, error) { - rsp, err := c.GenImageToVideoWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenImageToVideoResponse(rsp) -} - -// GenSegmentAnything2WithBodyWithResponse request with arbitrary body returning *GenSegmentAnything2Response -func (c *ClientWithResponses) GenSegmentAnything2WithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenSegmentAnything2Response, error) { - rsp, err := c.GenSegmentAnything2WithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenSegmentAnything2Response(rsp) -} - -// GenTextToImageWithBodyWithResponse request with arbitrary body returning *GenTextToImageResponse -func (c *ClientWithResponses) GenTextToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) { - rsp, err := c.GenTextToImageWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenTextToImageResponse(rsp) -} - -func (c *ClientWithResponses) GenTextToImageWithResponse(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) { - rsp, err := c.GenTextToImage(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenTextToImageResponse(rsp) -} - -// GenUpscaleWithBodyWithResponse request with arbitrary body returning *GenUpscaleResponse -func (c *ClientWithResponses) GenUpscaleWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenUpscaleResponse, error) { - rsp, err := c.GenUpscaleWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseGenUpscaleResponse(rsp) -} - -// ParseGenAudioToTextResponse parses an HTTP response from a GenAudioToTextWithResponse call -func ParseGenAudioToTextResponse(rsp *http.Response) (*GenAudioToTextResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &GenAudioToTextResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest TextResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 413: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON413 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseHealthResponse parses an HTTP response from a HealthWithResponse call -func ParseHealthResponse(rsp *http.Response) (*HealthResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &HealthResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest HealthCheck - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - } - - return response, nil -} - -// ParseGenImageToImageResponse parses an HTTP response from a GenImageToImageWithResponse call -func ParseGenImageToImageResponse(rsp *http.Response) (*GenImageToImageResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &GenImageToImageResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ImageResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseGenImageToVideoResponse parses an HTTP response from a GenImageToVideoWithResponse call -func ParseGenImageToVideoResponse(rsp *http.Response) (*GenImageToVideoResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &GenImageToVideoResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest VideoResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseGenSegmentAnything2Response parses an HTTP response from a GenSegmentAnything2WithResponse call -func ParseGenSegmentAnything2Response(rsp *http.Response) (*GenSegmentAnything2Response, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &GenSegmentAnything2Response{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest MasksResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseGenTextToImageResponse parses an HTTP response from a GenTextToImageWithResponse call -func ParseGenTextToImageResponse(rsp *http.Response) (*GenTextToImageResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &GenTextToImageResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ImageResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ParseGenUpscaleResponse parses an HTTP response from a GenUpscaleWithResponse call -func ParseGenUpscaleResponse(rsp *http.Response) (*GenUpscaleResponse, error) { - bodyBytes, err := io.ReadAll(rsp.Body) - defer func() { _ = rsp.Body.Close() }() - if err != nil { - return nil, err - } - - response := &GenUpscaleResponse{ - Body: bodyBytes, - HTTPResponse: rsp, - } - - switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest ImageResponse - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON400 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON401 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: - var dest HTTPValidationError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON422 = &dest - - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: - var dest HTTPError - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON500 = &dest - - } - - return response, nil -} - -// ServerInterface represents all server handlers. -type ServerInterface interface { - // Audio To Text - // (POST /audio-to-text) - GenAudioToText(w http.ResponseWriter, r *http.Request) - // Health - // (GET /health) - Health(w http.ResponseWriter, r *http.Request) - // Image To Image - // (POST /image-to-image) - GenImageToImage(w http.ResponseWriter, r *http.Request) - // Image To Video - // (POST /image-to-video) - GenImageToVideo(w http.ResponseWriter, r *http.Request) - // Segment Anything 2 - // (POST /segment-anything-2) - GenSegmentAnything2(w http.ResponseWriter, r *http.Request) - // Text To Image - // (POST /text-to-image) - GenTextToImage(w http.ResponseWriter, r *http.Request) - // Upscale - // (POST /upscale) - GenUpscale(w http.ResponseWriter, r *http.Request) -} - -// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. - -type Unimplemented struct{} - -// Audio To Text -// (POST /audio-to-text) -func (_ Unimplemented) GenAudioToText(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// Health -// (GET /health) -func (_ Unimplemented) Health(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// Image To Image -// (POST /image-to-image) -func (_ Unimplemented) GenImageToImage(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// Image To Video -// (POST /image-to-video) -func (_ Unimplemented) GenImageToVideo(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// Segment Anything 2 -// (POST /segment-anything-2) -func (_ Unimplemented) GenSegmentAnything2(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// Text To Image -// (POST /text-to-image) -func (_ Unimplemented) GenTextToImage(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// Upscale -// (POST /upscale) -func (_ Unimplemented) GenUpscale(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// ServerInterfaceWrapper converts contexts to parameters. -type ServerInterfaceWrapper struct { - Handler ServerInterface - HandlerMiddlewares []MiddlewareFunc - ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) -} - -type MiddlewareFunc func(http.Handler) http.Handler - -// GenAudioToText operation middleware -func (siw *ServerInterfaceWrapper) GenAudioToText(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GenAudioToText(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -// Health operation middleware -func (siw *ServerInterfaceWrapper) Health(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.Health(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -// GenImageToImage operation middleware -func (siw *ServerInterfaceWrapper) GenImageToImage(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GenImageToImage(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -// GenImageToVideo operation middleware -func (siw *ServerInterfaceWrapper) GenImageToVideo(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GenImageToVideo(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -// GenSegmentAnything2 operation middleware -func (siw *ServerInterfaceWrapper) GenSegmentAnything2(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GenSegmentAnything2(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -// GenTextToImage operation middleware -func (siw *ServerInterfaceWrapper) GenTextToImage(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GenTextToImage(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -// GenUpscale operation middleware -func (siw *ServerInterfaceWrapper) GenUpscale(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GenUpscale(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r.WithContext(ctx)) -} - -type UnescapedCookieParamError struct { - ParamName string - Err error -} - -func (e *UnescapedCookieParamError) Error() string { - return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) -} - -func (e *UnescapedCookieParamError) Unwrap() error { - return e.Err -} - -type UnmarshalingParamError struct { - ParamName string - Err error -} - -func (e *UnmarshalingParamError) Error() string { - return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) -} - -func (e *UnmarshalingParamError) Unwrap() error { - return e.Err -} - -type RequiredParamError struct { - ParamName string -} - -func (e *RequiredParamError) Error() string { - return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) -} - -type RequiredHeaderError struct { - ParamName string - Err error -} - -func (e *RequiredHeaderError) Error() string { - return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) -} - -func (e *RequiredHeaderError) Unwrap() error { - return e.Err -} - -type InvalidParamFormatError struct { - ParamName string - Err error -} - -func (e *InvalidParamFormatError) Error() string { - return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) -} - -func (e *InvalidParamFormatError) Unwrap() error { - return e.Err -} - -type TooManyValuesForParamError struct { - ParamName string - Count int -} - -func (e *TooManyValuesForParamError) Error() string { - return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) -} - -// Handler creates http.Handler with routing matching OpenAPI spec. -func Handler(si ServerInterface) http.Handler { - return HandlerWithOptions(si, ChiServerOptions{}) -} - -type ChiServerOptions struct { - BaseURL string - BaseRouter chi.Router - Middlewares []MiddlewareFunc - ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) -} - -// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. -func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler { - return HandlerWithOptions(si, ChiServerOptions{ - BaseRouter: r, - }) -} - -func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { - return HandlerWithOptions(si, ChiServerOptions{ - BaseURL: baseURL, - BaseRouter: r, - }) -} - -// HandlerWithOptions creates http.Handler with additional options -func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { - r := options.BaseRouter - - if r == nil { - r = chi.NewRouter() - } - if options.ErrorHandlerFunc == nil { - options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { - http.Error(w, err.Error(), http.StatusBadRequest) - } - } - wrapper := ServerInterfaceWrapper{ - Handler: si, - HandlerMiddlewares: options.Middlewares, - ErrorHandlerFunc: options.ErrorHandlerFunc, - } - - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/audio-to-text", wrapper.GenAudioToText) - }) - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/health", wrapper.Health) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/image-to-image", wrapper.GenImageToImage) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/image-to-video", wrapper.GenImageToVideo) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/segment-anything-2", wrapper.GenSegmentAnything2) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/text-to-image", wrapper.GenTextToImage) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/upscale", wrapper.GenUpscale) - }) - - return r -} - -// Base64 encoded, gzipped, json marshaled Swagger object -var swaggerSpec = []string{ - - "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", -} - -// GetSwagger returns the content of the embedded swagger specification file -// or error if failed to decode -func decodeSpec() ([]byte, error) { - zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) - if err != nil { - return nil, fmt.Errorf("error base64 decoding spec: %w", err) - } - zr, err := gzip.NewReader(bytes.NewReader(zipped)) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - var buf bytes.Buffer - _, err = buf.ReadFrom(zr) - if err != nil { - return nil, fmt.Errorf("error decompressing spec: %w", err) - } - - return buf.Bytes(), nil -} - -var rawSpec = decodeSpecCached() - -// a naive cached of a decoded swagger spec -func decodeSpecCached() func() ([]byte, error) { - data, err := decodeSpec() - return func() ([]byte, error) { - return data, err - } -} - -// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. -func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { - res := make(map[string]func() ([]byte, error)) - if len(pathToFile) > 0 { - res[pathToFile] = rawSpec - } - - return res -} - -// GetSwagger returns the Swagger specification corresponding to the generated code -// in this file. The external references of Swagger specification are resolved. -// The logic of resolving external references is tightly connected to "import-mapping" feature. -// Externally referenced files must be embedded in the corresponding golang packages. -// Urls can be supported but this task was out of the scope. -func GetSwagger() (swagger *openapi3.T, err error) { - resolvePath := PathToRawSpec("") - - loader := openapi3.NewLoader() - loader.IsExternalRefsAllowed = true - loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { - pathToFile := url.String() - pathToFile = path.Clean(pathToFile) - getSpec, ok := resolvePath[pathToFile] - if !ok { - err1 := fmt.Errorf("path not found: %s", pathToFile) - return nil, err1 - } - return getSpec() - } - var specData []byte - specData, err = rawSpec() - if err != nil { - return - } - swagger, err = loader.LoadFromData(specData) - if err != nil { - return - } - return -} diff --git a/worker/worker.go b/worker/worker.go index f1e176de..4b9849e8 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -351,6 +351,59 @@ func (w *Worker) SegmentAnything2(ctx context.Context, req GenSegmentAnything2Mu return resp.JSON200, nil } +func (w *Worker) SketchToImage(ctx context.Context, req SketchToImageMultipartRequestBody) (*TextResponse, error) { + c, err := w.borrowContainer(ctx, "audio-to-text", *req.ModelId) + if err != nil { + return nil, err + } + defer w.returnContainer(c) + + var buf bytes.Buffer + mw, err := NewAudioToTextMultipartWriter(&buf, req) + if err != nil { + return nil, err + } + + resp, err := c.Client.AudioToTextWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf) + if err != nil { + return nil, err + } + + if resp.JSON422 != nil { + val, err := json.Marshal(resp.JSON422) + if err != nil { + return nil, err + } + slog.Error("audio-to-text container returned 422", slog.String("err", string(val))) + return nil, errors.New("audio-to-text container returned 422") + } + + if resp.JSON400 != nil { + val, err := json.Marshal(resp.JSON400) + if err != nil { + return nil, err + } + slog.Error("audio-to-text container returned 400", slog.String("err", string(val))) + return nil, errors.New("audio-to-text container returned 400") + } + + if resp.JSON413 != nil { + msg := "audio-to-text container returned 413 file too large; max file size is 50MB" + slog.Error("audio-to-text container returned 413", slog.String("err", string(msg))) + return nil, errors.New(msg) + } + + if resp.JSON500 != nil { + val, err := json.Marshal(resp.JSON500) + if err != nil { + return nil, err + } + slog.Error("audio-to-text container returned 500", slog.String("err", string(val))) + return nil, errors.New("audio-to-text container returned 500") + } + + return resp.JSON200, nil +} func (w *Worker) Warm(ctx context.Context, pipeline string, modelID string, endpoint RunnerEndpoint, optimizationFlags OptimizationFlags) error { if endpoint.URL == "" { return w.manager.Warm(ctx, pipeline, modelID, optimizationFlags) From 19ca464cbd9f7a10e5588d99c5835556a660a718 Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Tue, 15 Oct 2024 18:41:33 +0000 Subject: [PATCH 2/7] update to routes --- .gitignore | 1 + runner/app/pipelines/image_to_image.py | 3 +- runner/app/pipelines/sketch_to_image.py | 52 ++++++++- runner/app/routes/sketch_to_image.py | 147 +++++++++++++++++++----- runner/dl_checkpoints.sh | 4 +- 5 files changed, 168 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 0ced8f70..a344d15c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ checkpoints # Python runner/.venv +runner/.models diff --git a/runner/app/pipelines/image_to_image.py b/runner/app/pipelines/image_to_image.py index 868f6b96..aa71450c 100644 --- a/runner/app/pipelines/image_to_image.py +++ b/runner/app/pipelines/image_to_image.py @@ -64,7 +64,8 @@ def __init__(self, model_id: str): ) or ModelName.SDXL_LIGHTNING.value in model_id ) - if torch_device != "cpu" and has_fp16_variant: + kwargs["torch_dtype"] = torch.float + if torch_device.type != "cpu" and has_fp16_variant: logger.info("ImageToImagePipeline loading fp16 variant for %s", model_id) kwargs["torch_dtype"] = torch.float16 diff --git a/runner/app/pipelines/sketch_to_image.py b/runner/app/pipelines/sketch_to_image.py index af402787..b5aa40b1 100644 --- a/runner/app/pipelines/sketch_to_image.py +++ b/runner/app/pipelines/sketch_to_image.py @@ -50,34 +50,74 @@ def __init__(self, model_id: str): repo_id=model_id, repo_type="model" ) folder_path = os.path.join(get_model_dir(), folder_name) + has_fp16_variant = ( + any( + ".fp16.safetensors" in fname + for _, _, files in os.walk(folder_path) + for fname in files + ) + ) + + torch_dtype = torch.float + if torch_device.type != "cpu" and has_fp16_variant: + logger.info("SketchToImagePipeline loading fp16 variant for %s", model_id) + torch_dtype = torch.float16 + kwargs["torch_dtype"] = torch.float16 + kwargs["variant"] = "fp16" eulera_scheduler = EulerAncestralDiscreteScheduler.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", - subfolder="scheduler" + subfolder="scheduler", + cache_dir=get_model_dir(), ) controlnet = ControlNetModel.from_pretrained( self.model_id, - torch_dtype=torch.float16 + torch_dtype=torch_dtype, + cache_dir=get_model_dir(), ) vae = AutoencoderKL.from_pretrained( "madebyollin/sdxl-vae-fp16-fix", - torch_dtype=torch.float16 + torch_dtype=torch_dtype ) self.ldm = StableDiffusionXLControlNetPipeline.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", controlnet=controlnet, vae=vae, safety_checker=None, - torch_dtype=torch.float16, scheduler=eulera_scheduler, ).to(torch_device) + safety_checker_device = os.getenv("SAFETY_CHECKER_DEVICE", "cuda").lower() + self._safety_checker = SafetyChecker(device=safety_checker_device) + def __call__( self, prompt: str, image: PIL.Image, **kwargs - ) -> List[PIL.Image]: + ) -> Tuple[List[PIL.Image], List[Optional[bool]]]: + seed = kwargs.pop("seed", None) + safety_check = kwargs.pop("safety_check", True) + + if seed is not None: + if isinstance(seed, int): + kwargs["generator"] = torch.Generator(get_torch_device()).manual_seed( + seed + ) + elif isinstance(seed, list): + kwargs["generator"] = [ + torch.Generator(get_torch_device()).manual_seed(s) for s in seed + ] + if "num_inference_steps" in kwargs and ( + kwargs["num_inference_steps"] is None or kwargs["num_inference_steps"] < 1 + ): + del kwargs["num_inference_steps"] + output = self.ldm(prompt, image=image, **kwargs) - return output.images + if safety_check: + _, has_nsfw_concept = self._safety_checker.check_nsfw_images(output.images) + else: + has_nsfw_concept = [None] * len(output.images) + + return output.images, has_nsfw_concept def __str__(self) -> str: return f"SketchToImagePipeline model_id={self.model_id}" diff --git a/runner/app/routes/sketch_to_image.py b/runner/app/routes/sketch_to_image.py index 963812cc..724cced6 100644 --- a/runner/app/routes/sketch_to_image.py +++ b/runner/app/routes/sketch_to_image.py @@ -2,23 +2,30 @@ import os from typing import Annotated -from fastapi import APIRouter, Depends, File, Form, UploadFile, status +import torch +from fastapi import APIRouter, Depends, status, UploadFile, File, Form from fastapi.responses import JSONResponse from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer +from PIL import Image, ImageFile from app.dependencies import get_pipeline from app.pipelines.base import Pipeline -from app.pipelines.utils.audio import AudioConversionError -from app.routes.util import HTTPError, TextResponse, file_exceeds_max_size, http_error +from app.routes.util import HTTPError, ImageResponse, image_to_data_url, http_error + +ImageFile.LOAD_TRUNCATED_IMAGES = True router = APIRouter() -logger = logging.getLogger(__name__) +logger = logging.getLogger(__name__) RESPONSES = { status.HTTP_200_OK: { "content": { - "application/json": {} + "application/json": { + "schema": { + "x-speakeasy-name-override": "data", + } + } }, }, status.HTTP_400_BAD_REQUEST: {"model": HTTPError}, @@ -29,44 +36,124 @@ def handle_pipeline_error(e: Exception) -> JSONResponse: - """Handles exceptions raised during audio processing. - - Args: - e: The exception raised during audio processing. - - Returns: - A JSONResponse with the appropriate error message and status code. - """ - logger.error(f"Audio processing error: {str(e)}") # Log the detailed error - if "Soundfile is either not in the correct format or is malformed" in str( - e - ) or isinstance(e, AudioConversionError): - status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE - error_message = "Unsupported audio format or malformed file." - else: - status_code = status.HTTP_500_INTERNAL_SERVER_ERROR - error_message = "Internal server error during audio processing." - + if isinstance(e, torch.cuda.OutOfMemoryError): + torch.cuda.empty_cache() + logger.error(f"SketchToImagePipeline error: {e}") + logger.exception(e) return JSONResponse( - status_code=status_code, - content=http_error(error_message), + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content=http_error("SketchToImagePipeline error"), ) - @router.post( "/sketch-to-image", - response_model=TextResponse, + response_model=ImageResponse, responses=RESPONSES, description="Transform sketch to image.", operation_id="genSketchToImage", summary="Sketch To Image", tags=["generate"], + openapi_extra={"x-speakeasy-name-override": "sketchToImage"}, ) @router.post( "/sketch-to-image/", - response_model=TextResponse, + response_model=ImageResponse, responses=RESPONSES, include_in_schema=False, ) -async def sketch_to_image(): - pass \ No newline at end of file +async def sketch_to_image( + prompt: Annotated[ + str, + Form( + description=( + "Text prompt(s) to guide image generation. Separate multiple prompts " + "with '|' if supported by the model." + ) + ), + ], + image: Annotated[ + UploadFile, + File(description="Uploaded sketch image to generate a image from."), + ], + model_id: Annotated[ + str, + Form( + description="Hugging Face model ID used for image generation." + ), + ] = "", + height: Annotated[ + int, + Form(description="The height in pixels of the generated image."), + ] = 512, + width: Annotated[ + int, + Form(description="The width in pixels of the generated image."), + ] = 1024, + negative_prompt: Annotated[ + str, + Form( + description=( + "Text prompt(s) to guide what to exclude from image generation. " + "Ignored if guidance_scale < 1." + ), + ), + ] = "", + num_inference_steps: Annotated[ + int, + Form( + description=( + "Number of denoising steps. More steps usually lead to higher quality " + "images but slower inference. Modulated by strength." + ), + ), + ] = 8, + controlnet_conditioning_scale: Annotated[ + float, + Form(description="Encourages model to generate images follow the conditioning input more strictly"), + ] = 1.0, + pipeline: Pipeline = Depends(get_pipeline), + token: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False)), +): + auth_token = os.environ.get("AUTH_TOKEN") + if auth_token: + if not token or token.credentials != auth_token: + return JSONResponse( + status_code=status.HTTP_401_UNAUTHORIZED, + headers={"WWW-Authenticate": "Bearer"}, + content=http_error("Invalid bearer token"), + ) + + if model_id != "" and model_id != pipeline.model_id: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content=http_error( + f"pipeline configured with {pipeline.model_id} but called with " + f"{model_id}" + ), + ) + + image = Image.open(image.file).convert("RGB") + + images = [] + has_nsfw_concept = [] + try: + imgs, nsfw_checks = pipeline( + prompt=prompt, + image=image, + height=height, + width=width, + negative_prompt=negative_prompt, + num_inference_steps=num_inference_steps, + controlnet_conditioning_scale=controlnet_conditioning_scale, + ) + images.extend(imgs) + has_nsfw_concept.extend(nsfw_checks) + except Exception as e: + handle_pipeline_error(e) + + output_images = [ + {"url": image_to_data_url(img), "seed": sd, "nsfw": nsfw or False} + for img, sd, nsfw in zip(images, [1], has_nsfw_concept) + ] + + return {"images": output_images} \ No newline at end of file diff --git a/runner/dl_checkpoints.sh b/runner/dl_checkpoints.sh index 8de48106..d0757963 100755 --- a/runner/dl_checkpoints.sh +++ b/runner/dl_checkpoints.sh @@ -28,6 +28,7 @@ function download_beta_models() { huggingface-cli download SG161222/RealVisXL_V4.0_Lightning --include "*.fp16.safetensors" "*.json" "*.txt" --exclude ".onnx" ".onnx_data" --cache-dir models huggingface-cli download ByteDance/SDXL-Lightning --include "*unet.safetensors" --cache-dir models huggingface-cli download timbrooks/instruct-pix2pix --include "*.fp16.safetensors" "*.json" "*.txt" --cache-dir models + huggingface-cli download xinsir/controlnet-scribble-sdxl-1.0 --include "*.safetensors" "*.json" --cache-dir models # Download upscale models huggingface-cli download stabilityai/stable-diffusion-x4-upscaler --include "*.fp16.safetensors" --cache-dir models @@ -35,8 +36,7 @@ function download_beta_models() { # Download audio-to-text models. huggingface-cli download openai/whisper-large-v3 --include "*.safetensors" "*.json" --cache-dir models - # Download sketch-to-image models. - huggingface-cli download xinsir/controlnet-scribble-sdxl-1.0 --include "*.safetensors" "*.json" --cache-dir models + printf "\nDownloading token-gated models...\n" From 9add37861c19322b99de4955f27b813da73ea583 Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Tue, 15 Oct 2024 20:29:36 +0000 Subject: [PATCH 3/7] update worker --- runner/gateway.openapi.yaml | 69 +- runner/openapi.yaml | 68 +- worker/multipart.go | 42 +- worker/runner.gen.go | 2120 +++++++++++++++++++++++++++++++++++ worker/worker.go | 27 +- 5 files changed, 2301 insertions(+), 25 deletions(-) diff --git a/runner/gateway.openapi.yaml b/runner/gateway.openapi.yaml index 904bf5c9..b86946d4 100644 --- a/runner/gateway.openapi.yaml +++ b/runner/gateway.openapi.yaml @@ -310,13 +310,20 @@ paths: summary: Sketch To Image description: Transform sketch to image. operationId: genSketchToImage + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/Body_genSketchToImage' + required: true responses: '200': description: Successful Response content: application/json: schema: - $ref: '#/components/schemas/TextResponse' + $ref: '#/components/schemas/ImageResponse' + x-speakeasy-name-override: data '400': description: Bad Request content: @@ -341,6 +348,15 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPError' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + security: + - HTTPBearer: [] + x-speakeasy-name-override: sketchToImage components: schemas: APIError: @@ -560,6 +576,57 @@ components: - image - model_id title: Body_genSegmentAnything2 + Body_genSketchToImage: + properties: + prompt: + type: string + title: Prompt + description: Text prompt(s) to guide image generation. Separate multiple + prompts with '|' if supported by the model. + image: + type: string + format: binary + title: Image + description: Uploaded sketch image to generate a image from. + model_id: + type: string + title: Model Id + description: Hugging Face model ID used for image generation. + default: '' + height: + type: integer + title: Height + description: The height in pixels of the generated image. + default: 512 + width: + type: integer + title: Width + description: The width in pixels of the generated image. + default: 1024 + negative_prompt: + type: string + title: Negative Prompt + description: Text prompt(s) to guide what to exclude from image generation. + Ignored if guidance_scale < 1. + default: '' + num_inference_steps: + type: integer + title: Num Inference Steps + description: Number of denoising steps. More steps usually lead to higher + quality images but slower inference. Modulated by strength. + default: 8 + controlnet_conditioning_scale: + type: number + title: Controlnet Conditioning Scale + description: Encourages model to generate images follow the conditioning + input more strictly + default: 1.0 + type: object + required: + - prompt + - image + - model_id + title: Body_genSketchToImage Body_genUpscale: properties: prompt: diff --git a/runner/openapi.yaml b/runner/openapi.yaml index 42e8f877..b3d492ca 100644 --- a/runner/openapi.yaml +++ b/runner/openapi.yaml @@ -321,13 +321,20 @@ paths: summary: Sketch To Image description: Transform sketch to image. operationId: genSketchToImage + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/Body_genSketchToImage' + required: true responses: '200': description: Successful Response content: application/json: schema: - $ref: '#/components/schemas/TextResponse' + $ref: '#/components/schemas/ImageResponse' + x-speakeasy-name-override: data '400': description: Bad Request content: @@ -352,6 +359,15 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPError' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + security: + - HTTPBearer: [] + x-speakeasy-name-override: sketchToImage components: schemas: APIError: @@ -567,6 +583,56 @@ components: required: - image title: Body_genSegmentAnything2 + Body_genSketchToImage: + properties: + prompt: + type: string + title: Prompt + description: Text prompt(s) to guide image generation. Separate multiple + prompts with '|' if supported by the model. + image: + type: string + format: binary + title: Image + description: Uploaded sketch image to generate a image from. + model_id: + type: string + title: Model Id + description: Hugging Face model ID used for image generation. + default: '' + height: + type: integer + title: Height + description: The height in pixels of the generated image. + default: 512 + width: + type: integer + title: Width + description: The width in pixels of the generated image. + default: 1024 + negative_prompt: + type: string + title: Negative Prompt + description: Text prompt(s) to guide what to exclude from image generation. + Ignored if guidance_scale < 1. + default: '' + num_inference_steps: + type: integer + title: Num Inference Steps + description: Number of denoising steps. More steps usually lead to higher + quality images but slower inference. Modulated by strength. + default: 8 + controlnet_conditioning_scale: + type: number + title: Controlnet Conditioning Scale + description: Encourages model to generate images follow the conditioning + input more strictly + default: 1.0 + type: object + required: + - prompt + - image + title: Body_genSketchToImage Body_genUpscale: properties: prompt: diff --git a/worker/multipart.go b/worker/multipart.go index 2acf8be7..b169c891 100644 --- a/worker/multipart.go +++ b/worker/multipart.go @@ -314,30 +314,58 @@ func NewSegmentAnything2MultipartWriter(w io.Writer, req GenSegmentAnything2Mult return mw, nil } -func NewSketchToImageMultipartWriter(w io.Writer, req SketchToImageMultipartRequestBody) (*multipart.Writer, error) { +func NewSketchToImageMultipartWriter(w io.Writer, req GenSketchToImageMultipartRequestBody) (*multipart.Writer, error) { mw := multipart.NewWriter(w) - writer, err := mw.CreateFormFile("audio", req.Audio.Filename()) + writer, err := mw.CreateFormFile("image", req.Image.Filename()) if err != nil { return nil, err } - audioSize := req.Audio.FileSize() - audioRdr, err := req.Audio.Reader() + imageSize := req.Image.FileSize() + imageRdr, err := req.Image.Reader() if err != nil { return nil, err } - copied, err := io.Copy(writer, audioRdr) + copied, err := io.Copy(writer, imageRdr) if err != nil { return nil, err } - if copied != audioSize { - return nil, fmt.Errorf("failed to copy audio to multipart request audioBytes=%v copiedBytes=%v", audioSize, copied) + if copied != imageSize { + return nil, fmt.Errorf("failed to copy image to multipart request imageBytes=%v copiedBytes=%v", imageSize, copied) } + if err := mw.WriteField("prompt", req.Prompt); err != nil { + return nil, err + } if req.ModelId != nil { if err := mw.WriteField("model_id", *req.ModelId); err != nil { return nil, err } } + if req.Width != nil { + if err := mw.WriteField("width", strconv.Itoa(*req.Width)); err != nil { + return nil, err + } + } + if req.Height != nil { + if err := mw.WriteField("height", strconv.Itoa(*req.Height)); err != nil { + return nil, err + } + } + if req.ControlnetConditioningScale != nil { + if err := mw.WriteField("controlnet_conditioning_scale", fmt.Sprintf("%f", *req.ControlnetConditioningScale)); err != nil { + return nil, err + } + } + if req.NegativePrompt != nil { + if err := mw.WriteField("negative_prompt", *req.NegativePrompt); err != nil { + return nil, err + } + } + if req.NumInferenceSteps != nil { + if err := mw.WriteField("num_inference_steps", strconv.Itoa(*req.NumInferenceSteps)); err != nil { + return nil, err + } + } if err := mw.Close(); err != nil { return nil, err diff --git a/worker/runner.gen.go b/worker/runner.gen.go index e69de29b..32437725 100644 --- a/worker/runner.gen.go +++ b/worker/runner.gen.go @@ -0,0 +1,2120 @@ +// Package worker provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. +package worker + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "path" + "strings" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/go-chi/chi/v5" + "github.com/oapi-codegen/runtime" + openapi_types "github.com/oapi-codegen/runtime/types" +) + +const ( + HTTPBearerScopes = "HTTPBearer.Scopes" +) + +// APIError API error response model. +type APIError struct { + // Msg The error message. + Msg string `json:"msg"` +} + +// BodyGenAudioToText defines model for Body_genAudioToText. +type BodyGenAudioToText struct { + // Audio Uploaded audio file to be transcribed. + Audio openapi_types.File `json:"audio"` + + // ModelId Hugging Face model ID used for transcription. + ModelId *string `json:"model_id,omitempty"` +} + +// BodyGenImageToImage defines model for Body_genImageToImage. +type BodyGenImageToImage struct { + // GuidanceScale Encourages model to generate images closely linked to the text prompt (higher values may reduce image quality). + GuidanceScale *float32 `json:"guidance_scale,omitempty"` + + // Image Uploaded image to modify with the pipeline. + Image openapi_types.File `json:"image"` + + // ImageGuidanceScale Degree to which the generated image is pushed towards the initial image. + ImageGuidanceScale *float32 `json:"image_guidance_scale,omitempty"` + + // Loras A LoRA (Low-Rank Adaptation) model and its corresponding weight for image generation. Example: { "latent-consistency/lcm-lora-sdxl": 1.0, "nerijs/pixel-art-xl": 1.2}. + Loras *string `json:"loras,omitempty"` + + // ModelId Hugging Face model ID used for image generation. + ModelId *string `json:"model_id,omitempty"` + + // NegativePrompt Text prompt(s) to guide what to exclude from image generation. Ignored if guidance_scale < 1. + NegativePrompt *string `json:"negative_prompt,omitempty"` + + // NumImagesPerPrompt Number of images to generate per prompt. + NumImagesPerPrompt *int `json:"num_images_per_prompt,omitempty"` + + // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. + NumInferenceSteps *int `json:"num_inference_steps,omitempty"` + + // Prompt Text prompt(s) to guide image generation. + Prompt string `json:"prompt"` + + // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. + SafetyCheck *bool `json:"safety_check,omitempty"` + + // Seed Seed for random number generation. + Seed *int `json:"seed,omitempty"` + + // Strength Degree of transformation applied to the reference image (0 to 1). + Strength *float32 `json:"strength,omitempty"` +} + +// BodyGenImageToVideo defines model for Body_genImageToVideo. +type BodyGenImageToVideo struct { + // Fps The frames per second of the generated video. + Fps *int `json:"fps,omitempty"` + + // Height The height in pixels of the generated video. + Height *int `json:"height,omitempty"` + + // Image Uploaded image to generate a video from. + Image openapi_types.File `json:"image"` + + // ModelId Hugging Face model ID used for video generation. + ModelId *string `json:"model_id,omitempty"` + + // MotionBucketId Used for conditioning the amount of motion for the generation. The higher the number the more motion will be in the video. + MotionBucketId *int `json:"motion_bucket_id,omitempty"` + + // NoiseAugStrength Amount of noise added to the conditioning image. Higher values reduce resemblance to the conditioning image and increase motion. + NoiseAugStrength *float32 `json:"noise_aug_strength,omitempty"` + + // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. + NumInferenceSteps *int `json:"num_inference_steps,omitempty"` + + // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. + SafetyCheck *bool `json:"safety_check,omitempty"` + + // Seed Seed for random number generation. + Seed *int `json:"seed,omitempty"` + + // Width The width in pixels of the generated video. + Width *int `json:"width,omitempty"` +} + +// BodyGenSegmentAnything2 defines model for Body_genSegmentAnything2. +type BodyGenSegmentAnything2 struct { + // Box A length 4 array given as a box prompt to the model, in XYXY format. + Box *string `json:"box,omitempty"` + + // Image Image to segment. + Image openapi_types.File `json:"image"` + + // MaskInput A low-resolution mask input to the model, typically from a previous prediction iteration, with the form 1xHxW (H=W=256 for SAM). + MaskInput *string `json:"mask_input,omitempty"` + + // ModelId Hugging Face model ID used for image generation. + ModelId *string `json:"model_id,omitempty"` + + // MultimaskOutput If true, the model will return three masks for ambiguous input prompts, often producing better masks than a single prediction. + MultimaskOutput *bool `json:"multimask_output,omitempty"` + + // NormalizeCoords If true, the point coordinates will be normalized to the range [0,1], with point_coords expected to be with respect to image dimensions. + NormalizeCoords *bool `json:"normalize_coords,omitempty"` + + // PointCoords Nx2 array of point prompts to the model, where each point is in (X,Y) in pixels. + PointCoords *string `json:"point_coords,omitempty"` + + // PointLabels Labels for the point prompts, where 1 indicates a foreground point and 0 indicates a background point. + PointLabels *string `json:"point_labels,omitempty"` + + // ReturnLogits If true, returns un-thresholded mask logits instead of a binary mask. + ReturnLogits *bool `json:"return_logits,omitempty"` +} + +// BodyGenSketchToImage defines model for Body_genSketchToImage. +type BodyGenSketchToImage struct { + // ControlnetConditioningScale Encourages model to generate images follow the conditioning input more strictly + ControlnetConditioningScale *float32 `json:"controlnet_conditioning_scale,omitempty"` + + // Height The height in pixels of the generated image. + Height *int `json:"height,omitempty"` + + // Image Uploaded sketch image to generate a image from. + Image openapi_types.File `json:"image"` + + // ModelId Hugging Face model ID used for image generation. + ModelId *string `json:"model_id,omitempty"` + + // NegativePrompt Text prompt(s) to guide what to exclude from image generation. Ignored if guidance_scale < 1. + NegativePrompt *string `json:"negative_prompt,omitempty"` + + // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. + NumInferenceSteps *int `json:"num_inference_steps,omitempty"` + + // Prompt Text prompt(s) to guide image generation. Separate multiple prompts with '|' if supported by the model. + Prompt string `json:"prompt"` + + // Width The width in pixels of the generated image. + Width *int `json:"width,omitempty"` +} + +// BodyGenUpscale defines model for Body_genUpscale. +type BodyGenUpscale struct { + // Image Uploaded image to modify with the pipeline. + Image openapi_types.File `json:"image"` + + // ModelId Hugging Face model ID used for upscaled image generation. + ModelId *string `json:"model_id,omitempty"` + + // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. + NumInferenceSteps *int `json:"num_inference_steps,omitempty"` + + // Prompt Text prompt(s) to guide upscaled image generation. + Prompt string `json:"prompt"` + + // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. + SafetyCheck *bool `json:"safety_check,omitempty"` + + // Seed Seed for random number generation. + Seed *int `json:"seed,omitempty"` +} + +// HTTPError HTTP error response model. +type HTTPError struct { + // Detail Detailed error information. + Detail APIError `json:"detail"` +} + +// HTTPValidationError defines model for HTTPValidationError. +type HTTPValidationError struct { + Detail *[]ValidationError `json:"detail,omitempty"` +} + +// HealthCheck defines model for HealthCheck. +type HealthCheck struct { + Status *string `json:"status,omitempty"` +} + +// ImageResponse Response model for image generation. +type ImageResponse struct { + // Images The generated images. + Images []Media `json:"images"` +} + +// MasksResponse Response model for object segmentation. +type MasksResponse struct { + // Logits The raw, unnormalized predictions (logits) for the masks. + Logits string `json:"logits"` + + // Masks The generated masks. + Masks string `json:"masks"` + + // Scores The model's confidence scores for each generated mask. + Scores string `json:"scores"` +} + +// Media A media object containing information about the generated media. +type Media struct { + // Nsfw Whether the media was flagged as NSFW. + Nsfw bool `json:"nsfw"` + + // Seed The seed used to generate the media. + Seed int `json:"seed"` + + // Url The URL where the media can be accessed. + Url string `json:"url"` +} + +// TextResponse Response model for text generation. +type TextResponse struct { + // Chunks The generated text chunks. + Chunks []Chunk `json:"chunks"` + + // Text The generated text. + Text string `json:"text"` +} + +// TextToImageParams defines model for TextToImageParams. +type TextToImageParams struct { + // GuidanceScale Encourages model to generate images closely linked to the text prompt (higher values may reduce image quality). + GuidanceScale *float32 `json:"guidance_scale,omitempty"` + + // Height The height in pixels of the generated image. + Height *int `json:"height,omitempty"` + + // Loras A LoRA (Low-Rank Adaptation) model and its corresponding weight for image generation. Example: { "latent-consistency/lcm-lora-sdxl": 1.0, "nerijs/pixel-art-xl": 1.2}. + Loras *string `json:"loras,omitempty"` + + // ModelId Hugging Face model ID used for image generation. + ModelId *string `json:"model_id,omitempty"` + + // NegativePrompt Text prompt(s) to guide what to exclude from image generation. Ignored if guidance_scale < 1. + NegativePrompt *string `json:"negative_prompt,omitempty"` + + // NumImagesPerPrompt Number of images to generate per prompt. + NumImagesPerPrompt *int `json:"num_images_per_prompt,omitempty"` + + // NumInferenceSteps Number of denoising steps. More steps usually lead to higher quality images but slower inference. Modulated by strength. + NumInferenceSteps *int `json:"num_inference_steps,omitempty"` + + // Prompt Text prompt(s) to guide image generation. Separate multiple prompts with '|' if supported by the model. + Prompt string `json:"prompt"` + + // SafetyCheck Perform a safety check to estimate if generated images could be offensive or harmful. + SafetyCheck *bool `json:"safety_check,omitempty"` + + // Seed Seed for random number generation. + Seed *int `json:"seed,omitempty"` + + // Width The width in pixels of the generated image. + Width *int `json:"width,omitempty"` +} + +// ValidationError defines model for ValidationError. +type ValidationError struct { + Loc []ValidationError_Loc_Item `json:"loc"` + Msg string `json:"msg"` + Type string `json:"type"` +} + +// ValidationErrorLoc0 defines model for . +type ValidationErrorLoc0 = string + +// ValidationErrorLoc1 defines model for . +type ValidationErrorLoc1 = int + +// ValidationError_Loc_Item defines model for ValidationError.loc.Item. +type ValidationError_Loc_Item struct { + union json.RawMessage +} + +// VideoResponse Response model for video generation. +type VideoResponse struct { + // Frames The generated video frames. + Frames [][]Media `json:"frames"` +} + +// Chunk A chunk of text with a timestamp. +type Chunk struct { + // Text The text of the chunk. + Text string `json:"text"` + + // Timestamp The timestamp of the chunk. + Timestamp []interface{} `json:"timestamp"` +} + +// GenAudioToTextMultipartRequestBody defines body for GenAudioToText for multipart/form-data ContentType. +type GenAudioToTextMultipartRequestBody = BodyGenAudioToText + +// GenImageToImageMultipartRequestBody defines body for GenImageToImage for multipart/form-data ContentType. +type GenImageToImageMultipartRequestBody = BodyGenImageToImage + +// GenImageToVideoMultipartRequestBody defines body for GenImageToVideo for multipart/form-data ContentType. +type GenImageToVideoMultipartRequestBody = BodyGenImageToVideo + +// GenSegmentAnything2MultipartRequestBody defines body for GenSegmentAnything2 for multipart/form-data ContentType. +type GenSegmentAnything2MultipartRequestBody = BodyGenSegmentAnything2 + +// GenSketchToImageMultipartRequestBody defines body for GenSketchToImage for multipart/form-data ContentType. +type GenSketchToImageMultipartRequestBody = BodyGenSketchToImage + +// GenTextToImageJSONRequestBody defines body for GenTextToImage for application/json ContentType. +type GenTextToImageJSONRequestBody = TextToImageParams + +// GenUpscaleMultipartRequestBody defines body for GenUpscale for multipart/form-data ContentType. +type GenUpscaleMultipartRequestBody = BodyGenUpscale + +// AsValidationErrorLoc0 returns the union data inside the ValidationError_Loc_Item as a ValidationErrorLoc0 +func (t ValidationError_Loc_Item) AsValidationErrorLoc0() (ValidationErrorLoc0, error) { + var body ValidationErrorLoc0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromValidationErrorLoc0 overwrites any union data inside the ValidationError_Loc_Item as the provided ValidationErrorLoc0 +func (t *ValidationError_Loc_Item) FromValidationErrorLoc0(v ValidationErrorLoc0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeValidationErrorLoc0 performs a merge with any union data inside the ValidationError_Loc_Item, using the provided ValidationErrorLoc0 +func (t *ValidationError_Loc_Item) MergeValidationErrorLoc0(v ValidationErrorLoc0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsValidationErrorLoc1 returns the union data inside the ValidationError_Loc_Item as a ValidationErrorLoc1 +func (t ValidationError_Loc_Item) AsValidationErrorLoc1() (ValidationErrorLoc1, error) { + var body ValidationErrorLoc1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromValidationErrorLoc1 overwrites any union data inside the ValidationError_Loc_Item as the provided ValidationErrorLoc1 +func (t *ValidationError_Loc_Item) FromValidationErrorLoc1(v ValidationErrorLoc1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeValidationErrorLoc1 performs a merge with any union data inside the ValidationError_Loc_Item, using the provided ValidationErrorLoc1 +func (t *ValidationError_Loc_Item) MergeValidationErrorLoc1(v ValidationErrorLoc1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t ValidationError_Loc_Item) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *ValidationError_Loc_Item) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Doer performs HTTP requests. +// +// The standard http.Client implements this interface. +type HttpRequestDoer interface { + Do(req *http.Request) (*http.Response, error) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// ClientOption allows setting custom parameters during construction +type ClientOption func(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + Server: server, + } + // mutate client and add all optional params + for _, o := range opts { + if err := o(&client); err != nil { + return nil, err + } + } + // ensure the server URL always has a trailing slash + if !strings.HasSuffix(client.Server, "/") { + client.Server += "/" + } + // create httpClient, if not already present + if client.Client == nil { + client.Client = &http.Client{} + } + return &client, nil +} + +// WithHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithHTTPClient(doer HttpRequestDoer) ClientOption { + return func(c *Client) error { + c.Client = doer + return nil + } +} + +// WithRequestEditorFn allows setting up a callback function, which will be +// called right before sending the request. This can be used to mutate the request. +func WithRequestEditorFn(fn RequestEditorFn) ClientOption { + return func(c *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { + // GenAudioToTextWithBody request with any body + GenAudioToTextWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + // Health request + Health(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenImageToImageWithBody request with any body + GenImageToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenImageToVideoWithBody request with any body + GenImageToVideoWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenSegmentAnything2WithBody request with any body + GenSegmentAnything2WithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenSketchToImageWithBody request with any body + GenSketchToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenTextToImageWithBody request with any body + GenTextToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + GenTextToImage(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // GenUpscaleWithBody request with any body + GenUpscaleWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (c *Client) GenAudioToTextWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenAudioToTextRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) Health(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewHealthRequest(c.Server) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenImageToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenImageToImageRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenImageToVideoWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenImageToVideoRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenSegmentAnything2WithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenSegmentAnything2RequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenSketchToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenSketchToImageRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenTextToImageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenTextToImageRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenTextToImage(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenTextToImageRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) GenUpscaleWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGenUpscaleRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +// NewGenAudioToTextRequestWithBody generates requests for GenAudioToText with any type of body +func NewGenAudioToTextRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/audio-to-text") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewHealthRequest generates requests for Health +func NewHealthRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/health") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewGenImageToImageRequestWithBody generates requests for GenImageToImage with any type of body +func NewGenImageToImageRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/image-to-image") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenImageToVideoRequestWithBody generates requests for GenImageToVideo with any type of body +func NewGenImageToVideoRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/image-to-video") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenSegmentAnything2RequestWithBody generates requests for GenSegmentAnything2 with any type of body +func NewGenSegmentAnything2RequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/segment-anything-2") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenSketchToImageRequestWithBody generates requests for GenSketchToImage with any type of body +func NewGenSketchToImageRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/sketch-to-image") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenTextToImageRequest calls the generic GenTextToImage builder with application/json body +func NewGenTextToImageRequest(server string, body GenTextToImageJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewGenTextToImageRequestWithBody(server, "application/json", bodyReader) +} + +// NewGenTextToImageRequestWithBody generates requests for GenTextToImage with any type of body +func NewGenTextToImageRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/text-to-image") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewGenUpscaleRequestWithBody generates requests for GenUpscale with any type of body +func NewGenUpscaleRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/upscale") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range c.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on ClientInterface to offer response payloads +type ClientWithResponses struct { + ClientInterface +} + +// NewClientWithResponses creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { + client, err := NewClient(server, opts...) + if err != nil { + return nil, err + } + return &ClientWithResponses{client}, nil +} + +// WithBaseURL overrides the baseURL. +func WithBaseURL(baseURL string) ClientOption { + return func(c *Client) error { + newBaseURL, err := url.Parse(baseURL) + if err != nil { + return err + } + c.Server = newBaseURL.String() + return nil + } +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { + // GenAudioToTextWithBodyWithResponse request with any body + GenAudioToTextWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenAudioToTextResponse, error) + + // HealthWithResponse request + HealthWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*HealthResponse, error) + + // GenImageToImageWithBodyWithResponse request with any body + GenImageToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToImageResponse, error) + + // GenImageToVideoWithBodyWithResponse request with any body + GenImageToVideoWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToVideoResponse, error) + + // GenSegmentAnything2WithBodyWithResponse request with any body + GenSegmentAnything2WithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenSegmentAnything2Response, error) + + // GenSketchToImageWithBodyWithResponse request with any body + GenSketchToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenSketchToImageResponse, error) + + // GenTextToImageWithBodyWithResponse request with any body + GenTextToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) + + GenTextToImageWithResponse(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) + + // GenUpscaleWithBodyWithResponse request with any body + GenUpscaleWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenUpscaleResponse, error) +} + +type GenAudioToTextResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *TextResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON413 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenAudioToTextResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenAudioToTextResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type HealthResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *HealthCheck +} + +// Status returns HTTPResponse.Status +func (r HealthResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r HealthResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenImageToImageResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ImageResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenImageToImageResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenImageToImageResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenImageToVideoResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *VideoResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenImageToVideoResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenImageToVideoResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenSegmentAnything2Response struct { + Body []byte + HTTPResponse *http.Response + JSON200 *MasksResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenSegmentAnything2Response) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenSegmentAnything2Response) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenSketchToImageResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ImageResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON413 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenSketchToImageResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenSketchToImageResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenTextToImageResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ImageResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenTextToImageResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenTextToImageResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type GenUpscaleResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *ImageResponse + JSON400 *HTTPError + JSON401 *HTTPError + JSON422 *HTTPValidationError + JSON500 *HTTPError +} + +// Status returns HTTPResponse.Status +func (r GenUpscaleResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GenUpscaleResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +// GenAudioToTextWithBodyWithResponse request with arbitrary body returning *GenAudioToTextResponse +func (c *ClientWithResponses) GenAudioToTextWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenAudioToTextResponse, error) { + rsp, err := c.GenAudioToTextWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenAudioToTextResponse(rsp) +} + +// HealthWithResponse request returning *HealthResponse +func (c *ClientWithResponses) HealthWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*HealthResponse, error) { + rsp, err := c.Health(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseHealthResponse(rsp) +} + +// GenImageToImageWithBodyWithResponse request with arbitrary body returning *GenImageToImageResponse +func (c *ClientWithResponses) GenImageToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToImageResponse, error) { + rsp, err := c.GenImageToImageWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenImageToImageResponse(rsp) +} + +// GenImageToVideoWithBodyWithResponse request with arbitrary body returning *GenImageToVideoResponse +func (c *ClientWithResponses) GenImageToVideoWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenImageToVideoResponse, error) { + rsp, err := c.GenImageToVideoWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenImageToVideoResponse(rsp) +} + +// GenSegmentAnything2WithBodyWithResponse request with arbitrary body returning *GenSegmentAnything2Response +func (c *ClientWithResponses) GenSegmentAnything2WithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenSegmentAnything2Response, error) { + rsp, err := c.GenSegmentAnything2WithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenSegmentAnything2Response(rsp) +} + +// GenSketchToImageWithBodyWithResponse request with arbitrary body returning *GenSketchToImageResponse +func (c *ClientWithResponses) GenSketchToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenSketchToImageResponse, error) { + rsp, err := c.GenSketchToImageWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenSketchToImageResponse(rsp) +} + +// GenTextToImageWithBodyWithResponse request with arbitrary body returning *GenTextToImageResponse +func (c *ClientWithResponses) GenTextToImageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) { + rsp, err := c.GenTextToImageWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenTextToImageResponse(rsp) +} + +func (c *ClientWithResponses) GenTextToImageWithResponse(ctx context.Context, body GenTextToImageJSONRequestBody, reqEditors ...RequestEditorFn) (*GenTextToImageResponse, error) { + rsp, err := c.GenTextToImage(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenTextToImageResponse(rsp) +} + +// GenUpscaleWithBodyWithResponse request with arbitrary body returning *GenUpscaleResponse +func (c *ClientWithResponses) GenUpscaleWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*GenUpscaleResponse, error) { + rsp, err := c.GenUpscaleWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseGenUpscaleResponse(rsp) +} + +// ParseGenAudioToTextResponse parses an HTTP response from a GenAudioToTextWithResponse call +func ParseGenAudioToTextResponse(rsp *http.Response) (*GenAudioToTextResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenAudioToTextResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest TextResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 413: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON413 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseHealthResponse parses an HTTP response from a HealthWithResponse call +func ParseHealthResponse(rsp *http.Response) (*HealthResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &HealthResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest HealthCheck + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseGenImageToImageResponse parses an HTTP response from a GenImageToImageWithResponse call +func ParseGenImageToImageResponse(rsp *http.Response) (*GenImageToImageResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenImageToImageResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ImageResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGenImageToVideoResponse parses an HTTP response from a GenImageToVideoWithResponse call +func ParseGenImageToVideoResponse(rsp *http.Response) (*GenImageToVideoResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenImageToVideoResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest VideoResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGenSegmentAnything2Response parses an HTTP response from a GenSegmentAnything2WithResponse call +func ParseGenSegmentAnything2Response(rsp *http.Response) (*GenSegmentAnything2Response, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenSegmentAnything2Response{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest MasksResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGenSketchToImageResponse parses an HTTP response from a GenSketchToImageWithResponse call +func ParseGenSketchToImageResponse(rsp *http.Response) (*GenSketchToImageResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenSketchToImageResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ImageResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 413: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON413 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGenTextToImageResponse parses an HTTP response from a GenTextToImageWithResponse call +func ParseGenTextToImageResponse(rsp *http.Response) (*GenTextToImageResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenTextToImageResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ImageResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ParseGenUpscaleResponse parses an HTTP response from a GenUpscaleWithResponse call +func ParseGenUpscaleResponse(rsp *http.Response) (*GenUpscaleResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GenUpscaleResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest ImageResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON400 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON401 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 422: + var dest HTTPValidationError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON422 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest HTTPError + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + // Audio To Text + // (POST /audio-to-text) + GenAudioToText(w http.ResponseWriter, r *http.Request) + // Health + // (GET /health) + Health(w http.ResponseWriter, r *http.Request) + // Image To Image + // (POST /image-to-image) + GenImageToImage(w http.ResponseWriter, r *http.Request) + // Image To Video + // (POST /image-to-video) + GenImageToVideo(w http.ResponseWriter, r *http.Request) + // Segment Anything 2 + // (POST /segment-anything-2) + GenSegmentAnything2(w http.ResponseWriter, r *http.Request) + // Sketch To Image + // (POST /sketch-to-image) + GenSketchToImage(w http.ResponseWriter, r *http.Request) + // Text To Image + // (POST /text-to-image) + GenTextToImage(w http.ResponseWriter, r *http.Request) + // Upscale + // (POST /upscale) + GenUpscale(w http.ResponseWriter, r *http.Request) +} + +// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint. + +type Unimplemented struct{} + +// Audio To Text +// (POST /audio-to-text) +func (_ Unimplemented) GenAudioToText(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Health +// (GET /health) +func (_ Unimplemented) Health(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Image To Image +// (POST /image-to-image) +func (_ Unimplemented) GenImageToImage(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Image To Video +// (POST /image-to-video) +func (_ Unimplemented) GenImageToVideo(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Segment Anything 2 +// (POST /segment-anything-2) +func (_ Unimplemented) GenSegmentAnything2(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Sketch To Image +// (POST /sketch-to-image) +func (_ Unimplemented) GenSketchToImage(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Text To Image +// (POST /text-to-image) +func (_ Unimplemented) GenTextToImage(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// Upscale +// (POST /upscale) +func (_ Unimplemented) GenUpscale(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +type MiddlewareFunc func(http.Handler) http.Handler + +// GenAudioToText operation middleware +func (siw *ServerInterfaceWrapper) GenAudioToText(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenAudioToText(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// Health operation middleware +func (siw *ServerInterfaceWrapper) Health(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.Health(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// GenImageToImage operation middleware +func (siw *ServerInterfaceWrapper) GenImageToImage(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenImageToImage(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// GenImageToVideo operation middleware +func (siw *ServerInterfaceWrapper) GenImageToVideo(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenImageToVideo(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// GenSegmentAnything2 operation middleware +func (siw *ServerInterfaceWrapper) GenSegmentAnything2(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenSegmentAnything2(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// GenSketchToImage operation middleware +func (siw *ServerInterfaceWrapper) GenSketchToImage(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenSketchToImage(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// GenTextToImage operation middleware +func (siw *ServerInterfaceWrapper) GenTextToImage(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenTextToImage(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// GenUpscale operation middleware +func (siw *ServerInterfaceWrapper) GenUpscale(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + ctx = context.WithValue(ctx, HTTPBearerScopes, []string{}) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GenUpscale(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +type UnescapedCookieParamError struct { + ParamName string + Err error +} + +func (e *UnescapedCookieParamError) Error() string { + return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) +} + +func (e *UnescapedCookieParamError) Unwrap() error { + return e.Err +} + +type UnmarshalingParamError struct { + ParamName string + Err error +} + +func (e *UnmarshalingParamError) Error() string { + return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) +} + +func (e *UnmarshalingParamError) Unwrap() error { + return e.Err +} + +type RequiredParamError struct { + ParamName string +} + +func (e *RequiredParamError) Error() string { + return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) +} + +type RequiredHeaderError struct { + ParamName string + Err error +} + +func (e *RequiredHeaderError) Error() string { + return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) +} + +func (e *RequiredHeaderError) Unwrap() error { + return e.Err +} + +type InvalidParamFormatError struct { + ParamName string + Err error +} + +func (e *InvalidParamFormatError) Error() string { + return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) +} + +func (e *InvalidParamFormatError) Unwrap() error { + return e.Err +} + +type TooManyValuesForParamError struct { + ParamName string + Count int +} + +func (e *TooManyValuesForParamError) Error() string { + return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) +} + +// Handler creates http.Handler with routing matching OpenAPI spec. +func Handler(si ServerInterface) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + Middlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. +func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + if options.ErrorHandlerFunc == nil { + options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.Middlewares, + ErrorHandlerFunc: options.ErrorHandlerFunc, + } + + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/audio-to-text", wrapper.GenAudioToText) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/health", wrapper.Health) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/image-to-image", wrapper.GenImageToImage) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/image-to-video", wrapper.GenImageToVideo) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/segment-anything-2", wrapper.GenSegmentAnything2) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/sketch-to-image", wrapper.GenSketchToImage) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/text-to-image", wrapper.GenTextToImage) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/upscale", wrapper.GenUpscale) + }) + + return r +} + +// Base64 encoded, gzipped, json marshaled Swagger object +var swaggerSpec = []string{ + + "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", + "AA==", +} + +// GetSwagger returns the content of the embedded swagger specification file +// or error if failed to decode +func decodeSpec() ([]byte, error) { + zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, "")) + if err != nil { + return nil, fmt.Errorf("error base64 decoding spec: %w", err) + } + zr, err := gzip.NewReader(bytes.NewReader(zipped)) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + var buf bytes.Buffer + _, err = buf.ReadFrom(zr) + if err != nil { + return nil, fmt.Errorf("error decompressing spec: %w", err) + } + + return buf.Bytes(), nil +} + +var rawSpec = decodeSpecCached() + +// a naive cached of a decoded swagger spec +func decodeSpecCached() func() ([]byte, error) { + data, err := decodeSpec() + return func() ([]byte, error) { + return data, err + } +} + +// Constructs a synthetic filesystem for resolving external references when loading openapi specifications. +func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) { + res := make(map[string]func() ([]byte, error)) + if len(pathToFile) > 0 { + res[pathToFile] = rawSpec + } + + return res +} + +// GetSwagger returns the Swagger specification corresponding to the generated code +// in this file. The external references of Swagger specification are resolved. +// The logic of resolving external references is tightly connected to "import-mapping" feature. +// Externally referenced files must be embedded in the corresponding golang packages. +// Urls can be supported but this task was out of the scope. +func GetSwagger() (swagger *openapi3.T, err error) { + resolvePath := PathToRawSpec("") + + loader := openapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) { + pathToFile := url.String() + pathToFile = path.Clean(pathToFile) + getSpec, ok := resolvePath[pathToFile] + if !ok { + err1 := fmt.Errorf("path not found: %s", pathToFile) + return nil, err1 + } + return getSpec() + } + var specData []byte + specData, err = rawSpec() + if err != nil { + return + } + swagger, err = loader.LoadFromData(specData) + if err != nil { + return + } + return +} diff --git a/worker/worker.go b/worker/worker.go index 4b9849e8..f300145a 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -351,20 +351,20 @@ func (w *Worker) SegmentAnything2(ctx context.Context, req GenSegmentAnything2Mu return resp.JSON200, nil } -func (w *Worker) SketchToImage(ctx context.Context, req SketchToImageMultipartRequestBody) (*TextResponse, error) { - c, err := w.borrowContainer(ctx, "audio-to-text", *req.ModelId) +func (w *Worker) SketchToImage(ctx context.Context, req GenSketchToImageMultipartRequestBody) (*TextResponse, error) { + c, err := w.borrowContainer(ctx, "sketch-to-image", *req.ModelId) if err != nil { return nil, err } defer w.returnContainer(c) var buf bytes.Buffer - mw, err := NewAudioToTextMultipartWriter(&buf, req) + mw, err := NewSketchToImageMultipartWriter(&buf, req) if err != nil { return nil, err } - resp, err := c.Client.AudioToTextWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf) + resp, err := c.Client.GenSketchToImageWithBodyWithResponse(ctx, mw.FormDataContentType(), &buf) if err != nil { return nil, err } @@ -374,8 +374,8 @@ func (w *Worker) SketchToImage(ctx context.Context, req SketchToImageMultipartRe if err != nil { return nil, err } - slog.Error("audio-to-text container returned 422", slog.String("err", string(val))) - return nil, errors.New("audio-to-text container returned 422") + slog.Error("sketch-to-image container returned 422", slog.String("err", string(val))) + return nil, errors.New("sketch-to-image container returned 422") } if resp.JSON400 != nil { @@ -383,14 +383,8 @@ func (w *Worker) SketchToImage(ctx context.Context, req SketchToImageMultipartRe if err != nil { return nil, err } - slog.Error("audio-to-text container returned 400", slog.String("err", string(val))) - return nil, errors.New("audio-to-text container returned 400") - } - - if resp.JSON413 != nil { - msg := "audio-to-text container returned 413 file too large; max file size is 50MB" - slog.Error("audio-to-text container returned 413", slog.String("err", string(msg))) - return nil, errors.New(msg) + slog.Error("sketch-to-image container returned 400", slog.String("err", string(val))) + return nil, errors.New("sketch-to-image container returned 400: " + resp.JSON400.Detail.Msg) } if resp.JSON500 != nil { @@ -398,12 +392,13 @@ func (w *Worker) SketchToImage(ctx context.Context, req SketchToImageMultipartRe if err != nil { return nil, err } - slog.Error("audio-to-text container returned 500", slog.String("err", string(val))) - return nil, errors.New("audio-to-text container returned 500") + slog.Error("sketch-to-image container returned 500", slog.String("err", string(val))) + return nil, errors.New("sketch-to-image container returned 500") } return resp.JSON200, nil } + func (w *Worker) Warm(ctx context.Context, pipeline string, modelID string, endpoint RunnerEndpoint, optimizationFlags OptimizationFlags) error { if endpoint.URL == "" { return w.manager.Warm(ctx, pipeline, modelID, optimizationFlags) From f515fbe9b50172184e0de1d04cc2685dff260b88 Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Fri, 18 Oct 2024 02:14:56 +0000 Subject: [PATCH 4/7] Add example --- cmd/examples/sketch-to-image/main.go | 105 +++++++++++++++++++++++++++ runner/app/routes/sketch_to_image.py | 2 +- runner/example_data/sketch.png | Bin 0 -> 82236 bytes worker/worker.go | 2 +- 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 cmd/examples/sketch-to-image/main.go create mode 100644 runner/example_data/sketch.png diff --git a/cmd/examples/sketch-to-image/main.go b/cmd/examples/sketch-to-image/main.go new file mode 100644 index 00000000..18b75aff --- /dev/null +++ b/cmd/examples/sketch-to-image/main.go @@ -0,0 +1,105 @@ +// Package main provides a small example on how to run the 'sketch-to-image' pipeline using the AI worker package. +package main + +import ( + "context" + "flag" + "log/slog" + "os" + "path" + "path/filepath" + "strconv" + "time" + + "github.com/livepeer/ai-worker/worker" + "github.com/oapi-codegen/runtime/types" +) + +func main() { + aiModelsDir := flag.String("aiModelsDir", "runner/models", "path to the models directory") + flag.Parse() + + containerName := "sketch-to-image" + baseOutputPath := "output" + + containerImageID := "livepeer/ai-runner:latest" + gpus := []string{"0"} + + modelsDir, err := filepath.Abs(*aiModelsDir) + if err != nil { + slog.Error("Error getting absolute path for 'aiModelsDir'", slog.String("error", err.Error())) + return + } + + modelID := "xinsir/controlnet-scribble-sdxl-1.0" + + w, err := worker.NewWorker(containerImageID, gpus, modelsDir) + if err != nil { + slog.Error("Error creating worker", slog.String("error", err.Error())) + return + } + + slog.Info("Warming container") + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + if err := w.Warm(ctx, containerName, modelID, worker.RunnerEndpoint{}, worker.OptimizationFlags{}); err != nil { + slog.Error("Error warming container", slog.String("error", err.Error())) + return + } + + slog.Info("Warm container is up") + + args := os.Args[1:] + runs, err := strconv.Atoi(args[0]) + if err != nil { + slog.Error("Invalid runs arg", slog.String("error", err.Error())) + return + } + + prompt := args[1] + imagePath := args[2] + + imageBytes, err := os.ReadFile(imagePath) + if err != nil { + slog.Error("Error reading image", slog.String("imagePath", imagePath)) + return + } + imageFile := types.File{} + imageFile.InitFromBytes(imageBytes, imagePath) + + req := worker.GenSketchToImageMultipartRequestBody{ + Image: imageFile, + ModelId: &modelID, + Prompt: prompt, + } + + for i := 0; i < runs; i++ { + slog.Info("Running sketch-to-image", slog.Int("num", i)) + + resp, err := w.SketchToImage(ctx, req) + if err != nil { + slog.Error("Error running sketch-to-image", slog.String("error", err.Error())) + return + } + + for j, media := range resp.Images { + outputPath := path.Join(baseOutputPath, strconv.Itoa(i)+"_"+strconv.Itoa(j)+".png") + if err := worker.SaveImageB64DataUrl(media.Url, outputPath); err != nil { + slog.Error("Error saving b64 data url as image", slog.String("error", err.Error())) + return + } + + slog.Info("Output written", slog.String("outputPath", outputPath)) + } + } + + slog.Info("Sleeping 2 seconds and then stopping container") + + time.Sleep(2 * time.Second) + + w.Stop(ctx) + + time.Sleep(1 * time.Second) +} diff --git a/runner/app/routes/sketch_to_image.py b/runner/app/routes/sketch_to_image.py index 724cced6..a344e009 100644 --- a/runner/app/routes/sketch_to_image.py +++ b/runner/app/routes/sketch_to_image.py @@ -152,7 +152,7 @@ async def sketch_to_image( handle_pipeline_error(e) output_images = [ - {"url": image_to_data_url(img), "seed": sd, "nsfw": nsfw or False} + {"url": image_to_data_url(img), "seed": 0, "nsfw": nsfw or False} for img, sd, nsfw in zip(images, [1], has_nsfw_concept) ] diff --git a/runner/example_data/sketch.png b/runner/example_data/sketch.png new file mode 100644 index 0000000000000000000000000000000000000000..089870ab0b884ac365a931ce43fa220cbad7e3c0 GIT binary patch literal 82236 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
    RS=%j4pBreBJwmOG(4QBg0QnzN- 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 DE Date: Fri, 18 Oct 2024 02:31:24 +0000 Subject: [PATCH 5/7] update api spec file --- .gitignore | 4 - runner/app/routes/sketch_to_image.py | 2 +- runner/gateway.openapi.yaml | 56 ++++++++++++- runner/openapi.yaml | 60 ++++++++++++-- worker/runner.gen.go | 119 ++++++++++++++------------- 5 files changed, 171 insertions(+), 70 deletions(-) diff --git a/.gitignore b/.gitignore index a344d15c..0a9429b0 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,3 @@ checkpoints # IDE .vscode *.code-workspace - -# Python -runner/.venv -runner/.models diff --git a/runner/app/routes/sketch_to_image.py b/runner/app/routes/sketch_to_image.py index a344e009..502f835e 100644 --- a/runner/app/routes/sketch_to_image.py +++ b/runner/app/routes/sketch_to_image.py @@ -10,7 +10,7 @@ from app.dependencies import get_pipeline from app.pipelines.base import Pipeline -from app.routes.util import HTTPError, ImageResponse, image_to_data_url, http_error +from app.routes.utils import HTTPError, ImageResponse, image_to_data_url, http_error ImageFile.LOAD_TRUNCATED_IMAGES = True diff --git a/runner/gateway.openapi.yaml b/runner/gateway.openapi.yaml index 77f51da1..6965773b 100644 --- a/runner/gateway.openapi.yaml +++ b/runner/gateway.openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.1.0 info: title: Livepeer AI Runner description: An application to run AI pipelines - version: v0.7.0 + version: '' servers: - url: https://dream-gateway.livepeer.cloud description: Livepeer Cloud Community Gateway @@ -356,6 +356,60 @@ paths: security: - HTTPBearer: [] x-speakeasy-name-override: llm + /sketch-to-image: + post: + tags: + - generate + summary: Sketch To Image + description: Transform sketch to image. + operationId: genSketchToImage + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/Body_genSketchToImage' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ImageResponse' + x-speakeasy-name-override: data + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '413': + description: Request Entity Too Large + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + security: + - HTTPBearer: [] + x-speakeasy-name-override: sketchToImage components: schemas: APIError: diff --git a/runner/openapi.yaml b/runner/openapi.yaml index e19900f8..9698fe4c 100644 --- a/runner/openapi.yaml +++ b/runner/openapi.yaml @@ -2,13 +2,7 @@ openapi: 3.1.0 info: title: Livepeer AI Runner description: An application to run AI pipelines -<<<<<<< HEAD version: '' -||||||| eb03c83 - version: v0.5.0 -======= - version: v0.7.0 ->>>>>>> main servers: - url: https://dream-gateway.livepeer.cloud description: Livepeer Cloud Community Gateway @@ -373,6 +367,60 @@ paths: security: - HTTPBearer: [] x-speakeasy-name-override: llm + /sketch-to-image: + post: + tags: + - generate + summary: Sketch To Image + description: Transform sketch to image. + operationId: genSketchToImage + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/Body_genSketchToImage' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ImageResponse' + x-speakeasy-name-override: data + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '413': + description: Request Entity Too Large + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + security: + - HTTPBearer: [] + x-speakeasy-name-override: sketchToImage components: schemas: APIError: diff --git a/worker/runner.gen.go b/worker/runner.gen.go index d54e4b59..4588ede9 100644 --- a/worker/runner.gen.go +++ b/worker/runner.gen.go @@ -2216,64 +2216,67 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "AAD//w0iQ6WcWQAA", } // GetSwagger returns the content of the embedded swagger specification file From cf8431e4b5e4b10b144a0e1c5bdb4533946b9d1a Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Fri, 18 Oct 2024 02:34:48 +0000 Subject: [PATCH 6/7] restore --- runner/app/pipelines/image_to_image.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runner/app/pipelines/image_to_image.py b/runner/app/pipelines/image_to_image.py index 31410409..cc30f648 100644 --- a/runner/app/pipelines/image_to_image.py +++ b/runner/app/pipelines/image_to_image.py @@ -65,8 +65,7 @@ def __init__(self, model_id: str): ) or ModelName.SDXL_LIGHTNING.value in model_id ) - kwargs["torch_dtype"] = torch.float - if torch_device.type != "cpu" and has_fp16_variant: + if torch_device != "cpu" and has_fp16_variant: logger.info("ImageToImagePipeline loading fp16 variant for %s", model_id) kwargs["torch_dtype"] = torch.float16 From e4ef844bc7d3aef4117436db7f042e1a95a618fb Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Thu, 24 Oct 2024 01:35:30 +0000 Subject: [PATCH 7/7] update spec --- runner/gateway.openapi.yaml | 56 ++++++++++++++++- runner/openapi.yaml | 56 ++++++++++++++++- worker/runner.gen.go | 122 ++++++++++++++++++------------------ 3 files changed, 172 insertions(+), 62 deletions(-) diff --git a/runner/gateway.openapi.yaml b/runner/gateway.openapi.yaml index eb22a430..bde80654 100644 --- a/runner/gateway.openapi.yaml +++ b/runner/gateway.openapi.yaml @@ -3,7 +3,7 @@ openapi: 3.1.0 info: title: Livepeer AI Runner description: An application to run AI pipelines - version: v0.9.0 + version: '' servers: - url: https://dream-gateway.livepeer.cloud description: Livepeer Cloud Community Gateway @@ -411,6 +411,60 @@ paths: security: - HTTPBearer: [] x-speakeasy-name-override: imageToText + /sketch-to-image: + post: + tags: + - generate + summary: Sketch To Image + description: Transform sketch to image. + operationId: genSketchToImage + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/Body_genSketchToImage' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ImageResponse' + x-speakeasy-name-override: data + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '413': + description: Request Entity Too Large + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + security: + - HTTPBearer: [] + x-speakeasy-name-override: sketchToImage components: schemas: APIError: diff --git a/runner/openapi.yaml b/runner/openapi.yaml index 5b430cee..bb82b20c 100644 --- a/runner/openapi.yaml +++ b/runner/openapi.yaml @@ -3,7 +3,7 @@ openapi: 3.1.0 info: title: Livepeer AI Runner description: An application to run AI pipelines - version: v0.9.0 + version: '' servers: - url: https://dream-gateway.livepeer.cloud description: Livepeer Cloud Community Gateway @@ -422,6 +422,60 @@ paths: security: - HTTPBearer: [] x-speakeasy-name-override: imageToText + /sketch-to-image: + post: + tags: + - generate + summary: Sketch To Image + description: Transform sketch to image. + operationId: genSketchToImage + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/Body_genSketchToImage' + required: true + responses: + '200': + description: Successful Response + content: + application/json: + schema: + $ref: '#/components/schemas/ImageResponse' + x-speakeasy-name-override: data + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '413': + description: Request Entity Too Large + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPError' + '422': + description: Validation Error + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + security: + - HTTPBearer: [] + x-speakeasy-name-override: sketchToImage components: schemas: APIError: diff --git a/worker/runner.gen.go b/worker/runner.gen.go index 437da2f5..f551ed83 100644 --- a/worker/runner.gen.go +++ b/worker/runner.gen.go @@ -2410,66 +2410,68 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "+lYAAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file