tryiton 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dc7c9b0e58bea7120e432b59b8db60364d95f66f2962fdc54e04a64602d8d757
4
+ data.tar.gz: e1f08ab852de54a201dc962e9799d35853b7b7a8c1da8c6947e3d1d135a85814
5
+ SHA512:
6
+ metadata.gz: b577a2d18b96023088aa636b0a287ec4a96581c264017fbc0aefb981af926b8bc49d1437964738e52e43da421628b7725028b7ac94dc54ca490c981769e4b445
7
+ data.tar.gz: 327f7c89b5a2b35f6dad23b60faaaaf6ee21e4ff7d39a42ea87ad29651eadd11c95679c000cc5c655893f386ecfd92104c05c38122009329a9969705dbb4d859
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # TryItOn Ruby SDK — AI Virtual Try-On API
2
+
3
+ Official Ruby client for the [TryItOn](https://tryiton.now) virtual try-on API. Add photoreal AI virtual try-on for clothing, accessories, hairstyles, and tattoos to your Ruby or Rails application with a few lines of code.
4
+
5
+ - Virtual clothing try-on and accessory try-on (eyewear, footwear, headwear, jewelry)
6
+ - Hairstyle and tattoo try-on
7
+ - Standard library only (no dependencies), with a built-in job polling helper
8
+
9
+ Full API reference: [docs.tryiton.now](https://docs.tryiton.now) · Get an API key: [tryiton.now/app/developer](https://tryiton.now/app/developer)
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ gem install tryiton
15
+ ```
16
+
17
+ Or add it to your Gemfile:
18
+
19
+ ```ruby
20
+ gem "tryiton"
21
+ ```
22
+
23
+ Requires Ruby 2.6 or later.
24
+
25
+ ## Quickstart: run a virtual try-on
26
+
27
+ Submit a garment and a model photo, then wait for the generated result image.
28
+
29
+ ```ruby
30
+ require "tryiton"
31
+
32
+ client = Tryiton::Client.new(api_key: ENV["TRYITON_API_KEY"])
33
+
34
+ # Submit a clothing try-on
35
+ job_id = client.try_on_clothes(
36
+ model_image: "https://example.com/model.jpg",
37
+ garment_image: "https://example.com/tshirt.jpg",
38
+ category: "clothing",
39
+ subcategory: "tops"
40
+ )
41
+
42
+ # Poll until the job completes and return the output image URL(s)
43
+ urls = client.wait_for_result(job_id)
44
+ puts urls.first # CDN URL, available for 72 hours
45
+ ```
46
+
47
+ Image inputs accept a public URL or a base64 data URL (`data:image/png;base64,...`).
48
+
49
+ ## Core parameters
50
+
51
+ `try_on_clothes` covers clothing and accessory try-on. The most important parameters:
52
+
53
+ | Parameter | Type | Required | Description |
54
+ | --------- | ---- | -------- | ----------- |
55
+ | `model_image` | String | Yes | URL or base64 data URL of the person. |
56
+ | `garment_image` | String | Yes | URL or base64 data URL of the garment or accessory. |
57
+ | `category` | String | No | Item type: `auto`, `clothing`, `eyewear`, `footwear`, `headwear`, `jewelry`, `accessories`, or `others`. `auto` detects it for you. |
58
+ | `subcategory` | String | No | Required for `clothing` (`tops`, `bottoms`, `dresses`), `jewelry`, and `accessories`. |
59
+
60
+ Additional options (`mode` and `moderation_level` for clothing; `num_samples` 1–4 and `output_format` `png`/`jpeg` for every try-on, including hairstyle and tattoo) are documented in the [API reference](https://docs.tryiton.now).
61
+
62
+ ## Other endpoints
63
+
64
+ ```ruby
65
+ # Hairstyle try-on (see Tryiton::HAIRCUTS for all supported values)
66
+ client.try_on_hairstyle(face_image: face_url, haircut: "BuzzCut", hair_color: "ash blonde")
67
+
68
+ # Tattoo try-on
69
+ client.try_on_tattoo(body_image: body_url, design_image: design_url, placement: "on the right forearm, small")
70
+
71
+ # Poll a job manually, or check your credit balance
72
+ status = client.get_status(job_id) # { "status" => ..., "output" => [...], "error" => ... }
73
+ credits = client.get_credits # { "on_demand" => ..., "subscription" => ..., "purchased" => ..., "reserved" => ... }
74
+ ```
75
+
76
+ ## Error handling
77
+
78
+ All failures raise `Tryiton::Error`, which carries the HTTP status code and the API error name.
79
+
80
+ ```ruby
81
+ begin
82
+ client.try_on_clothes(...)
83
+ rescue Tryiton::Error => e
84
+ puts "#{e.status} #{e.error_name} #{e.message}" # e.g. 429 OutOfCredits
85
+ end
86
+ ```
87
+
88
+ ## Notes
89
+
90
+ - Output image URLs expire 72 hours after completion. Download any results you want to keep.
91
+ - Failed jobs are never charged.
92
+
93
+ ## Documentation
94
+
95
+ Full documentation, parameter reference, and guides: [docs.tryiton.now](https://docs.tryiton.now)
96
+
97
+ ## License
98
+
99
+ MIT
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "net/http"
5
+ require "uri"
6
+
7
+ module Tryiton
8
+ # Raised for API-level errors and runtime (job) failures.
9
+ #
10
+ # status - HTTP status code, or nil for a runtime job failure.
11
+ # error_name - the API error name, e.g. "OutOfCredits" / "ProcessingError".
12
+ class Error < StandardError
13
+ attr_reader :status, :error_name
14
+
15
+ def initialize(message, status: nil, error_name: nil)
16
+ super(message)
17
+ @status = status
18
+ @error_name = error_name
19
+ end
20
+ end
21
+
22
+ # Supported `haircut` values for hairstyle try-on.
23
+ HAIRCUTS = %w[
24
+ Afro BobCut BowlCut BoxBraids BuzzCut Chignon CombOver CornrowBraids CurlyBob
25
+ CurlyShag DoubleBun Dreadlocks FauxHawk FishtailBraid LongCurly LongHairTiedUp
26
+ LongHimeCut LongStraight LongTwintails LongWavy LongWavyCurtainBangs ManBun
27
+ MessyTousled PixieCut Pompadour Ponytail ShortCurlyPixie ShortTwintails
28
+ ShoulderLengthHair Spiky TexturedFringe TwinBraids Updo WavyShag
29
+ ].freeze
30
+
31
+ # Client for the TryItOn virtual try-on API.
32
+ #
33
+ # client = Tryiton::Client.new(api_key: ENV["TRYITON_API_KEY"])
34
+ # job_id = client.try_on_clothes(
35
+ # model_image: "https://example.com/model.jpg",
36
+ # garment_image: "https://example.com/tshirt.jpg",
37
+ # category: "clothing", subcategory: "tops"
38
+ # )
39
+ # urls = client.wait_for_result(job_id)
40
+ #
41
+ # See https://docs.tryiton.now
42
+ class Client
43
+ DEFAULT_BASE_URL = "https://tryiton.now/api/v1"
44
+
45
+ def initialize(api_key:, base_url: DEFAULT_BASE_URL, timeout: 60)
46
+ raise Error.new("An api_key is required.", error_name: "ConfigError") if api_key.nil? || api_key.empty?
47
+
48
+ @api_key = api_key
49
+ @base_url = base_url.sub(%r{/+\z}, "")
50
+ @timeout = timeout
51
+ end
52
+
53
+ # Put a garment or accessory on a person. Returns the job id.
54
+ # Keys: model_image (required), garment_image (required), category,
55
+ # subcategory, mode, num_samples (1-4), output_format ("png"/"jpeg"),
56
+ # moderation_level ("conservative"/"permissive"/"none").
57
+ def try_on_clothes(**params)
58
+ request(:post, "/tryon/clothes", params)["jobId"]
59
+ end
60
+
61
+ # Restyle a person's hair. Returns the job id.
62
+ # Keys: face_image (required), haircut (required), hair_color,
63
+ # num_samples (1-4), output_format ("png"/"jpeg").
64
+ def try_on_hairstyle(**params)
65
+ request(:post, "/tryon/hairstyle", params)["jobId"]
66
+ end
67
+
68
+ # Ink a design onto skin. Returns the job id.
69
+ # Keys: body_image (required), design_image (required), placement,
70
+ # num_samples (1-4), output_format ("png"/"jpeg").
71
+ def try_on_tattoo(**params)
72
+ request(:post, "/tryon/tattoo", params)["jobId"]
73
+ end
74
+
75
+ # Fetch the current status of a job.
76
+ # Returns { "status" => ..., "output" => [...], "error" => ... }.
77
+ def get_status(job_id)
78
+ data = request(:get, "/status/#{URI.encode_www_form_component(job_id)}")
79
+ { "status" => data["status"] || "processing", "output" => data["output"] || [], "error" => data["error"] }
80
+ end
81
+
82
+ # Fetch your current credit balance.
83
+ def get_credits
84
+ request(:get, "/credits")["credits"]
85
+ end
86
+
87
+ # Poll a job until it completes, then return the output image URLs.
88
+ # Raises Tryiton::Error if the job fails or the timeout is reached.
89
+ def wait_for_result(job_id, poll_interval: 2.0, timeout: 120.0)
90
+ deadline = monotonic + timeout
91
+ loop do
92
+ status = get_status(job_id)
93
+ return status["output"] if status["status"] == "completed"
94
+
95
+ if status["status"] == "failed"
96
+ err = status["error"] || {}
97
+ raise Error.new(err["message"] || "Try-on failed.", error_name: err["name"] || "ProcessingError")
98
+ end
99
+
100
+ raise Error.new("Timed out waiting for job #{job_id}.", error_name: "Timeout") if monotonic > deadline
101
+
102
+ sleep(poll_interval)
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def monotonic
109
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
110
+ end
111
+
112
+ def request(method, path, body = nil)
113
+ uri = URI.parse("#{@base_url}#{path}")
114
+ req =
115
+ case method
116
+ when :post then Net::HTTP::Post.new(uri)
117
+ else Net::HTTP::Get.new(uri)
118
+ end
119
+ req["Authorization"] = "Bearer #{@api_key}"
120
+
121
+ unless body.nil?
122
+ compact = body.reject { |_, v| v.nil? }
123
+ req["Content-Type"] = "application/json"
124
+ req.body = JSON.generate(compact)
125
+ end
126
+
127
+ begin
128
+ res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https", read_timeout: @timeout) do |http|
129
+ http.request(req)
130
+ end
131
+ rescue StandardError => e
132
+ raise Error.new("Network error: #{e.message}", error_name: "NetworkError")
133
+ end
134
+
135
+ data =
136
+ begin
137
+ res.body && !res.body.empty? ? JSON.parse(res.body) : {}
138
+ rescue JSON::ParserError
139
+ {}
140
+ end
141
+
142
+ code = res.code.to_i
143
+ unless (200..299).cover?(code)
144
+ raise Error.new(data["message"] || "HTTP #{code}", status: code, error_name: data["error"])
145
+ end
146
+
147
+ data
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tryiton
4
+ VERSION = "1.0.0"
5
+ end
data/lib/tryiton.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "tryiton/version"
4
+ require_relative "tryiton/client"
5
+
6
+ # Official Ruby SDK for the TryItOn virtual try-on API.
7
+ # See https://docs.tryiton.now
8
+ module Tryiton
9
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tryiton
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - TryItOn
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Add photoreal clothing, accessory, hairstyle, and tattoo virtual try-on
13
+ to your app.
14
+ executables: []
15
+ extensions: []
16
+ extra_rdoc_files: []
17
+ files:
18
+ - README.md
19
+ - lib/tryiton.rb
20
+ - lib/tryiton/client.rb
21
+ - lib/tryiton/version.rb
22
+ homepage: https://docs.tryiton.now
23
+ licenses:
24
+ - MIT
25
+ metadata:
26
+ homepage_uri: https://tryiton.now
27
+ documentation_uri: https://docs.tryiton.now
28
+ source_code_uri: https://github.com/tryiton-now/tryiton-ruby
29
+ bug_tracker_uri: https://github.com/tryiton-now/tryiton-ruby/issues
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '2.6'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubygems_version: 3.6.9
45
+ specification_version: 4
46
+ summary: Official Ruby SDK for the TryItOn virtual try-on API.
47
+ test_files: []