getimg_client 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1028c687dea86e569bd237794d0a391db97d4079d7bbcdaa564eb5aff5fc1bc0
4
- data.tar.gz: eac3cb2255aadf16b2c271aa3515201fd2a4bd55b5605ed276ebaac6e1252d92
3
+ metadata.gz: 49df7df20de9d97f5bc96e06eb517c007f55101e61b56c6d33d4878687f13249
4
+ data.tar.gz: 4dc36a54730384489acb5068e24e55fd272186f1c6cafb610272f05b777e522c
5
5
  SHA512:
6
- metadata.gz: 015ba46c1a34e85ceb8bc42727ffcc0abc99a596167fdc33d9adc1bd10b79502bf3831be68f31344025db72cb9ff0f08b8d836834582bb0f77cfb5f906d04f72
7
- data.tar.gz: 76b468d1a099a92316f25cd531189348381572841f5ab82ea96acd19a2c226488b3335fda0a52ca4e5ded3f34b6ad253741b57a6e2028c75c5d4c0053e09c44b
6
+ metadata.gz: c2a3a252131ecfca467e4ca97704a6d1d86d3ac4d0f8840a9f18c03a2686b5bdff4322ddf09e697d6cc765e5cd743579580c6be70c2b6a6a0df0c1c51aa9781d
7
+ data.tar.gz: 586153f30ac2646900cd7e0ad87d531ec1151ea53c5a7dd3271f0120774531f1df2f6ad1ee608a47ab8020a9e223ed42171932a0e66f3845725dfff1e790271e
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # GetimgClient
1
+ # GetimgClient [![Gem Version](https://badge.fury.io/rb/getimg_client.svg)](https://badge.fury.io/rb/getimg_client)
2
2
 
3
3
  ## Introduction
4
4
  GetimgClient is a Ruby gem designed to interact with the Getimg.ai API, enabling users to generate, manipulate, and enhance images using various AI models. This gem simplifies the process of making API requests to Getimg.ai, allowing for seamless integration of image generation and manipulation capabilities into your Ruby applications.
@@ -46,14 +46,14 @@ Fetch and cache the list of available models from the API.
46
46
  ### `models`
47
47
  Retrieve cached models or fetch them if not already retrieved.
48
48
 
49
- ### `generate_image(prompt, model:, **options)`
50
- Generate an image based on a text prompt and specified model. Supports various image manipulation methods such as image-to-image, inpainting, controlnet, face fixing, instruct and upscaling.
49
+ ### `generate_image(prompt, model: :essential, **options)`
50
+ Generate an image based on a text prompt and specified model. Supports various image manipulation methods such as image-to-image, inpainting, controlnet, face fixing, instruct, and upscaling. Specifying a model is optional; by default, it will invoke the Essential V1 endpoint.
51
51
 
52
52
  ### `get_balance`
53
53
  Retrieve the current account balance from the Getimg.ai API.
54
54
 
55
55
  ## Request Routing
56
- The `generate_image` method routes requests based on the provided options and the model's supported pipelines, sending it to its respective pipeline whether that's SD1.5, SDXL or LCM based:
56
+ The `generate_image` method routes requests based on the provided options and the model's supported pipelines, sending it to its respective pipeline whether that's SD1.5, SDXL, Essential, or LCM based:
57
57
  - **text-to-image**: Default if no images are provided.
58
58
  - **image-to-image**: Triggered if a base image is provided.
59
59
  - **inpaint**: Triggered if a mask image is provided.
@@ -82,8 +82,12 @@ If an HTTP error occurs, the error message will include both the HTTP status and
82
82
  ## Models
83
83
  The provided `model` option will determine the model use, and contribute to the client's inference of the desired endpoint. Models can be the string `id` listed online at [the GetImg dashboard](https://dashboard.getimg.ai/models) or retrieved using the `GetimgClient.models` method. Equally, you can use symbols instead. For example, `:realistic_vision_v5_1` will translate to `'realistic-vision-v5-1'`
84
84
 
85
+ ## Essential
86
+ Getimg offers the "essential" checkpoints, which perform more abstract Stable Diffusion operations based on the provided prompt. Note that *:essential* and *:essential_v2* will *not* be listed in the model listing, as these are not in fact actual models, nor valid "model" values at the API's end.
87
+ In order to route a request to Essential or Essential V2 however, you can provide *:essential* or *:essential_v2* as a model argument in *#generate_image*.
88
+
85
89
  ## Latent Consistency Models (LCM)
86
- Latent consistency models are designed to speed up image generation by circumventing the iterative generation process of diffusion-based methods. Building on direct consistency models that operate on image pixels, latent consistency models operate in the latent (lower-dimensional) space. The client will automatically route requests to these models as needed.
90
+ Latent Consistency Models (LCM) are optimized for faster image generation and lower costs by avoiding the repetitive steps of traditional diffusion methods. They work in a lower-dimensional space, resulting in quicker outputs but with slightly less detail compared to standard models.
87
91
 
88
92
  ## Base Image Options
89
93
  The `base_image` option can be provided, which will automatically set the "image" property for image-to-image, controlnet, face-fix, upscale, inpaint and instruct calls, and can be either a file path or a base64 encoded string of the file contents.
@@ -98,7 +102,13 @@ If all went well and no errors were reported, the response will be equal to the
98
102
  GetimgClient.set_api_key('your_api_key')
99
103
  ```
100
104
 
101
- ### Generate Text-to-Image
105
+ ### Generate Text-to-Image using Essential V1 with default options
106
+ ```ruby
107
+ result = GetimgClient.generate_image("A city skyline at night")
108
+ puts result["image"]
109
+ ```
110
+
111
+ ### Generate Text-to-Image using Stable Diffusion 1.5
102
112
  ```ruby
103
113
  result = GetimgClient.generate_image("A scenic landscape", model: :stable_diffusion_v1_5, width: 512, height: 512)
104
114
  puts result["image"]
@@ -114,7 +124,7 @@ puts result["image"]
114
124
  ### Generate an image using Controlnet
115
125
  ```ruby
116
126
  base_image = "path/to/base_image.jpg"
117
- result = GetimgClient.generate_image("Enhance the scene", model: :stable_diffusion_v1_5, base_image:, strength: 0.7, controlnet: canny-1.1)
127
+ result = GetimgClient.generate_image("Enhance the scene", model: :stable_diffusion_v1_5, base_image:, strength: 0.7, controlnet: 'canny-1.1')
118
128
  puts result["image"]
119
129
  ```
120
130
 
@@ -148,7 +158,21 @@ puts result["image"]
148
158
  ```
149
159
 
150
160
  ## Logging
151
- Request logging will automatically be enabled, if the **RAILS_ENV** environment variable is set to "development"
161
+ GetimgClient supports logging request details for debugging and development purposes. The logging behavior depends on the environment and configuration:
162
+
163
+ Rails Development Environment: If the **RAILS_ENV** environment variable is set to "development" and Rails is defined, logs will be sent to the Rails logger.
164
+
165
+ **GETIMG_LOG** Environment Variable: If the GETIMG_LOG environment variable is set, logs will be printed to the standard output.
166
+
167
+ #### Log output example
168
+ ```text
169
+ Generating image with the following details:
170
+ Prompt: A scenic landscape
171
+ Model: stable-diffusion-v1-5
172
+ Requested Pipeline: text-to-image
173
+ Endpoint URI: https://api.getimg.ai/v1/stable-diffusion/text-to-image
174
+ Options: {width: 512, height: 512}
175
+ ```
152
176
 
153
177
  ## Unit Testing
154
178
  The gem includes unit tests using Minitest. Integration tests make real API calls and will incur usage fees. Ensure your API key is set in the environment before running tests.
data/lib/endpoints.json CHANGED
@@ -10,6 +10,7 @@
10
10
  "lcm_text_to_image": "https://api.getimg.ai/v1/latent-consistency/text-to-image",
11
11
  "lcm_image_to_image": "https://api.getimg.ai/v1/latent-consistency/image-to-image",
12
12
  "essential_text_to_image": "https://api.getimg.ai/v1/essential/text-to-image",
13
+ "essentialv2_text_to_image": "https://api.getimg.ai/v1/essential-v2/text-to-image",
13
14
  "face_fix": "https://api.getimg.ai/v1/enhancements/face-fix",
14
15
  "upscale": "https://api.getimg.ai/v1/enhancements/upscale",
15
16
  "models": "https://api.getimg.ai/v1/models",
data/lib/getimg_client.rb CHANGED
@@ -32,7 +32,7 @@ class GetimgClient
32
32
  end
33
33
 
34
34
  # Generate an image based on the prompt and model
35
- def self.generate_image(prompt, model:, **options)
35
+ def self.generate_image(prompt, model: :essential, **options)
36
36
  # Validate the prompt
37
37
  raise ArgumentError, 'Prompt is required' unless prompt.is_a?(String) && !prompt.strip.empty?
38
38
 
@@ -43,7 +43,11 @@ class GetimgClient
43
43
 
44
44
  # Convert model to appropriate ID format
45
45
  model_id = model.to_s.gsub('_', '-')
46
- model_info = models[model_id] || raise(ArgumentError, "Unknown model: #{model}")
46
+ if %w[essential essential-v2].include?(model_id)
47
+ model_info = models[model_id] || { name: model_id, pipelines: ['text-to-image'] }
48
+ else
49
+ model_info = models[model_id] || raise(ArgumentError, "Unknown model: #{model}")
50
+ end
47
51
 
48
52
  # Determine the requested pipeline
49
53
  requested_pipeline = method_requested(base_image, mask_image_path, controlnet, model_info).to_s.gsub('_', '-')
@@ -54,7 +58,7 @@ class GetimgClient
54
58
  end
55
59
 
56
60
  # Determine the endpoint key based on the model family and pipeline
57
- endpoint_key = determine_endpoint_key(model_info, requested_pipeline)
61
+ endpoint_key = determine_endpoint_key(model_info, requested_pipeline, model_id)
58
62
  uri = URI(API_ENDPOINTS[endpoint_key.to_s])
59
63
 
60
64
  # Handle image to image, controlnet, instruct, inpaint, face-fix, and upscale pipelines
@@ -71,16 +75,8 @@ class GetimgClient
71
75
  # Ensure scale is an integer if present
72
76
  options[:scale] = options[:scale].to_i if options[:scale]
73
77
 
74
- # Logging request details in development environment
75
- if ENV['RAILS_ENV'] == 'development'
76
- puts "Generating image with the following details:"
77
- puts "Prompt: #{prompt}"
78
- puts "Model: #{model_id}"
79
- puts "Requested Pipeline: #{requested_pipeline}"
80
- puts "Endpoint URI: #{uri}"
81
- truncated_options = options.transform_values { |v| v.is_a?(String) && v.length > 50 ? "#{v[0, 50]}..." : v }
82
- puts "Options: #{truncated_options}"
83
- end
78
+ # Log the request details
79
+ log_request_details(prompt, model_id, requested_pipeline, uri, options)
84
80
 
85
81
  # Create and send the request
86
82
  request = create_request(uri, prompt, model: model_id, **options)
@@ -101,6 +97,25 @@ class GetimgClient
101
97
 
102
98
  private
103
99
 
100
+ # Log request details
101
+ def self.log_request_details(prompt, model_id, requested_pipeline, uri, options)
102
+ log_message = <<~LOG
103
+ Generating image with the following details:
104
+ Prompt: #{prompt}
105
+ Model: #{model_id}
106
+ Requested Pipeline: #{requested_pipeline}
107
+ Endpoint URI: #{uri}
108
+ Options: #{options.transform_values { |v| v.is_a?(String) && v.length > 50 ? "#{v[0, 50]}..." : v }}
109
+ LOG
110
+
111
+ if ENV['RAILS_ENV'] === 'development' && defined?(Rails) && Rails.logger
112
+ Rails.logger.info(log_message)
113
+ end
114
+ if ENV['GETIMG_LOG']
115
+ puts log_message
116
+ end
117
+ end
118
+
104
119
  # Determine the requested method based on provided image paths, controlnet, and model_info
105
120
  def self.method_requested(base_image, mask_image_path, controlnet, model_info)
106
121
  return :controlnet if controlnet
@@ -113,8 +128,12 @@ class GetimgClient
113
128
  end
114
129
 
115
130
  # Determine the appropriate endpoint key based on the model family and pipeline
116
- def self.determine_endpoint_key(model_info, requested_pipeline)
117
- if model_info[:family] == 'stable-diffusion-xl'
131
+ def self.determine_endpoint_key(model_info, requested_pipeline, model_id)
132
+ if model_id == 'essential'
133
+ return :essential_text_to_image
134
+ elsif model_id == 'essential-v2'
135
+ return :essentialv2_text_to_image
136
+ elsif model_info[:family] == 'stable-diffusion-xl'
118
137
  return :sdxl_image_to_image if requested_pipeline == 'image-to-image'
119
138
  return :sdxl_inpaint if requested_pipeline == 'inpaint'
120
139
  return :sdxl_text_to_image
@@ -133,10 +152,8 @@ class GetimgClient
133
152
  request['accept'] = 'application/json'
134
153
  request['content-type'] = 'application/json'
135
154
 
136
- body = {
137
- prompt: prompt,
138
- model: model
139
- }.merge(options)
155
+ body = { prompt: prompt }.merge(options)
156
+ body[:model] = model unless %w[essential essential-v2].include?(model)
140
157
 
141
158
  request.body = body.to_json
142
159
  request
@@ -1,11 +1,10 @@
1
1
  require_relative "../test_helper"
2
+ require 'stringio'
2
3
 
3
4
  class GetimgClientIntegrationTest < Minitest::Test
4
5
  def setup
5
6
  @base_image = Base64.strict_encode64(File.read(File.join(__dir__, "sample_image.jpeg")))
6
-
7
7
  @small_image = Base64.strict_encode64(File.read(File.join(__dir__, "small_sample_image.jpeg")))
8
-
9
8
  @mask_image = Base64.strict_encode64(File.read(File.join(__dir__, "mask_image.jpeg")))
10
9
  end
11
10
 
@@ -58,6 +57,42 @@ class GetimgClientIntegrationTest < Minitest::Test
58
57
  save_image(result["image"], "test_upscale")
59
58
  end
60
59
 
60
+ def test_generate_text_to_image_essential
61
+ puts "-- Running test_generate_text_to_image_essential..."
62
+ result = GetimgClient.generate_image("A modern cityscape")
63
+ assert result["image"]
64
+ save_image(result["image"], "test_generate_text_to_image_essential")
65
+ end
66
+
67
+ def test_logging_to_rails_logger
68
+ skip "Rails not defined, skipping Rails logger test" unless defined?(Rails) && ENV['RAILS_ENV'] === 'development'
69
+
70
+ original_logger = Rails.logger
71
+ log_output = StringIO.new
72
+ Rails.logger = Logger.new(log_output)
73
+
74
+ GetimgClient.generate_image("A scenic landscape", model: :stable_diffusion_v1_5, width: 512, height: 512)
75
+
76
+ assert_includes log_output.string, "Generating image with the following details:"
77
+ assert_includes log_output.string, "Prompt: A scenic landscape"
78
+
79
+ Rails.logger = original_logger
80
+ end
81
+
82
+ def test_logging_to_puts
83
+ ENV['GETIMG_LOG'] = '1'
84
+ log_output = StringIO.new
85
+ $stdout = log_output
86
+
87
+ GetimgClient.generate_image("A scenic landscape", model: :stable_diffusion_v1_5, width: 512, height: 512)
88
+
89
+ assert_includes log_output.string, "Generating image with the following details:"
90
+ assert_includes log_output.string, "Prompt: A scenic landscape"
91
+
92
+ $stdout = STDOUT
93
+ ENV.delete('GETIMG_LOG')
94
+ end
95
+
61
96
  private
62
97
 
63
98
  def save_image(base64_image, filename)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: getimg_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Melvin Sommer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-15 00:00:00.000000000 Z
11
+ date: 2024-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest