From 9d3935a3dbbb27dac2f2f7a4d59d98cfd3ce5d49 Mon Sep 17 00:00:00 2001 From: Dev Aggarwal Date: Thu, 29 Feb 2024 15:15:57 +0530 Subject: [PATCH] add url validation on all recipes --- recipes/BulkRunner.py | 11 ++++++----- recipes/CompareText2Img.py | 4 +++- recipes/CompareUpscaler.py | 7 +++++-- recipes/DeforumSD.py | 3 ++- recipes/DocExtract.py | 7 ++++--- recipes/DocSummary.py | 3 ++- recipes/EmailFaceInpainting.py | 11 ++++++----- recipes/FaceInpainting.py | 11 ++++++----- recipes/ImageSegmentation.py | 11 ++++++----- recipes/Img2Img.py | 5 +++-- recipes/Lipsync.py | 8 +++++--- recipes/LipsyncTTS.py | 7 ++++--- recipes/ObjectInpainting.py | 11 ++++++----- recipes/QRCodeGenerator.py | 13 +++++++------ recipes/Text2Audio.py | 4 +++- recipes/TextToSpeech.py | 3 ++- recipes/VideoBots.py | 19 ++++++++++--------- recipes/asr.py | 5 +++-- 18 files changed, 83 insertions(+), 60 deletions(-) diff --git a/recipes/BulkRunner.py b/recipes/BulkRunner.py index c4ef5a3c0..7fed82c80 100644 --- a/recipes/BulkRunner.py +++ b/recipes/BulkRunner.py @@ -3,6 +3,7 @@ import typing import uuid +import pydantic from furl import furl from pydantic import BaseModel, Field @@ -33,7 +34,7 @@ class BulkRunnerPage(BasePage): price = 1 class RequestModel(BaseModel): - documents: list[str] = Field( + documents: list[pydantic.AnyHttpUrl] = Field( title="Input Data Spreadsheet", description=""" Upload or link to a CSV or google sheet that contains your sample input data. @@ -41,7 +42,7 @@ class RequestModel(BaseModel): Remember to includes header names in your CSV too. """, ) - run_urls: list[str] = Field( + run_urls: list[pydantic.AnyHttpUrl] = Field( title="Gooey Workflows", description=""" Provide one or more Gooey.AI workflow runs. @@ -62,7 +63,7 @@ class RequestModel(BaseModel): """, ) - eval_urls: list[str] | None = Field( + eval_urls: list[pydantic.AnyHttpUrl] | None = Field( title="Evaluation Workflows", description=""" _(optional)_ Add one or more Gooey.AI Evaluator Workflows to evaluate the results of your runs. @@ -70,9 +71,9 @@ class RequestModel(BaseModel): ) class ResponseModel(BaseModel): - output_documents: list[str] + output_documents: list[pydantic.AnyHttpUrl] - eval_runs: list[str] | None = Field( + eval_runs: list[pydantic.AnyHttpUrl] | None = Field( title="Evaluation Run URLs", description=""" List of URLs to the evaluation runs that you requested. diff --git a/recipes/CompareText2Img.py b/recipes/CompareText2Img.py index 7b1f421de..56b96edd5 100644 --- a/recipes/CompareText2Img.py +++ b/recipes/CompareText2Img.py @@ -1,5 +1,6 @@ import typing +import pydantic from pydantic import BaseModel import gooey_ui as st @@ -74,7 +75,8 @@ class RequestModel(BaseModel): class ResponseModel(BaseModel): output_images: dict[ - typing.Literal[tuple(e.name for e in Text2ImgModels)], list[str] + typing.Literal[tuple(e.name for e in Text2ImgModels)], + list[pydantic.AnyHttpUrl], ] @classmethod diff --git a/recipes/CompareUpscaler.py b/recipes/CompareUpscaler.py index 13f62de91..6328e2063 100644 --- a/recipes/CompareUpscaler.py +++ b/recipes/CompareUpscaler.py @@ -1,5 +1,6 @@ import typing +import pydantic from pydantic import BaseModel import gooey_ui as st @@ -20,7 +21,7 @@ class CompareUpscalerPage(BasePage): slug_versions = ["compare-ai-upscalers"] class RequestModel(BaseModel): - input_image: str + input_image: pydantic.AnyHttpUrl scale: int @@ -29,7 +30,9 @@ class RequestModel(BaseModel): ) class ResponseModel(BaseModel): - output_images: dict[typing.Literal[tuple(e.name for e in UpscalerModels)], str] + output_images: dict[ + typing.Literal[tuple(e.name for e in UpscalerModels)], pydantic.AnyHttpUrl + ] def render_form_v2(self): st.file_uploader( diff --git a/recipes/DeforumSD.py b/recipes/DeforumSD.py index d732e7b0c..708f3b0ac 100644 --- a/recipes/DeforumSD.py +++ b/recipes/DeforumSD.py @@ -1,6 +1,7 @@ import typing import uuid +import pydantic from django.db.models import TextChoices from pydantic import BaseModel from typing_extensions import TypedDict @@ -198,7 +199,7 @@ class RequestModel(BaseModel): seed: int | None class ResponseModel(BaseModel): - output_video: str + output_video: pydantic.AnyHttpUrl def preview_image(self, state: dict) -> str | None: return DEFAULT_DEFORUMSD_META_IMG diff --git a/recipes/DocExtract.py b/recipes/DocExtract.py index e9eaad6ae..804e80b49 100644 --- a/recipes/DocExtract.py +++ b/recipes/DocExtract.py @@ -4,6 +4,7 @@ import threading import typing +import pydantic import requests from aifail import retry_if from django.db.models import IntegerChoices @@ -68,14 +69,14 @@ class DocExtractPage(BasePage): price = 500 class RequestModel(BaseModel): - documents: list[str] + documents: list[pydantic.AnyHttpUrl] - sheet_url: str | None + sheet_url: pydantic.AnyHttpUrl | None selected_asr_model: typing.Literal[tuple(e.name for e in AsrModels)] | None # language: str | None google_translate_target: str | None - glossary_document: str | None + glossary_document: pydantic.AnyHttpUrl | None task_instructions: str | None diff --git a/recipes/DocSummary.py b/recipes/DocSummary.py index 8955d5e59..59ba924fc 100644 --- a/recipes/DocSummary.py +++ b/recipes/DocSummary.py @@ -1,6 +1,7 @@ import typing from enum import Enum +import pydantic from pydantic import BaseModel import gooey_ui as st @@ -55,7 +56,7 @@ class DocSummaryPage(BasePage): } class RequestModel(BaseModel): - documents: list[str] + documents: list[pydantic.AnyHttpUrl] task_instructions: str | None merge_instructions: str | None diff --git a/recipes/EmailFaceInpainting.py b/recipes/EmailFaceInpainting.py index 385596f6d..de5532409 100644 --- a/recipes/EmailFaceInpainting.py +++ b/recipes/EmailFaceInpainting.py @@ -2,6 +2,7 @@ import typing import glom +import pydantic import requests from pydantic import BaseModel @@ -81,11 +82,11 @@ class Config: } class ResponseModel(BaseModel): - input_image: str - resized_image: str - face_mask: str - diffusion_images: list[str] - output_images: list[str] + input_image: pydantic.AnyHttpUrl + resized_image: pydantic.AnyHttpUrl + face_mask: pydantic.AnyHttpUrl + diffusion_images: list[pydantic.AnyHttpUrl] + output_images: list[pydantic.AnyHttpUrl] email_sent: bool = False @classmethod diff --git a/recipes/FaceInpainting.py b/recipes/FaceInpainting.py index 2f1b6a0b0..5cfc0ad85 100644 --- a/recipes/FaceInpainting.py +++ b/recipes/FaceInpainting.py @@ -1,6 +1,7 @@ import typing from functools import partial +import pydantic import requests from pydantic import BaseModel @@ -44,7 +45,7 @@ class FaceInpaintingPage(BasePage): } class RequestModel(BaseModel): - input_image: str + input_image: pydantic.AnyHttpUrl text_prompt: str face_scale: float | None @@ -75,10 +76,10 @@ class Config: } class ResponseModel(BaseModel): - resized_image: str - face_mask: str - diffusion_images: list[str] - output_images: list[str] + resized_image: pydantic.AnyHttpUrl + face_mask: pydantic.AnyHttpUrl + diffusion_images: list[pydantic.AnyHttpUrl] + output_images: list[pydantic.AnyHttpUrl] def preview_image(self, state: dict) -> str | None: return DEFAULT_FACE_INPAINTING_META_IMG diff --git a/recipes/ImageSegmentation.py b/recipes/ImageSegmentation.py index c247fdeda..ff2bbd42a 100644 --- a/recipes/ImageSegmentation.py +++ b/recipes/ImageSegmentation.py @@ -3,6 +3,7 @@ import PIL import numpy as np +import pydantic import requests import gooey_ui as st from pydantic import BaseModel @@ -47,7 +48,7 @@ class ImageSegmentationPage(BasePage): } class RequestModel(BaseModel): - input_image: str + input_image: pydantic.AnyHttpUrl selected_model: ( typing.Literal[tuple(e.name for e in ImageSegmentationModels)] | None @@ -62,10 +63,10 @@ class RequestModel(BaseModel): obj_pos_y: float | None class ResponseModel(BaseModel): - output_image: str - cutout_image: str - resized_image: str - resized_mask: str + output_image: pydantic.AnyHttpUrl + cutout_image: pydantic.AnyHttpUrl + resized_image: pydantic.AnyHttpUrl + resized_mask: pydantic.AnyHttpUrl def preview_image(self, state: dict) -> str | None: return DEFAULT_IMG_SEGMENTATION_META_IMG diff --git a/recipes/Img2Img.py b/recipes/Img2Img.py index 41a1139e4..e9bda756d 100644 --- a/recipes/Img2Img.py +++ b/recipes/Img2Img.py @@ -1,5 +1,6 @@ import typing +import pydantic import requests from pydantic import BaseModel @@ -42,7 +43,7 @@ class Img2ImgPage(BasePage): } class RequestModel(BaseModel): - input_image: str + input_image: pydantic.AnyHttpUrl text_prompt: str | None selected_model: typing.Literal[tuple(e.name for e in Img2ImgModels)] | None @@ -70,7 +71,7 @@ class RequestModel(BaseModel): image_guidance_scale: float | None class ResponseModel(BaseModel): - output_images: list[str] + output_images: list[pydantic.AnyHttpUrl] @classmethod def get_example_preferred_fields(self, state: dict) -> list[str]: diff --git a/recipes/Lipsync.py b/recipes/Lipsync.py index c2ac64369..11d010e51 100644 --- a/recipes/Lipsync.py +++ b/recipes/Lipsync.py @@ -1,6 +1,8 @@ import typing from pathlib import Path import urllib.request + +import pydantic import requests from pydantic import BaseModel @@ -25,8 +27,8 @@ class LipsyncPage(BasePage): slug_versions = ["Lipsync"] class RequestModel(BaseModel): - input_face: str - input_audio: str + input_face: pydantic.AnyHttpUrl + input_audio: pydantic.AnyHttpUrl face_padding_top: int | None face_padding_bottom: int | None @@ -34,7 +36,7 @@ class RequestModel(BaseModel): face_padding_right: int | None class ResponseModel(BaseModel): - output_video: str + output_video: pydantic.AnyHttpUrl def preview_image(self, state: dict) -> str | None: return DEFAULT_LIPSYNC_META_IMG diff --git a/recipes/LipsyncTTS.py b/recipes/LipsyncTTS.py index 1fc0f6c64..b5beec999 100644 --- a/recipes/LipsyncTTS.py +++ b/recipes/LipsyncTTS.py @@ -1,5 +1,6 @@ import typing +import pydantic from pydantic import BaseModel import gooey_ui as st @@ -26,8 +27,8 @@ class LipsyncTTSPage(LipsyncPage, TextToSpeechPage): } class RequestModel(BaseModel): - input_face: str - input_audio: str | None + input_face: pydantic.AnyHttpUrl + input_audio: pydantic.AnyHttpUrl | None face_padding_top: int | None face_padding_bottom: int | None @@ -57,7 +58,7 @@ class RequestModel(BaseModel): elevenlabs_speaker_boost: bool | None class ResponseModel(BaseModel): - output_video: str + output_video: pydantic.AnyHttpUrl def related_workflows(self) -> list: from recipes.VideoBots import VideoBotsPage diff --git a/recipes/ObjectInpainting.py b/recipes/ObjectInpainting.py index db12760bf..c1eac6fe7 100644 --- a/recipes/ObjectInpainting.py +++ b/recipes/ObjectInpainting.py @@ -1,5 +1,6 @@ import typing +import pydantic import requests from pydantic import BaseModel @@ -45,7 +46,7 @@ class ObjectInpaintingPage(BasePage): } class RequestModel(BaseModel): - input_image: str + input_image: pydantic.AnyHttpUrl text_prompt: str obj_scale: float | None @@ -71,10 +72,10 @@ class RequestModel(BaseModel): seed: int | None class ResponseModel(BaseModel): - resized_image: str - obj_mask: str - # diffusion_images: list[str] - output_images: list[str] + resized_image: pydantic.AnyHttpUrl + obj_mask: pydantic.AnyHttpUrl + # diffusion_images: list[pydantic.AnyHttpUrl] + output_images: list[pydantic.AnyHttpUrl] def preview_image(self, state: dict) -> str | None: return DEFAULT_OBJECT_INPAINTING_META_IMG diff --git a/recipes/QRCodeGenerator.py b/recipes/QRCodeGenerator.py index 2e3a30002..32fe36ea5 100644 --- a/recipes/QRCodeGenerator.py +++ b/recipes/QRCodeGenerator.py @@ -2,6 +2,7 @@ from enum import Enum import numpy as np +import pydantic import qrcode import requests from django.core.exceptions import ValidationError @@ -79,9 +80,9 @@ def __init__(self, *args, **kwargs): class RequestModel(BaseModel): qr_code_data: str | None - qr_code_input_image: str | None + qr_code_input_image: pydantic.AnyHttpUrl | None qr_code_vcard: VCARD | None - qr_code_file: str | None + qr_code_file: pydantic.AnyHttpUrl | None use_url_shortener: bool | None @@ -118,10 +119,10 @@ class RequestModel(BaseModel): obj_pos_y: float | None class ResponseModel(BaseModel): - output_images: list[str] - raw_images: list[str] - shortened_url: str | None - cleaned_qr_code: str + output_images: list[pydantic.AnyHttpUrl] + raw_images: list[pydantic.AnyHttpUrl] + shortened_url: pydantic.AnyHttpUrl | None + cleaned_qr_code: pydantic.AnyHttpUrl def preview_image(self, state: dict) -> str | None: if len(state.get("output_images") or []) > 0: diff --git a/recipes/Text2Audio.py b/recipes/Text2Audio.py index f7ddf5aab..83399f636 100644 --- a/recipes/Text2Audio.py +++ b/recipes/Text2Audio.py @@ -1,6 +1,7 @@ import typing from enum import Enum +import pydantic from pydantic import BaseModel import gooey_ui as st @@ -55,7 +56,8 @@ class RequestModel(BaseModel): class ResponseModel(BaseModel): output_audios: dict[ - typing.Literal[tuple(e.name for e in Text2AudioModels)], list[str] + typing.Literal[tuple(e.name for e in Text2AudioModels)], + list[pydantic.AnyHttpUrl], ] def preview_image(self, state: dict) -> str | None: diff --git a/recipes/TextToSpeech.py b/recipes/TextToSpeech.py index 7d8f301fe..7be2ae717 100644 --- a/recipes/TextToSpeech.py +++ b/recipes/TextToSpeech.py @@ -3,6 +3,7 @@ import time import typing +import pydantic import requests import gooey_ui as st from google.cloud import texttospeech @@ -76,7 +77,7 @@ class RequestModel(BaseModel): elevenlabs_speaker_boost: bool | None class ResponseModel(BaseModel): - audio_url: str + audio_url: pydantic.AnyHttpUrl def fallback_preivew_image(self) -> str | None: return DEFAULT_TTS_META_IMG diff --git a/recipes/VideoBots.py b/recipes/VideoBots.py index 502f6e552..c3dd9489d 100644 --- a/recipes/VideoBots.py +++ b/recipes/VideoBots.py @@ -4,6 +4,7 @@ import os.path import typing +import pydantic from django.db.models import QuerySet, Q from furl import furl from pydantic import BaseModel, Field @@ -157,8 +158,8 @@ class RequestModel(BaseModel): bot_script: str | None input_prompt: str - input_images: list[str] | None - input_documents: list[str] | None + input_images: list[pydantic.AnyHttpUrl] | None + input_documents: list[pydantic.AnyHttpUrl] | None # conversation history/context messages: list[ConversationEntry] | None @@ -196,7 +197,7 @@ class RequestModel(BaseModel): sampling_temperature: float | None # lipsync - input_face: str | None + input_face: pydantic.AnyHttpUrl | None face_padding_top: int | None face_padding_bottom: int | None face_padding_left: int | None @@ -206,7 +207,7 @@ class RequestModel(BaseModel): task_instructions: str | None query_instructions: str | None keyword_instructions: str | None - documents: list[str] | None + documents: list[pydantic.AnyHttpUrl] | None max_references: int | None max_context_words: int | None scroll_jump: int | None @@ -222,13 +223,13 @@ class RequestModel(BaseModel): description="If provided, the copilot will translate user messages to English and the copilot's response back to the selected language.", ) # llm_language: str | None = "en" <-- implicit since this is hardcoded everywhere in the code base (from facebook and bots to slack and copilot etc.) - input_glossary_document: str | None = Field( + input_glossary_document: pydantic.AnyHttpUrl | None = Field( title="Input Glossary", description=""" Translation Glossary for User Langauge -> LLM Language (English) """, ) - output_glossary_document: str | None = Field( + output_glossary_document: pydantic.AnyHttpUrl | None = Field( title="Output Glossary", description=""" Translation Glossary for LLM Language (English) -> User Langauge @@ -248,10 +249,10 @@ class ResponseModel(BaseModel): output_text: list[str] # tts - output_audio: list[str] + output_audio: list[pydantic.AnyHttpUrl] # lipsync - output_video: list[str] + output_video: list[pydantic.AnyHttpUrl] # intermediate text raw_input_text: str | None @@ -264,7 +265,7 @@ class ResponseModel(BaseModel): final_keyword_query: str | list[str] | None # function calls - output_documents: list[str] | None + output_documents: list[pydantic.AnyHttpUrl] | None reply_buttons: list[ReplyButton] | None def preview_image(self, state: dict) -> str | None: diff --git a/recipes/asr.py b/recipes/asr.py index 3542614c8..898fd1bb2 100644 --- a/recipes/asr.py +++ b/recipes/asr.py @@ -1,5 +1,6 @@ import typing +import pydantic from jinja2.lexer import whitespace_re from pydantic import BaseModel @@ -37,11 +38,11 @@ class AsrPage(BasePage): sane_defaults = dict(output_format=AsrOutputFormat.text.name) class RequestModel(BaseModel): - documents: list[str] + documents: list[pydantic.AnyHttpUrl] selected_model: typing.Literal[tuple(e.name for e in AsrModels)] | None language: str | None google_translate_target: str | None - glossary_document: str | None + glossary_document: pydantic.AnyHttpUrl | None output_format: typing.Literal[tuple(e.name for e in AsrOutputFormat)] | None class ResponseModel(BaseModel):