ovedrive commited on
Commit
fc21604
·
1 Parent(s): 879971e

working system

Browse files
Files changed (5) hide show
  1. Project.md +10 -0
  2. api.py +22 -10
  3. api_example.py +39 -13
  4. app.py +13 -11
  5. config.py +9 -2
Project.md CHANGED
@@ -9,6 +9,7 @@ A Python application that uses Hugging Face inference endpoints for text-to-imag
9
  - Gradio UI for interactive use
10
  - API endpoints for integration with other applications
11
  - Configurable models via text input
 
12
 
13
  ## Project Structure
14
 
@@ -37,6 +38,15 @@ A Python application that uses Hugging Face inference endpoints for text-to-imag
37
  - `POST /text-to-image` - Generate an image from text
38
  - `POST /image-to-image` - Transform an image with optional prompt
39
 
 
 
 
 
 
 
 
 
 
40
  ## Environment Variables
41
 
42
  - `HF_TOKEN` - Your Hugging Face API token
 
9
  - Gradio UI for interactive use
10
  - API endpoints for integration with other applications
11
  - Configurable models via text input
12
+ - Default values for prompts, negative prompts, and models
13
 
14
  ## Project Structure
15
 
 
38
  - `POST /text-to-image` - Generate an image from text
39
  - `POST /image-to-image` - Transform an image with optional prompt
40
 
41
+ ## Default Values
42
+
43
+ The application includes defaults for:
44
+ - Sample prompts for text-to-image and image-to-image
45
+ - Negative prompts to exclude unwanted elements
46
+ - Pre-filled model names for both text-to-image and image-to-image
47
+
48
+ These defaults are applied to both the Gradio UI and API endpoints for consistency.
49
+
50
  ## Environment Variables
51
 
52
  - `HF_TOKEN` - Your Hugging Face API token
api.py CHANGED
@@ -17,9 +17,9 @@ async def root():
17
 
18
  @app.post("/text-to-image")
19
  async def text_to_image(
20
- prompt: str = Form(...),
21
- model: str = Form(None),
22
- negative_prompt: str = Form(None),
23
  guidance_scale: float = Form(7.5),
24
  num_inference_steps: int = Form(50)
25
  ):
@@ -27,10 +27,14 @@ async def text_to_image(
27
  Generate an image from a text prompt
28
  """
29
  try:
30
- # Use default model if not specified
31
- if not model:
32
  model = config.DEFAULT_TEXT2IMG_MODEL
33
 
 
 
 
 
34
  # Call the inference module
35
  image = inference.text_to_image(
36
  prompt=prompt,
@@ -52,9 +56,9 @@ async def text_to_image(
52
  @app.post("/image-to-image")
53
  async def image_to_image(
54
  image: UploadFile = File(...),
55
- prompt: str = Form(None),
56
- model: str = Form(None),
57
- negative_prompt: str = Form(None),
58
  guidance_scale: float = Form(7.5),
59
  num_inference_steps: int = Form(50)
60
  ):
@@ -66,10 +70,18 @@ async def image_to_image(
66
  contents = await image.read()
67
  input_image = Image.open(io.BytesIO(contents))
68
 
69
- # Use default model if not specified
70
- if not model:
71
  model = config.DEFAULT_IMG2IMG_MODEL
72
 
 
 
 
 
 
 
 
 
73
  # Call the inference module
74
  result = inference.image_to_image(
75
  image=input_image,
 
17
 
18
  @app.post("/text-to-image")
19
  async def text_to_image(
20
+ prompt: str = Form(config.DEFAULT_TEXT2IMG_PROMPT),
21
+ model: str = Form(config.DEFAULT_TEXT2IMG_MODEL),
22
+ negative_prompt: str = Form(config.DEFAULT_NEGATIVE_PROMPT),
23
  guidance_scale: float = Form(7.5),
24
  num_inference_steps: int = Form(50)
25
  ):
 
27
  Generate an image from a text prompt
28
  """
29
  try:
30
+ # Use default model if not specified or empty
31
+ if not model or model.strip() == '':
32
  model = config.DEFAULT_TEXT2IMG_MODEL
33
 
34
+ # Use default negative prompt if not specified or empty
35
+ if not negative_prompt or negative_prompt.strip() == '':
36
+ negative_prompt = config.DEFAULT_NEGATIVE_PROMPT
37
+
38
  # Call the inference module
39
  image = inference.text_to_image(
40
  prompt=prompt,
 
56
  @app.post("/image-to-image")
57
  async def image_to_image(
58
  image: UploadFile = File(...),
59
+ prompt: str = Form(config.DEFAULT_IMG2IMG_PROMPT),
60
+ model: str = Form(config.DEFAULT_IMG2IMG_MODEL),
61
+ negative_prompt: str = Form(config.DEFAULT_NEGATIVE_PROMPT),
62
  guidance_scale: float = Form(7.5),
63
  num_inference_steps: int = Form(50)
64
  ):
 
70
  contents = await image.read()
71
  input_image = Image.open(io.BytesIO(contents))
72
 
73
+ # Use default model if not specified or empty
74
+ if not model or model.strip() == '':
75
  model = config.DEFAULT_IMG2IMG_MODEL
76
 
77
+ # Use default prompt if not specified or empty
78
+ if not prompt or prompt.strip() == '':
79
+ prompt = config.DEFAULT_IMG2IMG_PROMPT
80
+
81
+ # Use default negative prompt if not specified or empty
82
+ if not negative_prompt or negative_prompt.strip() == '':
83
+ negative_prompt = config.DEFAULT_NEGATIVE_PROMPT
84
+
85
  # Call the inference module
86
  result = inference.image_to_image(
87
  image=input_image,
api_example.py CHANGED
@@ -13,22 +13,31 @@ HF_TOKEN = os.getenv("HF_TOKEN")
13
  # API base URL
14
  API_BASE = "http://localhost:8000"
15
 
16
- def text_to_image(prompt, model=None, negative_prompt=None):
17
  """
18
  Generate image from text using the API
 
19
  """
20
  url = f"{API_BASE}/text-to-image"
21
 
22
- # Prepare form data
23
- data = {
24
- "prompt": prompt,
25
- }
 
 
26
 
27
- if model:
28
  data["model"] = model
29
 
30
- if negative_prompt:
31
  data["negative_prompt"] = negative_prompt
 
 
 
 
 
 
32
 
33
  # Make API request
34
  response = requests.post(url, data=data)
@@ -42,20 +51,33 @@ def text_to_image(prompt, model=None, negative_prompt=None):
42
  print(response.text)
43
  return None
44
 
45
- def image_to_image(image_path, prompt=None, model=None):
 
46
  """
47
  Transform image using the API
 
48
  """
49
  url = f"{API_BASE}/image-to-image"
50
 
51
- # Prepare form data and files
52
  data = {}
53
- if prompt:
 
54
  data["prompt"] = prompt
55
 
56
- if model:
57
  data["model"] = model
 
 
 
 
 
 
 
 
 
58
 
 
59
  files = {
60
  "image": open(image_path, "rb")
61
  }
@@ -75,14 +97,18 @@ def image_to_image(image_path, prompt=None, model=None):
75
  if __name__ == "__main__":
76
  # Example usage
77
  print("Text to Image example:")
78
- image = text_to_image("A beautiful mountain landscape at sunset")
 
79
  if image:
80
  image.save("text2img_output.png")
81
  print("Image saved as text2img_output.png")
82
 
 
 
 
83
  print("Image to Image example (requires an input image):")
84
  # Uncomment and modify path to run:
85
- # result = image_to_image("input.png", "Turn this into a fantasy scene")
86
  # if result:
87
  # result.save("img2img_output.png")
88
  # print("Image saved as img2img_output.png")
 
13
  # API base URL
14
  API_BASE = "http://localhost:8000"
15
 
16
+ def text_to_image(prompt=None, model=None, negative_prompt=None, guidance_scale=None, num_inference_steps=None):
17
  """
18
  Generate image from text using the API
19
+ All parameters are optional and will use server defaults if not provided
20
  """
21
  url = f"{API_BASE}/text-to-image"
22
 
23
+ # Prepare form data - only add parameters that are provided
24
+ # (otherwise use server defaults)
25
+ data = {}
26
+
27
+ if prompt is not None:
28
+ data["prompt"] = prompt
29
 
30
+ if model is not None:
31
  data["model"] = model
32
 
33
+ if negative_prompt is not None:
34
  data["negative_prompt"] = negative_prompt
35
+
36
+ if guidance_scale is not None:
37
+ data["guidance_scale"] = guidance_scale
38
+
39
+ if num_inference_steps is not None:
40
+ data["num_inference_steps"] = num_inference_steps
41
 
42
  # Make API request
43
  response = requests.post(url, data=data)
 
51
  print(response.text)
52
  return None
53
 
54
+ def image_to_image(image_path, prompt=None, model=None, negative_prompt=None,
55
+ guidance_scale=None, num_inference_steps=None):
56
  """
57
  Transform image using the API
58
+ Only image_path is required, other parameters are optional and will use server defaults
59
  """
60
  url = f"{API_BASE}/image-to-image"
61
 
62
+ # Prepare form data - only add parameters that are provided
63
  data = {}
64
+
65
+ if prompt is not None:
66
  data["prompt"] = prompt
67
 
68
+ if model is not None:
69
  data["model"] = model
70
+
71
+ if negative_prompt is not None:
72
+ data["negative_prompt"] = negative_prompt
73
+
74
+ if guidance_scale is not None:
75
+ data["guidance_scale"] = guidance_scale
76
+
77
+ if num_inference_steps is not None:
78
+ data["num_inference_steps"] = num_inference_steps
79
 
80
+ # Prepare the image file
81
  files = {
82
  "image": open(image_path, "rb")
83
  }
 
97
  if __name__ == "__main__":
98
  # Example usage
99
  print("Text to Image example:")
100
+ # Can call without arguments to use server defaults
101
+ image = text_to_image()
102
  if image:
103
  image.save("text2img_output.png")
104
  print("Image saved as text2img_output.png")
105
 
106
+ # Or with specific parameters
107
+ # image = text_to_image("A beautiful mountain landscape at sunset")
108
+
109
  print("Image to Image example (requires an input image):")
110
  # Uncomment and modify path to run:
111
+ # result = image_to_image("input.png") # Uses default prompt
112
  # if result:
113
  # result.save("img2img_output.png")
114
  # print("Image saved as img2img_output.png")
app.py CHANGED
@@ -12,7 +12,8 @@ def text_to_image_fn(prompt, model, negative_prompt=None, guidance_scale=7.5, nu
12
  Handle text to image generation request
13
  """
14
  try:
15
- if not model:
 
16
  model = config.DEFAULT_TEXT2IMG_MODEL
17
 
18
  # Call the inference module
@@ -40,12 +41,13 @@ def image_to_image_fn(image, prompt, model, negative_prompt=None, guidance_scale
40
  if image is None:
41
  return None, "No input image provided."
42
 
43
- if not model:
 
44
  model = config.DEFAULT_IMG2IMG_MODEL
45
 
46
- # Handle empty prompt
47
- if prompt == "":
48
- prompt = None
49
 
50
  try:
51
  # Call the inference module with explicit parameters
@@ -77,9 +79,9 @@ with gr.Blocks(title="Diffusion Models") as app:
77
  with gr.Tab("Text to Image"):
78
  with gr.Row():
79
  with gr.Column():
80
- txt2img_prompt = gr.Textbox(label="Prompt", placeholder="Enter your prompt here...")
81
- txt2img_negative = gr.Textbox(label="Negative Prompt (Optional)", placeholder="What to exclude from the image")
82
- txt2img_model = gr.Textbox(label="Model", placeholder=f"Enter model name (default: {config.DEFAULT_TEXT2IMG_MODEL})")
83
  txt2img_guidance = gr.Slider(minimum=1.0, maximum=20.0, value=7.5, step=0.5, label="Guidance Scale")
84
  txt2img_steps = gr.Slider(minimum=10, maximum=100, value=50, step=1, label="Inference Steps")
85
  txt2img_button = gr.Button("Generate Image")
@@ -98,9 +100,9 @@ with gr.Blocks(title="Diffusion Models") as app:
98
  with gr.Row():
99
  with gr.Column():
100
  img2img_input = gr.Image(type="pil", label="Input Image")
101
- img2img_prompt = gr.Textbox(label="Prompt", placeholder="Enter your prompt here...")
102
- img2img_negative = gr.Textbox(label="Negative Prompt (Optional)", placeholder="What to exclude from the image")
103
- img2img_model = gr.Textbox(label="Model", placeholder=f"Enter model name (default: {config.DEFAULT_IMG2IMG_MODEL})")
104
  img2img_guidance = gr.Slider(minimum=1.0, maximum=20.0, value=7.5, step=0.5, label="Guidance Scale")
105
  img2img_steps = gr.Slider(minimum=10, maximum=100, value=50, step=1, label="Inference Steps")
106
  img2img_button = gr.Button("Transform Image")
 
12
  Handle text to image generation request
13
  """
14
  try:
15
+ # Model validation - fallback to default if empty
16
+ if not model or model.strip() == '':
17
  model = config.DEFAULT_TEXT2IMG_MODEL
18
 
19
  # Call the inference module
 
41
  if image is None:
42
  return None, "No input image provided."
43
 
44
+ # Model validation - fallback to default if empty
45
+ if not model or model.strip() == '':
46
  model = config.DEFAULT_IMG2IMG_MODEL
47
 
48
+ # Handle empty prompt - use default if completely empty
49
+ if prompt is None or prompt.strip() == "":
50
+ prompt = config.DEFAULT_IMG2IMG_PROMPT
51
 
52
  try:
53
  # Call the inference module with explicit parameters
 
79
  with gr.Tab("Text to Image"):
80
  with gr.Row():
81
  with gr.Column():
82
+ txt2img_prompt = gr.Textbox(label="Prompt", placeholder="Enter your prompt here...", value=config.DEFAULT_TEXT2IMG_PROMPT)
83
+ txt2img_negative = gr.Textbox(label="Negative Prompt (Optional)", placeholder="What to exclude from the image", value=config.DEFAULT_NEGATIVE_PROMPT)
84
+ txt2img_model = gr.Textbox(label="Model", placeholder=f"Enter model name", value=config.DEFAULT_TEXT2IMG_MODEL)
85
  txt2img_guidance = gr.Slider(minimum=1.0, maximum=20.0, value=7.5, step=0.5, label="Guidance Scale")
86
  txt2img_steps = gr.Slider(minimum=10, maximum=100, value=50, step=1, label="Inference Steps")
87
  txt2img_button = gr.Button("Generate Image")
 
100
  with gr.Row():
101
  with gr.Column():
102
  img2img_input = gr.Image(type="pil", label="Input Image")
103
+ img2img_prompt = gr.Textbox(label="Prompt", placeholder="Enter your prompt here...", value=config.DEFAULT_IMG2IMG_PROMPT)
104
+ img2img_negative = gr.Textbox(label="Negative Prompt (Optional)", placeholder="What to exclude from the image", value=config.DEFAULT_NEGATIVE_PROMPT)
105
+ img2img_model = gr.Textbox(label="Model", placeholder=f"Enter model name", value=config.DEFAULT_IMG2IMG_MODEL)
106
  img2img_guidance = gr.Slider(minimum=1.0, maximum=20.0, value=7.5, step=0.5, label="Guidance Scale")
107
  img2img_steps = gr.Slider(minimum=10, maximum=100, value=50, step=1, label="Inference Steps")
108
  img2img_button = gr.Button("Transform Image")
config.py CHANGED
@@ -8,10 +8,17 @@ load_dotenv()
8
  HF_TOKEN = os.getenv("HF_TOKEN", "")
9
 
10
  # Default model for text to image
11
- DEFAULT_TEXT2IMG_MODEL = "stabilityai/stable-diffusion-2-1"
12
 
13
  # Default model for image to image
14
- DEFAULT_IMG2IMG_MODEL = "lllyasviel/sd-controlnet-depth"
 
 
 
 
 
 
 
15
 
16
  # API settings
17
  API_HOST = os.getenv("API_HOST", "0.0.0.0")
 
8
  HF_TOKEN = os.getenv("HF_TOKEN", "")
9
 
10
  # Default model for text to image
11
+ DEFAULT_TEXT2IMG_MODEL = "stabilityai/stable-diffusion-3-medium-diffusers"
12
 
13
  # Default model for image to image
14
+ DEFAULT_IMG2IMG_MODEL = "stabilityai/stable-diffusion-xl-refiner-1.0"
15
+
16
+ # Default prompts - used as placeholders in UI and defaults in API
17
+ DEFAULT_TEXT2IMG_PROMPT = "A beautiful landscape with mountains and a lake"
18
+ DEFAULT_IMG2IMG_PROMPT = "Transform this image with fantasy elements"
19
+
20
+ # Default negative prompts - used to improve image quality by avoiding common issues
21
+ DEFAULT_NEGATIVE_PROMPT = "blurry, low quality, distorted, deformed, ugly, pixelated, noise, grain, text, watermark, poor composition, bad proportions, disfigured, mutation, mutated, extra limbs, extra fingers, fused fingers, malformed hands, poorly drawn face, bad anatomy, amateur drawing, low resolution, duplicate, cropped, out of frame, worst quality, jpeg artifacts, compression artifacts, glitch, overexposed, underexposed, low contrast, washed out colors, oversaturated, signature, username, artist name, logo, unnatural lighting, uneven lighting, harsh shadows, motion blur, out of focus, chromatic aberration, film grain, scratches, stains, dark spots, light leaks, fuzzy edges, jagged edges, broken lines, stretched image, elongated features, asymmetrical eyes, misaligned features, missing details, incomplete rendering"
22
 
23
  # API settings
24
  API_HOST = os.getenv("API_HOST", "0.0.0.0")