+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/node_modules/@bundled-es-modules/cookie/node_modules/cookie/README.md b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5449c3a2587996d44b242281692c01ad2d2a3cf3
--- /dev/null
+++ b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/README.md
@@ -0,0 +1,302 @@
+# cookie
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][github-actions-ci-image]][github-actions-ci-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Basic HTTP cookie parser and serializer for HTTP servers.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install cookie
+```
+
+## API
+
+```js
+var cookie = require('cookie');
+```
+
+### cookie.parse(str, options)
+
+Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs.
+The `str` argument is the string representing a `Cookie` header value and `options` is an
+optional object containing additional parsing options.
+
+```js
+var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2');
+// { foo: 'bar', equation: 'E=mc^2' }
+```
+
+#### Options
+
+`cookie.parse` accepts these properties in the options object.
+
+##### decode
+
+Specifies a function that will be used to decode a cookie's value. Since the value of a cookie
+has a limited character set (and must be a simple string), this function can be used to decode
+a previously-encoded cookie value into a JavaScript string or other object.
+
+The default function is the global `decodeURIComponent`, which will decode any URL-encoded
+sequences into their byte representations.
+
+**note** if an error is thrown from this function, the original, non-decoded cookie value will
+be returned as the cookie's value.
+
+### cookie.serialize(name, value, options)
+
+Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the
+name for the cookie, the `value` argument is the value to set the cookie to, and the `options`
+argument is an optional object containing additional serialization options.
+
+```js
+var setCookie = cookie.serialize('foo', 'bar');
+// foo=bar
+```
+
+#### Options
+
+`cookie.serialize` accepts these properties in the options object.
+
+##### domain
+
+Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no
+domain is set, and most clients will consider the cookie to apply to only the current domain.
+
+##### encode
+
+Specifies a function that will be used to encode a cookie's value. Since value of a cookie
+has a limited character set (and must be a simple string), this function can be used to encode
+a value into a string suited for a cookie's value.
+
+The default function is the global `encodeURIComponent`, which will encode a JavaScript string
+into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range.
+
+##### expires
+
+Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1].
+By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and
+will delete it on a condition like exiting a web browser application.
+
+**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and
+`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
+so if both are set, they should point to the same date and time.
+
+##### httpOnly
+
+Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set.
+
+**note** be careful when setting this to `true`, as compliant clients will not allow client-side
+JavaScript to see the cookie in `document.cookie`.
+
+##### maxAge
+
+Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2].
+The given number will be converted to an integer by rounding down. By default, no maximum age is set.
+
+**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and
+`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
+so if both are set, they should point to the same date and time.
+
+##### path
+
+Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path
+is considered the ["default path"][rfc-6265-5.1.4].
+
+##### priority
+
+Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
+
+ - `'low'` will set the `Priority` attribute to `Low`.
+ - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
+ - `'high'` will set the `Priority` attribute to `High`.
+
+More information about the different priority levels can be found in
+[the specification][rfc-west-cookie-priority-00-4.1].
+
+**note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### sameSite
+
+Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-09-5.4.7].
+
+ - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+ - `false` will not set the `SameSite` attribute.
+ - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+ - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+ - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-09-5.4.7].
+
+**note** This is an attribute that has not yet been fully standardized, and may change in the future.
+This also means many clients may ignore this attribute until they understand it.
+
+##### secure
+
+Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
+
+**note** be careful when setting this to `true`, as compliant clients will not send the cookie back to
+the server in the future if the browser does not have an HTTPS connection.
+
+## Example
+
+The following example uses this module in conjunction with the Node.js core HTTP server
+to prompt a user for their name and display it back on future visits.
+
+```js
+var cookie = require('cookie');
+var escapeHtml = require('escape-html');
+var http = require('http');
+var url = require('url');
+
+function onRequest(req, res) {
+ // Parse the query string
+ var query = url.parse(req.url, true, true).query;
+
+ if (query && query.name) {
+ // Set a new cookie with the name
+ res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), {
+ httpOnly: true,
+ maxAge: 60 * 60 * 24 * 7 // 1 week
+ }));
+
+ // Redirect back after setting cookie
+ res.statusCode = 302;
+ res.setHeader('Location', req.headers.referer || '/');
+ res.end();
+ return;
+ }
+
+ // Parse the cookies on the request
+ var cookies = cookie.parse(req.headers.cookie || '');
+
+ // Get the visitor name set in the cookie
+ var name = cookies.name;
+
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+
+ if (name) {
+ res.write('Welcome back, ' + escapeHtml(name) + '!
');
+ } else {
+ res.write('Hello, new visitor!
');
+ }
+
+ res.write('');
+}
+
+http.createServer(onRequest).listen(3000);
+```
+
+## Testing
+
+```sh
+$ npm test
+```
+
+## Benchmark
+
+```
+$ npm run bench
+
+> cookie@0.4.2 bench
+> node benchmark/index.js
+
+ node@16.14.0
+ v8@9.4.146.24-node.20
+ uv@1.43.0
+ zlib@1.2.11
+ brotli@1.0.9
+ ares@1.18.1
+ modules@93
+ nghttp2@1.45.1
+ napi@8
+ llhttp@6.0.4
+ openssl@1.1.1m+quic
+ cldr@40.0
+ icu@70.1
+ tz@2021a3
+ unicode@14.0
+ ngtcp2@0.1.0-DEV
+ nghttp3@0.1.0-DEV
+
+> node benchmark/parse-top.js
+
+ cookie.parse - top sites
+
+ 15 tests completed.
+
+ parse accounts.google.com x 2,421,245 ops/sec ±0.80% (188 runs sampled)
+ parse apple.com x 2,684,710 ops/sec ±0.59% (189 runs sampled)
+ parse cloudflare.com x 2,231,418 ops/sec ±0.76% (186 runs sampled)
+ parse docs.google.com x 2,316,357 ops/sec ±1.28% (187 runs sampled)
+ parse drive.google.com x 2,363,543 ops/sec ±0.49% (189 runs sampled)
+ parse en.wikipedia.org x 839,414 ops/sec ±0.53% (189 runs sampled)
+ parse linkedin.com x 553,797 ops/sec ±0.63% (190 runs sampled)
+ parse maps.google.com x 1,314,779 ops/sec ±0.72% (189 runs sampled)
+ parse microsoft.com x 153,783 ops/sec ±0.53% (190 runs sampled)
+ parse play.google.com x 2,249,574 ops/sec ±0.59% (187 runs sampled)
+ parse plus.google.com x 2,258,682 ops/sec ±0.60% (188 runs sampled)
+ parse sites.google.com x 2,247,069 ops/sec ±0.68% (189 runs sampled)
+ parse support.google.com x 1,456,840 ops/sec ±0.70% (187 runs sampled)
+ parse www.google.com x 1,046,028 ops/sec ±0.58% (188 runs sampled)
+ parse youtu.be x 937,428 ops/sec ±1.47% (190 runs sampled)
+ parse youtube.com x 963,878 ops/sec ±0.59% (190 runs sampled)
+
+> node benchmark/parse.js
+
+ cookie.parse - generic
+
+ 6 tests completed.
+
+ simple x 2,745,604 ops/sec ±0.77% (185 runs sampled)
+ decode x 557,287 ops/sec ±0.60% (188 runs sampled)
+ unquote x 2,498,475 ops/sec ±0.55% (189 runs sampled)
+ duplicates x 868,591 ops/sec ±0.89% (187 runs sampled)
+ 10 cookies x 306,745 ops/sec ±0.49% (190 runs sampled)
+ 100 cookies x 22,414 ops/sec ±2.38% (182 runs sampled)
+```
+
+## References
+
+- [RFC 6265: HTTP State Management Mechanism][rfc-6265]
+- [Same-site Cookies][rfc-6265bis-09-5.4.7]
+
+[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1
+[rfc-6265bis-09-5.4.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7
+[rfc-6265]: https://tools.ietf.org/html/rfc6265
+[rfc-6265-5.1.4]: https://tools.ietf.org/html/rfc6265#section-5.1.4
+[rfc-6265-5.2.1]: https://tools.ietf.org/html/rfc6265#section-5.2.1
+[rfc-6265-5.2.2]: https://tools.ietf.org/html/rfc6265#section-5.2.2
+[rfc-6265-5.2.3]: https://tools.ietf.org/html/rfc6265#section-5.2.3
+[rfc-6265-5.2.4]: https://tools.ietf.org/html/rfc6265#section-5.2.4
+[rfc-6265-5.2.5]: https://tools.ietf.org/html/rfc6265#section-5.2.5
+[rfc-6265-5.2.6]: https://tools.ietf.org/html/rfc6265#section-5.2.6
+[rfc-6265-5.3]: https://tools.ietf.org/html/rfc6265#section-5.3
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master
+[coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master
+[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/cookie/ci/master?label=ci
+[github-actions-ci-url]: https://github.com/jshttp/cookie/actions/workflows/ci.yml
+[node-version-image]: https://badgen.net/npm/node/cookie
+[node-version-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/cookie
+[npm-url]: https://npmjs.org/package/cookie
+[npm-version-image]: https://badgen.net/npm/v/cookie
diff --git a/node_modules/@bundled-es-modules/cookie/node_modules/cookie/SECURITY.md b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/SECURITY.md
new file mode 100644
index 0000000000000000000000000000000000000000..fd4a6c53a9cd1abacf91125dab3fde3163b4c412
--- /dev/null
+++ b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/SECURITY.md
@@ -0,0 +1,25 @@
+# Security Policies and Procedures
+
+## Reporting a Bug
+
+The `cookie` team and community take all security bugs seriously. Thank
+you for improving the security of the project. We appreciate your efforts and
+responsible disclosure and will make every effort to acknowledge your
+contributions.
+
+Report security bugs by emailing the current owner(s) of `cookie`. This
+information can be found in the npm registry using the command
+`npm owner ls cookie`.
+If unsure or unable to get the information from the above, open an issue
+in the [project issue tracker](https://github.com/jshttp/cookie/issues)
+asking for the current contact information.
+
+To ensure the timely response to your report, please ensure that the entirety
+of the report is contained within the email body and not solely behind a web
+link or an attachment.
+
+At least one owner will acknowledge your email within 48 hours, and will send a
+more detailed response within 48 hours indicating the next steps in handling
+your report. After the initial reply to your report, the owners will
+endeavor to keep you informed of the progress towards a fix and full
+announcement, and may ask for additional information or guidance.
diff --git a/node_modules/@bundled-es-modules/cookie/node_modules/cookie/index.js b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c3d07d890de51262462fd80b2e13b7bd37d401d
--- /dev/null
+++ b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/index.js
@@ -0,0 +1,270 @@
+/*!
+ * cookie
+ * Copyright(c) 2012-2014 Roman Shtylman
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module exports.
+ * @public
+ */
+
+exports.parse = parse;
+exports.serialize = serialize;
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var __toString = Object.prototype.toString
+
+/**
+ * RegExp to match field-content in RFC 7230 sec 3.2
+ *
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+ * field-vchar = VCHAR / obs-text
+ * obs-text = %x80-FF
+ */
+
+var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
+
+/**
+ * Parse a cookie header.
+ *
+ * Parse the given cookie header string into an object
+ * The object has the various cookies as keys(names) => values
+ *
+ * @param {string} str
+ * @param {object} [options]
+ * @return {object}
+ * @public
+ */
+
+function parse(str, options) {
+ if (typeof str !== 'string') {
+ throw new TypeError('argument str must be a string');
+ }
+
+ var obj = {}
+ var opt = options || {};
+ var dec = opt.decode || decode;
+
+ var index = 0
+ while (index < str.length) {
+ var eqIdx = str.indexOf('=', index)
+
+ // no more cookie pairs
+ if (eqIdx === -1) {
+ break
+ }
+
+ var endIdx = str.indexOf(';', index)
+
+ if (endIdx === -1) {
+ endIdx = str.length
+ } else if (endIdx < eqIdx) {
+ // backtrack on prior semicolon
+ index = str.lastIndexOf(';', eqIdx - 1) + 1
+ continue
+ }
+
+ var key = str.slice(index, eqIdx).trim()
+
+ // only assign once
+ if (undefined === obj[key]) {
+ var val = str.slice(eqIdx + 1, endIdx).trim()
+
+ // quoted values
+ if (val.charCodeAt(0) === 0x22) {
+ val = val.slice(1, -1)
+ }
+
+ obj[key] = tryDecode(val, dec);
+ }
+
+ index = endIdx + 1
+ }
+
+ return obj;
+}
+
+/**
+ * Serialize data into a cookie header.
+ *
+ * Serialize the a name value pair into a cookie string suitable for
+ * http headers. An optional options object specified cookie parameters.
+ *
+ * serialize('foo', 'bar', { httpOnly: true })
+ * => "foo=bar; httpOnly"
+ *
+ * @param {string} name
+ * @param {string} val
+ * @param {object} [options]
+ * @return {string}
+ * @public
+ */
+
+function serialize(name, val, options) {
+ var opt = options || {};
+ var enc = opt.encode || encode;
+
+ if (typeof enc !== 'function') {
+ throw new TypeError('option encode is invalid');
+ }
+
+ if (!fieldContentRegExp.test(name)) {
+ throw new TypeError('argument name is invalid');
+ }
+
+ var value = enc(val);
+
+ if (value && !fieldContentRegExp.test(value)) {
+ throw new TypeError('argument val is invalid');
+ }
+
+ var str = name + '=' + value;
+
+ if (null != opt.maxAge) {
+ var maxAge = opt.maxAge - 0;
+
+ if (isNaN(maxAge) || !isFinite(maxAge)) {
+ throw new TypeError('option maxAge is invalid')
+ }
+
+ str += '; Max-Age=' + Math.floor(maxAge);
+ }
+
+ if (opt.domain) {
+ if (!fieldContentRegExp.test(opt.domain)) {
+ throw new TypeError('option domain is invalid');
+ }
+
+ str += '; Domain=' + opt.domain;
+ }
+
+ if (opt.path) {
+ if (!fieldContentRegExp.test(opt.path)) {
+ throw new TypeError('option path is invalid');
+ }
+
+ str += '; Path=' + opt.path;
+ }
+
+ if (opt.expires) {
+ var expires = opt.expires
+
+ if (!isDate(expires) || isNaN(expires.valueOf())) {
+ throw new TypeError('option expires is invalid');
+ }
+
+ str += '; Expires=' + expires.toUTCString()
+ }
+
+ if (opt.httpOnly) {
+ str += '; HttpOnly';
+ }
+
+ if (opt.secure) {
+ str += '; Secure';
+ }
+
+ if (opt.priority) {
+ var priority = typeof opt.priority === 'string'
+ ? opt.priority.toLowerCase()
+ : opt.priority
+
+ switch (priority) {
+ case 'low':
+ str += '; Priority=Low'
+ break
+ case 'medium':
+ str += '; Priority=Medium'
+ break
+ case 'high':
+ str += '; Priority=High'
+ break
+ default:
+ throw new TypeError('option priority is invalid')
+ }
+ }
+
+ if (opt.sameSite) {
+ var sameSite = typeof opt.sameSite === 'string'
+ ? opt.sameSite.toLowerCase() : opt.sameSite;
+
+ switch (sameSite) {
+ case true:
+ str += '; SameSite=Strict';
+ break;
+ case 'lax':
+ str += '; SameSite=Lax';
+ break;
+ case 'strict':
+ str += '; SameSite=Strict';
+ break;
+ case 'none':
+ str += '; SameSite=None';
+ break;
+ default:
+ throw new TypeError('option sameSite is invalid');
+ }
+ }
+
+ return str;
+}
+
+/**
+ * URL-decode string value. Optimized to skip native call when no %.
+ *
+ * @param {string} str
+ * @returns {string}
+ */
+
+function decode (str) {
+ return str.indexOf('%') !== -1
+ ? decodeURIComponent(str)
+ : str
+}
+
+/**
+ * URL-encode value.
+ *
+ * @param {string} str
+ * @returns {string}
+ */
+
+function encode (val) {
+ return encodeURIComponent(val)
+}
+
+/**
+ * Determine if value is a Date.
+ *
+ * @param {*} val
+ * @private
+ */
+
+function isDate (val) {
+ return __toString.call(val) === '[object Date]' ||
+ val instanceof Date
+}
+
+/**
+ * Try decoding a string using a decoding function.
+ *
+ * @param {string} str
+ * @param {function} decode
+ * @private
+ */
+
+function tryDecode(str, decode) {
+ try {
+ return decode(str);
+ } catch (e) {
+ return str;
+ }
+}
diff --git a/node_modules/@bundled-es-modules/cookie/node_modules/cookie/package.json b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..40cca5da923d5f8c80c8dfdec175d458b086cd77
--- /dev/null
+++ b/node_modules/@bundled-es-modules/cookie/node_modules/cookie/package.json
@@ -0,0 +1,82 @@
+{
+ "_from": "cookie@^0.5.0",
+ "_id": "cookie@0.5.0",
+ "_inBundle": false,
+ "_integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "_location": "/@bundled-es-modules/cookie/cookie",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "cookie@^0.5.0",
+ "name": "cookie",
+ "escapedName": "cookie",
+ "rawSpec": "^0.5.0",
+ "saveSpec": null,
+ "fetchSpec": "^0.5.0"
+ },
+ "_requiredBy": [
+ "/@bundled-es-modules/cookie"
+ ],
+ "_resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "_shasum": "d1f5d71adec6558c58f389987c366aa47e994f8b",
+ "_spec": "cookie@^0.5.0",
+ "_where": "/Users/sylvainfiloni/Documents/HuggingFace_Projects/live-vision/node_modules/@bundled-es-modules/cookie",
+ "author": {
+ "name": "Roman Shtylman",
+ "email": "shtylman@gmail.com"
+ },
+ "bugs": {
+ "url": "https://github.com/jshttp/cookie/issues"
+ },
+ "bundleDependencies": false,
+ "contributors": [
+ {
+ "name": "Douglas Christopher Wilson",
+ "email": "doug@somethingdoug.com"
+ }
+ ],
+ "deprecated": false,
+ "description": "HTTP server cookie parsing and serialization",
+ "devDependencies": {
+ "beautify-benchmark": "0.2.4",
+ "benchmark": "2.1.4",
+ "eslint": "7.32.0",
+ "eslint-plugin-markdown": "2.2.1",
+ "mocha": "9.2.2",
+ "nyc": "15.1.0",
+ "safe-buffer": "5.2.1",
+ "top-sites": "1.1.97"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ },
+ "files": [
+ "HISTORY.md",
+ "LICENSE",
+ "README.md",
+ "SECURITY.md",
+ "index.js"
+ ],
+ "homepage": "https://github.com/jshttp/cookie#readme",
+ "keywords": [
+ "cookie",
+ "cookies"
+ ],
+ "license": "MIT",
+ "name": "cookie",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jshttp/cookie.git"
+ },
+ "scripts": {
+ "bench": "node benchmark/index.js",
+ "lint": "eslint .",
+ "test": "mocha --reporter spec --bail --check-leaks test/",
+ "test-ci": "nyc --reporter=lcov --reporter=text npm test",
+ "test-cov": "nyc --reporter=html --reporter=text npm test",
+ "update-bench": "node scripts/update-benchmark.js",
+ "version": "node scripts/version-history.js && git add HISTORY.md"
+ },
+ "version": "0.5.0"
+}
diff --git a/node_modules/@bundled-es-modules/cookie/package.json b/node_modules/@bundled-es-modules/cookie/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..30cf9d75aa755e26c938bea312b95cd854690f57
--- /dev/null
+++ b/node_modules/@bundled-es-modules/cookie/package.json
@@ -0,0 +1,59 @@
+{
+ "_from": "@bundled-es-modules/cookie@^2.0.0",
+ "_id": "@bundled-es-modules/cookie@2.0.0",
+ "_inBundle": false,
+ "_integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==",
+ "_location": "/@bundled-es-modules/cookie",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "@bundled-es-modules/cookie@^2.0.0",
+ "name": "@bundled-es-modules/cookie",
+ "escapedName": "@bundled-es-modules%2fcookie",
+ "scope": "@bundled-es-modules",
+ "rawSpec": "^2.0.0",
+ "saveSpec": null,
+ "fetchSpec": "^2.0.0"
+ },
+ "_requiredBy": [
+ "/msw"
+ ],
+ "_resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz",
+ "_shasum": "c3b82703969a61cf6a46e959a012b2c257f6b164",
+ "_spec": "@bundled-es-modules/cookie@^2.0.0",
+ "_where": "/Users/sylvainfiloni/Documents/HuggingFace_Projects/live-vision/node_modules/msw",
+ "author": {
+ "name": "Pascal Schilp",
+ "email": "pascalschilp@gmail.com"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "cookie": "^0.5.0"
+ },
+ "deprecated": false,
+ "description": "mirror of cookie, bundled and exposed as ES module",
+ "devDependencies": {
+ "esbuild": "^0.17.17"
+ },
+ "exports": {
+ ".": {
+ "import": "./index-esm.js",
+ "require": "./index-cjs.cjs"
+ }
+ },
+ "files": [
+ "index-esm.js",
+ "index-cjs.cjs"
+ ],
+ "keywords": [],
+ "license": "ISC",
+ "main": "index-esm.js",
+ "name": "@bundled-es-modules/cookie",
+ "scripts": {
+ "build": "esbuild source.js --bundle --format=esm --outfile=index.js",
+ "dev": "node --watch dev.js"
+ },
+ "type": "module",
+ "version": "2.0.0"
+}
diff --git a/node_modules/@bundled-es-modules/statuses/README.md b/node_modules/@bundled-es-modules/statuses/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..dac56919fc8f94b8e6df2918da9b3b65dd981c30
--- /dev/null
+++ b/node_modules/@bundled-es-modules/statuses/README.md
@@ -0,0 +1,17 @@
+# statuses
+
+This is a mirror of [statuses](https://www.npmjs.com/package/statuses), bundled and exposed as ES module.
+
+## Install
+
+```
+npm install @bundled-es-modules/statuses
+```
+
+## Use
+
+```html
+
+```
\ No newline at end of file
diff --git a/node_modules/@bundled-es-modules/statuses/index-cjs.cjs b/node_modules/@bundled-es-modules/statuses/index-cjs.cjs
new file mode 100644
index 0000000000000000000000000000000000000000..274452e87289edc1f2dfb43638ded397893e7d6f
--- /dev/null
+++ b/node_modules/@bundled-es-modules/statuses/index-cjs.cjs
@@ -0,0 +1,2 @@
+const status = require('statuses');
+module.exports = status;
\ No newline at end of file
diff --git a/node_modules/@bundled-es-modules/statuses/index-esm.js b/node_modules/@bundled-es-modules/statuses/index-esm.js
new file mode 100644
index 0000000000000000000000000000000000000000..872044aeb0872b7e46105f21ec32f1cd76521ede
--- /dev/null
+++ b/node_modules/@bundled-es-modules/statuses/index-esm.js
@@ -0,0 +1,184 @@
+var __create = Object.create;
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+ // If the importer is in node compatibility mode or this is not an ESM
+ // file that has been converted to a CommonJS file using a Babel-
+ // compatible transform (i.e. "__esModule" has not been set), then set
+ // "default" to the CommonJS "module.exports" for node compatibility.
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+ mod
+));
+
+// node_modules/statuses/codes.json
+var require_codes = __commonJS({
+ "node_modules/statuses/codes.json"(exports, module) {
+ module.exports = {
+ "100": "Continue",
+ "101": "Switching Protocols",
+ "102": "Processing",
+ "103": "Early Hints",
+ "200": "OK",
+ "201": "Created",
+ "202": "Accepted",
+ "203": "Non-Authoritative Information",
+ "204": "No Content",
+ "205": "Reset Content",
+ "206": "Partial Content",
+ "207": "Multi-Status",
+ "208": "Already Reported",
+ "226": "IM Used",
+ "300": "Multiple Choices",
+ "301": "Moved Permanently",
+ "302": "Found",
+ "303": "See Other",
+ "304": "Not Modified",
+ "305": "Use Proxy",
+ "307": "Temporary Redirect",
+ "308": "Permanent Redirect",
+ "400": "Bad Request",
+ "401": "Unauthorized",
+ "402": "Payment Required",
+ "403": "Forbidden",
+ "404": "Not Found",
+ "405": "Method Not Allowed",
+ "406": "Not Acceptable",
+ "407": "Proxy Authentication Required",
+ "408": "Request Timeout",
+ "409": "Conflict",
+ "410": "Gone",
+ "411": "Length Required",
+ "412": "Precondition Failed",
+ "413": "Payload Too Large",
+ "414": "URI Too Long",
+ "415": "Unsupported Media Type",
+ "416": "Range Not Satisfiable",
+ "417": "Expectation Failed",
+ "418": "I'm a Teapot",
+ "421": "Misdirected Request",
+ "422": "Unprocessable Entity",
+ "423": "Locked",
+ "424": "Failed Dependency",
+ "425": "Too Early",
+ "426": "Upgrade Required",
+ "428": "Precondition Required",
+ "429": "Too Many Requests",
+ "431": "Request Header Fields Too Large",
+ "451": "Unavailable For Legal Reasons",
+ "500": "Internal Server Error",
+ "501": "Not Implemented",
+ "502": "Bad Gateway",
+ "503": "Service Unavailable",
+ "504": "Gateway Timeout",
+ "505": "HTTP Version Not Supported",
+ "506": "Variant Also Negotiates",
+ "507": "Insufficient Storage",
+ "508": "Loop Detected",
+ "509": "Bandwidth Limit Exceeded",
+ "510": "Not Extended",
+ "511": "Network Authentication Required"
+ };
+ }
+});
+
+// node_modules/statuses/index.js
+var require_statuses = __commonJS({
+ "node_modules/statuses/index.js"(exports, module) {
+ "use strict";
+ var codes = require_codes();
+ module.exports = status2;
+ status2.message = codes;
+ status2.code = createMessageToStatusCodeMap(codes);
+ status2.codes = createStatusCodeList(codes);
+ status2.redirect = {
+ 300: true,
+ 301: true,
+ 302: true,
+ 303: true,
+ 305: true,
+ 307: true,
+ 308: true
+ };
+ status2.empty = {
+ 204: true,
+ 205: true,
+ 304: true
+ };
+ status2.retry = {
+ 502: true,
+ 503: true,
+ 504: true
+ };
+ function createMessageToStatusCodeMap(codes2) {
+ var map = {};
+ Object.keys(codes2).forEach(function forEachCode(code) {
+ var message = codes2[code];
+ var status3 = Number(code);
+ map[message.toLowerCase()] = status3;
+ });
+ return map;
+ }
+ function createStatusCodeList(codes2) {
+ return Object.keys(codes2).map(function mapCode(code) {
+ return Number(code);
+ });
+ }
+ function getStatusCode(message) {
+ var msg = message.toLowerCase();
+ if (!Object.prototype.hasOwnProperty.call(status2.code, msg)) {
+ throw new Error('invalid status message: "' + message + '"');
+ }
+ return status2.code[msg];
+ }
+ function getStatusMessage(code) {
+ if (!Object.prototype.hasOwnProperty.call(status2.message, code)) {
+ throw new Error("invalid status code: " + code);
+ }
+ return status2.message[code];
+ }
+ function status2(code) {
+ if (typeof code === "number") {
+ return getStatusMessage(code);
+ }
+ if (typeof code !== "string") {
+ throw new TypeError("code must be a number or string");
+ }
+ var n = parseInt(code, 10);
+ if (!isNaN(n)) {
+ return getStatusMessage(n);
+ }
+ return getStatusCode(code);
+ }
+ }
+});
+
+// source.js
+var import_statuses = __toESM(require_statuses(), 1);
+var source_default = import_statuses.default;
+export {
+ source_default as default
+};
+/*! Bundled license information:
+
+statuses/index.js:
+ (*!
+ * statuses
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2016 Douglas Christopher Wilson
+ * MIT Licensed
+ *)
+*/
diff --git a/node_modules/@bundled-es-modules/statuses/package.json b/node_modules/@bundled-es-modules/statuses/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..e41d7a7e04091499b49ceb2d5f264a01c32d38b0
--- /dev/null
+++ b/node_modules/@bundled-es-modules/statuses/package.json
@@ -0,0 +1,59 @@
+{
+ "_from": "@bundled-es-modules/statuses@^1.0.1",
+ "_id": "@bundled-es-modules/statuses@1.0.1",
+ "_inBundle": false,
+ "_integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==",
+ "_location": "/@bundled-es-modules/statuses",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "@bundled-es-modules/statuses@^1.0.1",
+ "name": "@bundled-es-modules/statuses",
+ "escapedName": "@bundled-es-modules%2fstatuses",
+ "scope": "@bundled-es-modules",
+ "rawSpec": "^1.0.1",
+ "saveSpec": null,
+ "fetchSpec": "^1.0.1"
+ },
+ "_requiredBy": [
+ "/msw"
+ ],
+ "_resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz",
+ "_shasum": "761d10f44e51a94902c4da48675b71a76cc98872",
+ "_spec": "@bundled-es-modules/statuses@^1.0.1",
+ "_where": "/Users/sylvainfiloni/Documents/HuggingFace_Projects/live-vision/node_modules/msw",
+ "author": {
+ "name": "Pascal Schilp",
+ "email": "pascalschilp@gmail.com"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "statuses": "^2.0.1"
+ },
+ "deprecated": false,
+ "description": "mirror of statuses, bundled and exposed as ES module",
+ "devDependencies": {
+ "esbuild": "^0.17.17"
+ },
+ "exports": {
+ ".": {
+ "import": "./index-esm.js",
+ "require": "./index-cjs.cjs"
+ }
+ },
+ "files": [
+ "index-esm.js",
+ "index-cjs.cjs"
+ ],
+ "keywords": [],
+ "license": "ISC",
+ "main": "index-esm.js",
+ "name": "@bundled-es-modules/statuses",
+ "scripts": {
+ "build": "esbuild source.js --bundle --format=esm --outfile=index-esm.js",
+ "dev": "node dev.js"
+ },
+ "type": "module",
+ "version": "1.0.1"
+}
diff --git a/node_modules/@gradio/.DS_Store b/node_modules/@gradio/.DS_Store
deleted file mode 100644
index 89794c5909f890382306a25db7deb50054724627..0000000000000000000000000000000000000000
Binary files a/node_modules/@gradio/.DS_Store and /dev/null differ
diff --git a/node_modules/@gradio/client/.DS_Store b/node_modules/@gradio/client/.DS_Store
deleted file mode 100644
index feca8613504bcd7430524202412f605a970dd548..0000000000000000000000000000000000000000
Binary files a/node_modules/@gradio/client/.DS_Store and /dev/null differ
diff --git a/node_modules/@gradio/client/CHANGELOG.md b/node_modules/@gradio/client/CHANGELOG.md
index 7c0b67c8e3baf5b3e1c6289f1ffdb6149ce1fc43..e9e66289889c3b3611de41e97de84a8afd51bfec 100644
--- a/node_modules/@gradio/client/CHANGELOG.md
+++ b/node_modules/@gradio/client/CHANGELOG.md
@@ -1,5 +1,420 @@
# @gradio/client
+## 1.1.1
+
+### Features
+
+- [#8499](https://github.com/gradio-app/gradio/pull/8499) [`c5f6e77`](https://github.com/gradio-app/gradio/commit/c5f6e7722a197d4706419ade14276ddecf3196f8) - Cache break themes on change. Thanks @aliabid94!
+
+## 1.1.0
+
+### Features
+
+- [#8483](https://github.com/gradio-app/gradio/pull/8483) [`e2271e2`](https://github.com/gradio-app/gradio/commit/e2271e207d98074bf39b02ae3c5443b2f097627d) - documentation for @gradio/client. Thanks @pngwn!
+- [#8485](https://github.com/gradio-app/gradio/pull/8485) [`f8ebace`](https://github.com/gradio-app/gradio/commit/f8ebaceccef60a112603d290d10072ef4e938a6a) - Ensure all status are reported internally when calling `predict`. Thanks @pngwn!
+
+## 1.0.0
+
+### Highlights
+
+#### Clients 1.0 Launch! ([#8468](https://github.com/gradio-app/gradio/pull/8468) [`7cc0a0c`](https://github.com/gradio-app/gradio/commit/7cc0a0c1abea585c3f50ffb1ff78d2b08ddbdd92))
+
+We're excited to unveil the first major release of the Gradio clients.
+We've made it even easier to turn any Gradio application into a production endpoint thanks to the clients' **ergonomic**, **transparent**, and **portable** design.
+
+#### Ergonomic API 💆
+
+**Stream From a Gradio app in 5 lines**
+
+Use the `submit` method to get a job you can iterate over:
+
+```python
+from gradio_client import Client
+
+client = Client("gradio/llm_stream")
+
+for result in client.submit("What's the best UI framework in Python?"):
+ print(result)
+```
+
+```ts
+import { Client } from "@gradio/client";
+
+const client = await Client.connect("gradio/llm_stream")
+const job = client.submit("/predict", {"text": "What's the best UI framework in Python?"})
+
+for await (const msg of job) console.log(msg.data)
+```
+
+**Use the same keyword arguments as the app**
+
+
+```python
+from gradio_client import Client
+
+client = Client("http://127.0.0.1:7860/")
+result = client.predict(
+ message="Hello!!",
+ system_prompt="You are helpful AI.",
+ tokens=10,
+ api_name="/chat"
+)
+print(result)
+```
+
+```ts
+import { Client } from "@gradio/client";
+
+const client = await Client.connect("http://127.0.0.1:7860/");
+const result = await client.predict("/chat", {
+ message: "Hello!!",
+ system_prompt: "Hello!!",
+ tokens: 10,
+});
+
+console.log(result.data);
+```
+
+**Better Error Messages**
+
+If something goes wrong in the upstream app, the client will raise the same exception as the app provided that `show_error=True` in the original app's `launch()` function, or it's a `gr.Error` exception.
+
+#### Transparent Design 🪟
+
+Anything you can do in the UI, you can do with the client:
+* 🔒 Authentication
+* 🛑 Job Cancelling
+* ℹ️ Access Queue Position and API
+* 📕 View the API information
+
+Here's an example showing how to display the queue position of a pending job:
+
+```python
+from gradio_client import Client
+
+client = Client("gradio/diffusion_model")
+
+job = client.submit("A cute cat")
+while not job.done():
+ status = job.status()
+ print(f"Current in position {status.rank} out of {status.queue_size}")
+```
+
+#### Portable Design ⛺️
+
+The client can run from pretty much any python and javascript environment (node, deno, the browser, Service Workers).
+
+Here's an example using the client from a Flask server using gevent:
+
+```python
+from gevent import monkey
+monkey.patch_all()
+
+from gradio_client import Client
+from flask import Flask, send_file
+import time
+
+app = Flask(__name__)
+
+imageclient = Client("gradio/diffusion_model")
+
+@app.route("/gen")
+def gen():
+ result = imageclient.predict(
+ "A cute cat",
+ api_name="/predict"
+ )
+ return send_file(result)
+
+if __name__ == "__main__":
+ app.run(host="0.0.0.0", port=5000)
+```
+
+#### 1.0 Migration Guide and Breaking Changes
+
+**Python**
+- The `serialize` argument of the `Client` class was removed. Has no effect.
+- The `upload_files` argument of the `Client` was removed.
+- All filepaths must be wrapped in the `handle_file` method. Example:
+```python
+from gradio_client import Client, handle_file
+
+client = Client("gradio/image_captioner")
+client.predict(handle_file("cute_cat.jpg"))
+```
+- The `output_dir` argument was removed. It is not specified in the `download_files` argument.
+
+
+**Javascript**
+The client has been redesigned entirely. It was refactored from a function into a class. An instance can now be constructed by awaiting the `connect` method.
+
+```js
+const app = await Client.connect("gradio/whisper")
+```
+The app variable has the same methods as the python class (`submit`, `predict`, `view_api`, `duplicate`).
+
+
+
+#### Additional Changes
+
+- [#8243](https://github.com/gradio-app/gradio/pull/8243) - Set orig_name in python client file uploads.
+- [#8264](https://github.com/gradio-app/gradio/pull/8264) - Make exceptions in the Client more specific.
+- [#8247](https://github.com/gradio-app/gradio/pull/8247) - Fix api recorder.
+- [#8276](https://github.com/gradio-app/gradio/pull/8276) - Fix bug where client could not connect to apps that had self signed certificates.
+- [#8245](https://github.com/gradio-app/gradio/pull/8245) - Cancel server progress from the python client.
+- [#8200](https://github.com/gradio-app/gradio/pull/8200) - Support custom components in gr.load
+- [#8182](https://github.com/gradio-app/gradio/pull/8182) - Convert sse calls in client from async to sync.
+- [#7732](https://github.com/gradio-app/gradio/pull/7732) - Adds support for kwargs and default arguments in the python client, and improves how parameter information is displayed in the "view API" page.
+- [#7888](https://github.com/gradio-app/gradio/pull/7888) - Cache view_api info in server and python client.
+- [#7575](https://github.com/gradio-app/gradio/pull/7575) - Files should now be supplied as `file(...)` in the Client, and some fixes to `gr.load()` as well.
+- [#8401](https://github.com/gradio-app/gradio/pull/8401) - Add CDN installation to JS docs.
+- [#8299](https://github.com/gradio-app/gradio/pull/8299) - Allow JS Client to work with authenticated spaces 🍪.
+- [#8408](https://github.com/gradio-app/gradio/pull/8408) - Connect heartbeat if state created in render. Also fix config cleanup bug #8407.
+- [#8258](https://github.com/gradio-app/gradio/pull/8258) - Improve URL handling in JS Client.
+- [#8322](https://github.com/gradio-app/gradio/pull/8322) - ensure the client correctly handles all binary data.
+- [#8296](https://github.com/gradio-app/gradio/pull/8296) - always create a jwt when connecting to a space if a hf_token is present.
+- [#8285](https://github.com/gradio-app/gradio/pull/8285) - use the correct query param to pass the jwt to the heartbeat event.
+- [#8272](https://github.com/gradio-app/gradio/pull/8272) - ensure client works for private spaces.
+- [#8197](https://github.com/gradio-app/gradio/pull/8197) - Add support for passing keyword args to `data` in JS client.
+- [#8252](https://github.com/gradio-app/gradio/pull/8252) - Client node fix.
+- [#8209](https://github.com/gradio-app/gradio/pull/8209) - Rename `eventSource_Factory` and `fetch_implementation`.
+- [#8109](https://github.com/gradio-app/gradio/pull/8109) - Implement JS Client tests.
+- [#8211](https://github.com/gradio-app/gradio/pull/8211) - remove redundant event source logic.
+- [#8179](https://github.com/gradio-app/gradio/pull/8179) - rework upload to be a class method + pass client into each component.
+- [#8181](https://github.com/gradio-app/gradio/pull/8181) - Ensure connectivity to private HF spaces with SSE protocol.
+- [#8169](https://github.com/gradio-app/gradio/pull/8169) - Only connect to heartbeat if needed.
+- [#8118](https://github.com/gradio-app/gradio/pull/8118) - Add eventsource polyfill for Node.js and browser environments.
+- [#7646](https://github.com/gradio-app/gradio/pull/7646) - Refactor JS Client.
+- [#7974](https://github.com/gradio-app/gradio/pull/7974) - Fix heartbeat in the js client to be Lite compatible.
+- [#7926](https://github.com/gradio-app/gradio/pull/7926) - Fixes streaming event race condition.
+
+ Thanks @freddyaboulton!
+
+### Features
+
+- [#8370](https://github.com/gradio-app/gradio/pull/8370) [`48eeea4`](https://github.com/gradio-app/gradio/commit/48eeea4eaab7e24168688e3c3fbafb30e4e78d51) - Refactor Cancelling Logic To Use /cancel. Thanks @freddyaboulton!
+
+### Fixes
+
+- [#8477](https://github.com/gradio-app/gradio/pull/8477) [`d5a9604`](https://github.com/gradio-app/gradio/commit/d5a960493017a4890685af61d78ce7d3b3b12e6b) - Fix js client bundle. Thanks @pngwn!
+- [#8451](https://github.com/gradio-app/gradio/pull/8451) [`9d2d605`](https://github.com/gradio-app/gradio/commit/9d2d6051caed5c8749a26a6fa7480a5ae6e6c4f3) - Change client submit API to be an AsyncIterable and support more platforms. Thanks @pngwn!
+- [#8462](https://github.com/gradio-app/gradio/pull/8462) [`6447dfa`](https://github.com/gradio-app/gradio/commit/6447dface4d46db1c69460e8325a1928d0476a46) - Improve file handling in JS Client. Thanks @hannahblair!
+- [#8439](https://github.com/gradio-app/gradio/pull/8439) [`63d36fb`](https://github.com/gradio-app/gradio/commit/63d36fbbf4bf6dc909be9a0ffc7b6bf6621d83e8) - Handle gradio apps using `state` in the JS Client. Thanks @hannahblair!
+
+## 0.20.1
+
+### Features
+
+- [#8415](https://github.com/gradio-app/gradio/pull/8415) [`227de35`](https://github.com/gradio-app/gradio/commit/227de352982b3dcdf9384eaa28b7e9cf09afb6e8) - Fix spaces load error. Thanks @aliabid94!
+
+## 0.20.0
+
+### Features
+
+- [#8401](https://github.com/gradio-app/gradio/pull/8401) [`d078621`](https://github.com/gradio-app/gradio/commit/d078621928136c09ca902d2f37594ed887c67d2e) - Add CDN installation to JS docs. Thanks @hannahblair!
+- [#8243](https://github.com/gradio-app/gradio/pull/8243) [`55f664f`](https://github.com/gradio-app/gradio/commit/55f664f2979a49acc29a73cde16c6ebdfcc91db2) - Add event listener support to render blocks. Thanks @aliabid94!
+- [#8398](https://github.com/gradio-app/gradio/pull/8398) [`945ac83`](https://github.com/gradio-app/gradio/commit/945ac837e779b120790814ea6f6f81bd2712f5f8) - Improve rendering. Thanks @aliabid94!
+- [#8299](https://github.com/gradio-app/gradio/pull/8299) [`ab65360`](https://github.com/gradio-app/gradio/commit/ab653608045ff9462db7ad9fe63e1c60bf20e773) - Allow JS Client to work with authenticated spaces 🍪. Thanks @hannahblair!
+
+### Fixes
+
+- [#8408](https://github.com/gradio-app/gradio/pull/8408) [`e86dd01`](https://github.com/gradio-app/gradio/commit/e86dd01b6e8f7bab3d3c25b84f2ad33129138af4) - Connect heartbeat if state created in render. Also fix config cleanup bug #8407. Thanks @freddyaboulton!
+- [#8258](https://github.com/gradio-app/gradio/pull/8258) [`1f8e5c4`](https://github.com/gradio-app/gradio/commit/1f8e5c44e054b943052d8f24d044696ddfd01a54) - Improve URL handling in JS Client. Thanks @hannahblair!
+
+## 0.19.4
+
+### Fixes
+
+- [#8322](https://github.com/gradio-app/gradio/pull/8322) [`47012a0`](https://github.com/gradio-app/gradio/commit/47012a0c4e3e8a80fcae620aaf08b16ceb343cde) - ensure the client correctly handles all binary data. Thanks @Saghen!
+
+## 0.19.3
+
+### Features
+
+- [#8229](https://github.com/gradio-app/gradio/pull/8229) [`7c81897`](https://github.com/gradio-app/gradio/commit/7c81897076ddcd0bb05e0e4ffec35bb9a986d330) - chore(deps): update dependency esbuild to ^0.21.0. Thanks @renovate!
+
+### Fixes
+
+- [#8296](https://github.com/gradio-app/gradio/pull/8296) [`929d216`](https://github.com/gradio-app/gradio/commit/929d216d49aa05614bc83f0761cf7b1cd803d8fe) - always create a jwt when connecting to a space if a hf_token is present. Thanks @pngwn!
+
+## 0.19.2
+
+### Fixes
+
+- [#8285](https://github.com/gradio-app/gradio/pull/8285) [`7d9d8ea`](https://github.com/gradio-app/gradio/commit/7d9d8eab50d36cbecbb84c6a0f3cc1bca7215604) - use the correct query param to pass the jwt to the heartbeat event. Thanks @pngwn!
+
+## 0.19.1
+
+### Fixes
+
+- [#8272](https://github.com/gradio-app/gradio/pull/8272) [`fbf4edd`](https://github.com/gradio-app/gradio/commit/fbf4edde7c896cdf4c903463e44c31ed96111b3c) - ensure client works for private spaces. Thanks @pngwn!
+
+## 0.19.0
+
+### Features
+
+- [#8110](https://github.com/gradio-app/gradio/pull/8110) [`5436031`](https://github.com/gradio-app/gradio/commit/5436031f92c1596282eb64e1e74d555f279e9697) - Render decorator 2. Thanks @aliabid94!
+- [#8197](https://github.com/gradio-app/gradio/pull/8197) [`e09b4e8`](https://github.com/gradio-app/gradio/commit/e09b4e8216b970bc1b142a0f08e7d190b954eb35) - Add support for passing keyword args to `data` in JS client. Thanks @hannahblair!
+
+### Fixes
+
+- [#8252](https://github.com/gradio-app/gradio/pull/8252) [`22df61a`](https://github.com/gradio-app/gradio/commit/22df61a26adf8023f6dd49c051979990e8d3879a) - Client node fix. Thanks @pngwn!
+
+## 0.18.0
+
+### Features
+
+- [#8121](https://github.com/gradio-app/gradio/pull/8121) [`f5b710c`](https://github.com/gradio-app/gradio/commit/f5b710c919b0ce604ea955f0d5f4faa91095ca4a) - chore(deps): update dependency eslint to v9. Thanks @renovate!
+- [#8209](https://github.com/gradio-app/gradio/pull/8209) [`b9afe93`](https://github.com/gradio-app/gradio/commit/b9afe93915401df5bd6737c89395c2477acfa585) - Rename `eventSource_Factory` and `fetch_implementation`. Thanks @hannahblair!
+- [#8109](https://github.com/gradio-app/gradio/pull/8109) [`bed2f82`](https://github.com/gradio-app/gradio/commit/bed2f82e2297b50f7b59423a3de05af0b9910724) - Implement JS Client tests. Thanks @hannahblair!
+- [#8211](https://github.com/gradio-app/gradio/pull/8211) [`91b5cd6`](https://github.com/gradio-app/gradio/commit/91b5cd6132fb8903c92f70fce0800324836a1fc3) - remove redundant event source logic. Thanks @hannahblair!
+
+### Fixes
+
+- [#8179](https://github.com/gradio-app/gradio/pull/8179) [`6a218b4`](https://github.com/gradio-app/gradio/commit/6a218b4148095aaa0c58d8c20973ba01c8764fc2) - rework upload to be a class method + pass client into each component. Thanks @pngwn!
+- [#8181](https://github.com/gradio-app/gradio/pull/8181) [`cf52ca6`](https://github.com/gradio-app/gradio/commit/cf52ca6a51320ece97f009a177792840b5fbc785) - Ensure connectivity to private HF spaces with SSE protocol. Thanks @hannahblair!
+- [#8169](https://github.com/gradio-app/gradio/pull/8169) [`3a6f1a5`](https://github.com/gradio-app/gradio/commit/3a6f1a50b263e0a733f609a08019fc4d05480e1a) - Only connect to heartbeat if needed. Thanks @freddyaboulton!
+- [#8118](https://github.com/gradio-app/gradio/pull/8118) [`7aca673`](https://github.com/gradio-app/gradio/commit/7aca673b38a087533524b2fd8dd3a03e0e4bacfe) - Add eventsource polyfill for Node.js and browser environments. Thanks @hannahblair!
+
+## 0.17.0
+
+### Highlights
+
+#### Setting File Upload Limits ([#7909](https://github.com/gradio-app/gradio/pull/7909) [`2afca65`](https://github.com/gradio-app/gradio/commit/2afca6541912b37dc84f447c7ad4af21607d7c72))
+
+We have added a `max_file_size` size parameter to `launch()` that limits to size of files uploaded to the server. This limit applies to each individual file. This parameter can be specified as a string or an integer (corresponding to the size in bytes).
+
+The following code snippet sets a max file size of 5 megabytes.
+
+```python
+import gradio as gr
+
+demo = gr.Interface(lambda x: x, "image", "image")
+
+demo.launch(max_file_size="5mb")
+# or
+demo.launch(max_file_size=5 * gr.FileSize.MB)
+```
+
+![max_file_size_upload](https://github.com/gradio-app/gradio/assets/41651716/7547330c-a082-4901-a291-3f150a197e45)
+
+
+#### Error states can now be cleared
+
+When a component encounters an error, the error state shown in the UI can now be cleared by clicking on the `x` icon in the top right of the component. This applies to all types of errors, whether it's raised in the UI or the server.
+
+![error_modal_calculator](https://github.com/gradio-app/gradio/assets/41651716/16cb071c-accd-45a6-9c18-0dea27d4bd98)
+
+ Thanks @freddyaboulton!
+
+### Features
+
+- [#8056](https://github.com/gradio-app/gradio/pull/8056) [`2e469a5`](https://github.com/gradio-app/gradio/commit/2e469a5f99e52a5011a010f46e47dde7bb0c7140) - Using keys to preserve values between reloads. Thanks @aliabid94!
+- [#7646](https://github.com/gradio-app/gradio/pull/7646) [`450b8cc`](https://github.com/gradio-app/gradio/commit/450b8cc898f130f15caa3742f65c17b9f7a8f398) - Refactor JS Client. Thanks @hannahblair!
+- [#8061](https://github.com/gradio-app/gradio/pull/8061) [`17e83c9`](https://github.com/gradio-app/gradio/commit/17e83c958ebb35b3e122ca486067d1bd5ce33a22) - Docs Reorg and Intro Page. Thanks @aliabd!
+
+### Fixes
+
+- [#8066](https://github.com/gradio-app/gradio/pull/8066) [`624f9b9`](https://github.com/gradio-app/gradio/commit/624f9b9477f74a581a6c14119234f9efdfcda398) - make gradio dev tools a local dependency rather than bundling. Thanks @pngwn!
+
+## 0.16.0
+
+### Features
+
+- [#7845](https://github.com/gradio-app/gradio/pull/7845) [`dbb7373`](https://github.com/gradio-app/gradio/commit/dbb7373dde69d4ed2741942b5a1898f8620cec24) - ensure `ImageEditor` events work as expected. Thanks @pngwn!
+
+### Fixes
+
+- [#7974](https://github.com/gradio-app/gradio/pull/7974) [`79e0aa8`](https://github.com/gradio-app/gradio/commit/79e0aa81c94e755faa6e85d76ac5d5a666313e6a) - Fix heartbeat in the js client to be Lite compatible. Thanks @whitphx!
+
+## 0.15.1
+
+### Fixes
+
+- [#7926](https://github.com/gradio-app/gradio/pull/7926) [`9666854`](https://github.com/gradio-app/gradio/commit/966685479078f59430b3bced7e6068eb8157c003) - Fixes streaming event race condition. Thanks @aliabid94!
+
+## 0.15.0
+
+### Highlights
+
+#### Automatically delete state after user has disconnected from the webpage ([#7829](https://github.com/gradio-app/gradio/pull/7829) [`6a4bf7a`](https://github.com/gradio-app/gradio/commit/6a4bf7abe29059dbdc6a342e0366fdaa2e4120ee))
+
+Gradio now automatically deletes `gr.State` variables stored in the server's RAM when users close their browser tab.
+The deletion will happen 60 minutes after the server detected a disconnect from the user's browser.
+If the user connects again in that timeframe, their state will not be deleted.
+
+Additionally, Gradio now includes a `Blocks.unload()` event, allowing you to run arbitrary cleanup functions when users disconnect (this does not have a 60 minute delay).
+You can think of the `unload` event as the opposite of the `load` event.
+
+
+```python
+with gr.Blocks() as demo:
+ gr.Markdown(
+"""# State Cleanup Demo
+🖼️ Images are saved in a user-specific directory and deleted when the users closes the page via demo.unload.
+""")
+ with gr.Row():
+ with gr.Column(scale=1):
+ with gr.Row():
+ img = gr.Image(label="Generated Image", height=300, width=300)
+ with gr.Row():
+ gen = gr.Button(value="Generate")
+ with gr.Row():
+ history = gr.Gallery(label="Previous Generations", height=500, columns=10)
+ state = gr.State(value=[], delete_callback=lambda v: print("STATE DELETED"))
+
+ demo.load(generate_random_img, [state], [img, state, history])
+ gen.click(generate_random_img, [state], [img, state, history])
+ demo.unload(delete_directory)
+
+
+demo.launch(auth=lambda user,pwd: True,
+ auth_message="Enter any username and password to continue")
+```
+
+ Thanks @freddyaboulton!
+
+## 0.14.0
+
+### Features
+
+- [#7691](https://github.com/gradio-app/gradio/pull/7691) [`84f81fe`](https://github.com/gradio-app/gradio/commit/84f81fec9287b041203a141bbf2852720f7d199c) - Closing stream from the backend. Thanks @aliabid94!
+
+### Fixes
+
+- [#7564](https://github.com/gradio-app/gradio/pull/7564) [`5d1e8da`](https://github.com/gradio-app/gradio/commit/5d1e8dae5ac23f605c3b5f41dbe18751dff380a0) - batch UI updates on a per frame basis. Thanks @pngwn!
+
+## 0.13.0
+
+### Fixes
+
+- [#7575](https://github.com/gradio-app/gradio/pull/7575) [`d0688b3`](https://github.com/gradio-app/gradio/commit/d0688b3c25feabb4fc7dfa0ab86086b3af7eb337) - Files should now be supplied as `file(...)` in the Client, and some fixes to `gr.load()` as well. Thanks @abidlabs!
+
+## 0.12.2
+
+### Features
+
+- [#7528](https://github.com/gradio-app/gradio/pull/7528) [`eda33b3`](https://github.com/gradio-app/gradio/commit/eda33b3763897a542acf298e523fa493dc655aee) - Refactors `get_fetchable_url_or_file()` to remove it from the frontend. Thanks [@abidlabs](https://github.com/abidlabs)!
+- [#7340](https://github.com/gradio-app/gradio/pull/7340) [`4b0d589`](https://github.com/gradio-app/gradio/commit/4b0d58933057432758a54169a360eb352903d6b4) - chore(deps): update all non-major dependencies. Thanks [@renovate](https://github.com/apps/renovate)!
+
+## 0.12.1
+
+### Fixes
+
+- [#7411](https://github.com/gradio-app/gradio/pull/7411) [`32b317f`](https://github.com/gradio-app/gradio/commit/32b317f24e3d43f26684bb9f3964f31efd0ea556) - Set `root` correctly for Gradio apps that are deployed behind reverse proxies. Thanks [@abidlabs](https://github.com/abidlabs)!
+
+## 0.12.0
+
+### Features
+
+- [#7183](https://github.com/gradio-app/gradio/pull/7183) [`49d9c48`](https://github.com/gradio-app/gradio/commit/49d9c48537aa706bf72628e3640389470138bdc6) - [WIP] Refactor file normalization to be in the backend and remove it from the frontend of each component. Thanks [@abidlabs](https://github.com/abidlabs)!
+
+## 0.11.0
+
+### Features
+
+- [#7102](https://github.com/gradio-app/gradio/pull/7102) [`68a54a7`](https://github.com/gradio-app/gradio/commit/68a54a7a310d8d7072fdae930bf1cfdf12c45a7f) - Improve chatbot streaming performance with diffs. Thanks [@aliabid94](https://github.com/aliabid94)!/n Note that this PR changes the API format for generator functions, which would be a breaking change for any clients reading the EventStream directly
+
## 0.10.1
### Fixes
diff --git a/node_modules/@gradio/client/README.md b/node_modules/@gradio/client/README.md
index ddf80eb862ad5d36ec53cdef0f470d2aa67c41da..0da7a166c2e8105c41f8bca5575d658df4a2083f 100644
--- a/node_modules/@gradio/client/README.md
+++ b/node_modules/@gradio/client/README.md
@@ -1,29 +1,36 @@
## JavaScript Client Library
-A javascript (and typescript) client to call Gradio APIs.
+Interact with Gradio APIs using our JavaScript (and TypeScript) client.
+
## Installation
-The Gradio JavaScript client is available on npm as `@gradio/client`. You can install it as below:
+The Gradio JavaScript Client is available on npm as `@gradio/client`. You can install it as below:
-```sh
+```shell
npm i @gradio/client
```
+Or, you can include it directly in your HTML via the jsDelivr CDN:
+
+```shell
+
+```
+
## Usage
-The JavaScript Gradio Client exposes two named imports, `client` and `duplicate`.
+The JavaScript Gradio Client exposes the Client class, `Client`, along with various other utility functions. `Client` is used to initialise and establish a connection to, or duplicate, a Gradio app.
-### `client`
+### `Client`
-The client function connects to the API of a hosted Gradio space and returns an object that allows you to make calls to that API.
+The Client function connects to the API of a hosted Gradio space and returns an object that allows you to make calls to that API.
The simplest example looks like this:
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
const result = await app.predict("/predict");
```
@@ -34,7 +41,7 @@ This function accepts two arguments: `source` and `options`:
This is the url or name of the gradio app whose API you wish to connect to. This parameter is required and should always be a string. For example:
```ts
-client("user/space-name");
+Client.connect("user/space-name");
```
#### `options`
@@ -48,23 +55,23 @@ This should be a Hugging Face personal access token and is required if you wish
Example:
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name", { hf_token: "hf_..." });
+const app = await Client.connect("user/space-name", { hf_token: "hf_..." });
```
##### `status_callback`
-This should be a function which will notify your of the status of a space if it is not running. If the gradio API you are connecting to is awake and running or is not hosted on Hugging Face space then this function will do nothing.
+This should be a function which will notify you of the status of a space if it is not running. If the gradio API you are connecting to is not awake and running or is not hosted on Hugging Face space then this function will do nothing.
**Additional context**
Applications hosted on Hugging Face spaces can be in a number of different states. As spaces are a GitOps tool and will rebuild when new changes are pushed to the repository, they have various building, running and error states. If a space is not 'running' then the function passed as the `status_callback` will notify you of the current state of the space and the status of the space as it changes. Spaces that are building or sleeping can take longer than usual to respond, so you can use this information to give users feedback about the progress of their action.
```ts
-import { client, type SpaceStatus } from "@gradio/client";
+import { Client, type SpaceStatus } from "@gradio/client";
-const app = await client("user/space-name", {
+const app = await Client.connect("user/space-name", {
// The space_status parameter does not need to be manually annotated, this is just for illustration.
space_status: (space_status: SpaceStatus) => console.log(space_status)
});
@@ -100,9 +107,9 @@ The gradio client returns an object with a number of methods and properties:
The `predict` method allows you to call an api endpoint and get a prediction result:
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
const result = await app.predict("/predict");
```
@@ -113,21 +120,25 @@ const result = await app.predict("/predict");
This is the endpoint for an api request and is required. The default endpoint for a `gradio.Interface` is `"/predict"`. Explicitly named endpoints have a custom name. The endpoint names can be found on the "View API" page of a space.
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
const result = await app.predict("/predict");
```
##### `payload`
-The `payload` argument is generally optional but this depends on the API itself. If the API endpoint depends on values being passed in then it is required for the API request to succeed. The data that should be passed in is detailed on the "View API" page of a space, or accessible via the `view_api()` method of the client.
+The `payload` argument is generally required but this depends on the API itself. If the API endpoint depends on values being passed in then the argument is required for the API request to succeed. The data that should be passed in is detailed on the "View API" page of a space, or accessible via the `view_api()` method of the client.
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
-const result = await app.predict("/predict", [1, "Hello", "friends"]);
+const app = await Client.connect("user/space-name");
+const result = await app.predict("/predict", {
+ input: 1,
+ word_1: "Hello",
+ word_2: "friends"
+});
```
#### `submit`
@@ -135,19 +146,27 @@ const result = await app.predict("/predict", [1, "Hello", "friends"]);
The `submit` method provides a more flexible way to call an API endpoint, providing you with status updates about the current progress of the prediction as well as supporting more complex endpoint types.
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
-const submission = app.submit("/predict", payload);
+const app = await Client.connect("user/space-name");
+const submission = app.submit("/predict", { name: "Chewbacca" });
```
The `submit` method accepts the same [`endpoint`](#endpoint) and [`payload`](#payload) arguments as `predict`.
-The `submit` method does not return a promise and should not be awaited, instead it returns an object with a `on`, `off`, and `cancel` methods.
+The `submit` method does not return a promise and should not be awaited, instead it returns an async iterator with a `cancel` method.
+
+##### Accessing values
-##### `on`
+Iterating the submission allows you to access the events related to the submitted API request. There are two types of events that can be listened for: `"data"` updates and `"status"` updates. By default only the `"data"` event is reported, but you can listen for the `"status"` event by manually passing the events you care about when instantiating the client:
-The `on` method allows you to subscribe to events related to the submitted API request. There are two types of event that can be subscribed to: `"data"` updates and `"status"` updates.
+```ts
+import { Client } from "@gradio/client";
+
+const app = await Client.connect("user/space-name", {
+ events: ["data", "status"]
+});
+```
`"data"` updates are issued when the API computes a value, the callback provided as the second argument will be called when such a value is sent to the client. The shape of the data depends on the way the API itself is constructed. This event may fire more than once if that endpoint supports emmitting new values over time.
@@ -176,61 +195,38 @@ interface Status {
}
```
-Usage of these subscribe callback looks like this:
+Usage looks like this:
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
const submission = app
- .submit("/predict", payload)
- .on("data", (data) => console.log(data))
- .on("status", (status: Status) => console.log(status));
-```
-
-##### `off`
+ .submit("/predict", { name: "Chewbacca" })
-The `off` method unsubscribes from a specific event of the submitted job and works similarly to `document.removeEventListener`; both the event name and the original callback must be passed in to successfully unsubscribe:
+ for await (const msg of submission) {
+ if (msg.type === "data") {
+ console.log(msg.data);
+ }
-```ts
-import { client } from "@gradio/client";
-
-const app = await client("user/space-name");
-const handle_data = (data) => console.log(data);
-
-const submission = app.submit("/predict", payload).on("data", handle_data);
-
-// later
-submission.off("/predict", handle_data);
+ if (msg.type === "status") {
+ console.log(msg);
+ }
+ }
```
-##### `destroy`
-
-The `destroy` method will remove all subscriptions to a job, regardless of whether or not they are `"data"` or `"status"` events. This is a convenience method for when you do not want to unsubscribe use the `off` method.
-
-```js
-import { client } from "@gradio/client";
-
-const app = await client("user/space-name");
-const handle_data = (data) => console.log(data);
-
-const submission = app.submit("/predict", payload).on("data", handle_data);
-
-// later
-submission.destroy();
-```
##### `cancel`
Certain types of gradio function can run repeatedly and in some cases indefinitely. the `cancel` method will stop such an endpoints and prevent the API from issuing additional updates.
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
const submission = app
- .submit("/predict", payload)
- .on("data", (data) => console.log(data));
+ .submit("/predict", { name: "Chewbacca" })
+
// later
@@ -242,9 +238,9 @@ submission.cancel();
The `view_api` method provides details about the API you are connected to. It returns a JavaScript object of all named endpoints, unnamed endpoints and what values they accept and return. This method does not accept arguments.
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
const api_info = await app.view_api();
console.log(api_info);
@@ -255,9 +251,9 @@ console.log(api_info);
The `config` property contains the configuration for the gradio application you are connected to. This object may contain useful meta information about the application.
```ts
-import { client } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await client("user/space-name");
+const app = await Client.connect("user/space-name");
console.log(app.config);
```
@@ -268,9 +264,9 @@ The duplicate function will attempt to duplicate the space that is referenced an
`duplicate` accepts the same arguments as `client` with the addition of a `private` options property dictating whether the duplicated space should be private or public. A huggingface token is required for duplication to work.
```ts
-import { duplicate } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await duplicate("user/space-name", {
+const app = await Client.duplicate("user/space-name", {
hf_token: "hf_..."
});
```
@@ -292,9 +288,9 @@ Accepts all options that `client` accepts, except `hf_token` is required. [See `
This is an optional property specific to `duplicate`'s options object and will determine whether the space should be public or private. Spaces duplicated via the `duplicate` method are public by default.
```ts
-import { duplicate } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await duplicate("user/space-name", {
+const app = await Client.duplicate("user/space-name", {
hf_token: "hf_...",
private: true
});
@@ -305,9 +301,9 @@ const app = await duplicate("user/space-name", {
This is an optional property specific to `duplicate`'s options object and will set the timeout in minutes before the duplicated space will go to sleep.
```ts
-import { duplicate } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await duplicate("user/space-name", {
+const app = await Client.duplicate("user/space-name", {
hf_token: "hf_...",
private: true,
timeout: 5
@@ -322,16 +318,22 @@ Possible hardware options are:
- `"cpu-basic"`
- `"cpu-upgrade"`
+- `"cpu-xl"`
- `"t4-small"`
- `"t4-medium"`
- `"a10g-small"`
- `"a10g-large"`
+- `"a10g-largex2"`
+- `"a10g-largex4"`
- `"a100-large"`
+- `"zero-a10g"`
+- `"h100"`
+- `"h100x8"`
```ts
-import { duplicate } from "@gradio/client";
+import { Client } from "@gradio/client";
-const app = await duplicate("user/space-name", {
+const app = await Client.duplicate("user/space-name", {
hf_token: "hf_...",
private: true,
hardware: "a10g-small"
diff --git a/node_modules/@gradio/client/dist/client.d.ts b/node_modules/@gradio/client/dist/client.d.ts
index 238887c0f3432b0a910f31a72ce1da5ba06d4686..69c0c70e718f2c68cdedd2923db55f46171d20f2 100644
--- a/node_modules/@gradio/client/dist/client.d.ts
+++ b/node_modules/@gradio/client/dist/client.d.ts
@@ -1,76 +1,70 @@
-import { hardware_types } from "./utils.js";
-import type { EventType, EventListener, PostResponse, UploadResponse, SpaceStatusCallback } from "./types.js";
-import type { Config } from "./types.js";
-type event = (eventType: K, listener: EventListener) => SubmitReturn;
-type predict = (endpoint: string | number, data?: unknown[], event_data?: unknown) => Promise;
-type client_return = {
- predict: predict;
- config: Config;
- submit: (endpoint: string | number, data?: unknown[], event_data?: unknown, trigger_id?: number | null) => SubmitReturn;
- component_server: (component_id: number, fn_name: string, data: unknown[]) => any;
- view_api: (c?: Config) => Promise>;
-};
-type SubmitReturn = {
- on: event;
- off: event;
- cancel: () => Promise;
- destroy: () => void;
-};
-export declare let NodeBlob: any;
-export declare function duplicate(app_reference: string, options: {
- hf_token: `hf_${string}`;
- private?: boolean;
- status_callback: SpaceStatusCallback;
- hardware?: (typeof hardware_types)[number];
- timeout?: number;
-}): Promise;
-interface Client {
- post_data: (url: string, body: unknown, token?: `hf_${string}`) => Promise<[PostResponse, number]>;
- upload_files: (root: string, files: File[], token?: `hf_${string}`, upload_id?: string) => Promise;
- client: (app_reference: string, options: {
- hf_token?: `hf_${string}`;
- status_callback?: SpaceStatusCallback;
- normalise_files?: boolean;
- }) => Promise;
- handle_blob: (endpoint: string, data: unknown[], api_info: ApiInfo, token?: `hf_${string}`) => Promise;
-}
-export declare function api_factory(fetch_implementation: typeof fetch, EventSource_factory: (url: URL) => EventSource): Client;
-export declare const post_data: (url: string, body: unknown, token?: `hf_${string}`) => Promise<[PostResponse, number]>, upload_files: (root: string, files: File[], token?: `hf_${string}`, upload_id?: string) => Promise, client: (app_reference: string, options: {
- hf_token?: `hf_${string}`;
- status_callback?: SpaceStatusCallback;
- normalise_files?: boolean;
-}) => Promise, handle_blob: (endpoint: string, data: unknown[], api_info: ApiInfo, token?: `hf_${string}`) => Promise;
-interface ApiData {
- label: string;
- type: {
- type: any;
- description: string;
- };
- component: string;
- example_input?: any;
-}
-interface JsApiData {
- label: string;
- type: string;
- component: string;
- example_input: any;
-}
-interface EndpointInfo {
- parameters: T[];
- returns: T[];
-}
-interface ApiInfo {
- named_endpoints: {
- [key: string]: EndpointInfo;
- };
- unnamed_endpoints: {
- [key: string]: EndpointInfo;
+import type { ApiData, ApiInfo, ClientOptions, Config, DuplicateOptions, EndpointInfo, JsApiData, PredictReturn, SpaceStatus, Status, UploadResponse, SubmitIterable, GradioEvent } from "./types";
+import { FileData } from "./upload";
+export declare class Client {
+ app_reference: string;
+ options: ClientOptions;
+ config: Config | undefined;
+ api_info: ApiInfo | undefined;
+ api_map: Record;
+ session_hash: string;
+ jwt: string | false;
+ last_status: Record;
+ private cookies;
+ stream_status: {
+ open: boolean;
};
+ pending_stream_messages: Record;
+ pending_diff_streams: Record;
+ event_callbacks: Record Promise>;
+ unclosed_events: Set;
+ heartbeat_event: EventSource | null;
+ abort_controller: AbortController | null;
+ stream_instance: EventSource | null;
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise;
+ stream(url: URL): EventSource;
+ view_api: () => Promise>;
+ upload_files: (root_url: string, files: (Blob | File)[], upload_id?: string) => Promise;
+ upload: (file_data: FileData[], root_url: string, upload_id?: string, max_file_size?: number) => Promise<(FileData | null)[] | null>;
+ handle_blob: (endpoint: string, data: unknown[], endpoint_info: EndpointInfo) => Promise;
+ post_data: (url: string, body: unknown, additional_headers?: any) => Promise;
+ submit: (endpoint: string | number, data: unknown[] | Record, event_data?: unknown, trigger_id?: number | null, all_events?: boolean) => SubmitIterable;
+ predict: (endpoint: string | number, data: unknown[] | Record, event_data?: unknown) => Promise;
+ open_stream: () => Promise;
+ private resolve_config;
+ private resolve_cookies;
+ constructor(app_reference: string, options?: ClientOptions);
+ private init;
+ _resolve_hearbeat(_config: Config): Promise;
+ static connect(app_reference: string, options?: ClientOptions): Promise;
+ close(): void;
+ static duplicate(app_reference: string, options?: DuplicateOptions): Promise;
+ private _resolve_config;
+ private config_success;
+ handle_space_success(status: SpaceStatus): Promise;
+ component_server(component_id: number, fn_name: string, data: unknown[] | {
+ binary: boolean;
+ data: Record;
+ }): Promise;
+ set_cookies(raw_cookies: string): void;
+ private prepare_return_obj;
}
-export declare function walk_and_store_blobs(param: any, type?: any, path?: any[], root?: boolean, api_info?: any): Promise<{
- path: string[];
- type: string;
- blob: Blob | false;
-}[]>;
-export {};
+/**
+ * @deprecated This method will be removed in v1.0. Use `Client.connect()` instead.
+ * Creates a client instance for interacting with Gradio apps.
+ *
+ * @param {string} app_reference - The reference or URL to a Gradio space or app.
+ * @param {ClientOptions} options - Configuration options for the client.
+ * @returns {Promise} A promise that resolves to a `Client` instance.
+ */
+export declare function client(app_reference: string, options?: ClientOptions): Promise;
+/**
+ * @deprecated This method will be removed in v1.0. Use `Client.duplicate()` instead.
+ * Creates a duplicate of a space and returns a client instance for the duplicated space.
+ *
+ * @param {string} app_reference - The reference or URL to a Gradio space or app to duplicate.
+ * @param {DuplicateOptions} options - Configuration options for the client.
+ * @returns {Promise} A promise that resolves to a `Client` instance.
+ */
+export declare function duplicate_space(app_reference: string, options: DuplicateOptions): Promise;
+export type ClientInstance = Client;
//# sourceMappingURL=client.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/client.d.ts.map b/node_modules/@gradio/client/dist/client.d.ts.map
index 2dada055520b489bc4595e6afa9fcbf15ac9c668..bb1ba310c0cce5b3fab83c864cb774f4f0b98839 100644
--- a/node_modules/@gradio/client/dist/client.d.ts.map
+++ b/node_modules/@gradio/client/dist/client.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/constants.d.ts b/node_modules/@gradio/client/dist/constants.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3acacf2404339fc177718be4bcd1e398756dd4a2
--- /dev/null
+++ b/node_modules/@gradio/client/dist/constants.d.ts
@@ -0,0 +1,30 @@
+export declare const HOST_URL = "host";
+export declare const API_URL = "api/predict/";
+export declare const SSE_URL_V0 = "queue/join";
+export declare const SSE_DATA_URL_V0 = "queue/data";
+export declare const SSE_URL = "queue/data";
+export declare const SSE_DATA_URL = "queue/join";
+export declare const UPLOAD_URL = "upload";
+export declare const LOGIN_URL = "login";
+export declare const CONFIG_URL = "config";
+export declare const API_INFO_URL = "info";
+export declare const RUNTIME_URL = "runtime";
+export declare const SLEEPTIME_URL = "sleeptime";
+export declare const RAW_API_INFO_URL = "info?serialize=False";
+export declare const SPACE_FETCHER_URL = "https://gradio-space-api-fetcher-v2.hf.space/api";
+export declare const RESET_URL = "reset";
+export declare const SPACE_URL = "https://hf.space/{}";
+export declare const QUEUE_FULL_MSG = "This application is currently busy. Please try again. ";
+export declare const BROKEN_CONNECTION_MSG = "Connection errored out. ";
+export declare const CONFIG_ERROR_MSG = "Could not resolve app config. ";
+export declare const SPACE_STATUS_ERROR_MSG = "Could not get space status. ";
+export declare const API_INFO_ERROR_MSG = "Could not get API info. ";
+export declare const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. ";
+export declare const INVALID_URL_MSG = "Invalid URL. A full URL path is required.";
+export declare const UNAUTHORIZED_MSG = "Not authorized to access this space. ";
+export declare const INVALID_CREDENTIALS_MSG = "Invalid credentials. Could not login. ";
+export declare const MISSING_CREDENTIALS_MSG = "Login credentials are required to access this space.";
+export declare const NODEJS_FS_ERROR_MSG = "File system access is only available in Node.js environments";
+export declare const ROOT_URL_ERROR_MSG = "Root URL not found in client config";
+export declare const FILE_PROCESSING_ERROR_MSG = "Error uploading file";
+//# sourceMappingURL=constants.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/constants.d.ts.map b/node_modules/@gradio/client/dist/constants.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..90e5b5fedce4824f829cfc1ffa3fc63f1d07ff3c
--- /dev/null
+++ b/node_modules/@gradio/client/dist/constants.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,QAAQ,SAAS,CAAC;AAC/B,eAAO,MAAM,OAAO,iBAAiB,CAAC;AACtC,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,OAAO,eAAe,CAAC;AACpC,eAAO,MAAM,YAAY,eAAe,CAAC;AACzC,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,eAAO,MAAM,YAAY,SAAS,CAAC;AACnC,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,aAAa,cAAc,CAAC;AACzC,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AACvD,eAAO,MAAM,iBAAiB,qDACqB,CAAC;AACpD,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,SAAS,wBAAwB,CAAC;AAG/C,eAAO,MAAM,cAAc,2DAC8B,CAAC;AAC1D,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAChE,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AACjE,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AACrE,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAC7D,eAAO,MAAM,wBAAwB,yCAAyC,CAAC;AAC/E,eAAO,MAAM,eAAe,8CAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,0CAA0C,CAAC;AACxE,eAAO,MAAM,uBAAuB,2CAA2C,CAAC;AAChF,eAAO,MAAM,uBAAuB,yDACmB,CAAC;AACxD,eAAO,MAAM,mBAAmB,iEAC+B,CAAC;AAChE,eAAO,MAAM,kBAAkB,wCAAwC,CAAC;AACxE,eAAO,MAAM,yBAAyB,yBAAyB,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/api_info.d.ts b/node_modules/@gradio/client/dist/helpers/api_info.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3b869c24f5d891aad144e6e87f784456710adcda
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/api_info.d.ts
@@ -0,0 +1,48 @@
+import type { Status } from "../types";
+import type { ApiData, ApiInfo, Config, JsApiData } from "../types";
+export declare const RE_SPACE_NAME: RegExp;
+export declare const RE_SPACE_DOMAIN: RegExp;
+export declare function process_endpoint(app_reference: string, hf_token?: `hf_${string}`): Promise<{
+ space_id: string | false;
+ host: string;
+ ws_protocol: "ws" | "wss";
+ http_protocol: "http:" | "https:";
+}>;
+export declare const join_urls: (...urls: string[]) => string;
+export declare function transform_api_info(api_info: ApiInfo, config: Config, api_map: Record): ApiInfo;
+export declare function get_type(type: {
+ type: any;
+ description: string;
+}, component: string, serializer: string, signature_type: "return" | "parameter"): string | undefined;
+export declare function get_description(type: {
+ type: any;
+ description: string;
+}, serializer: string): string;
+export declare function handle_message(data: any, last_status: Status["stage"]): {
+ type: "hash" | "data" | "update" | "complete" | "generating" | "log" | "none" | "heartbeat" | "unexpected_error";
+ data?: any;
+ status?: Status;
+};
+/**
+ * Maps the provided `data` to the parameters defined by the `/info` endpoint response.
+ * This allows us to support both positional and keyword arguments passed to the client
+ * and ensures that all parameters are either directly provided or have default values assigned.
+ *
+ * @param {unknown[] | Record} data - The input data for the function,
+ * which can be either an array of values for positional arguments or an object
+ * with key-value pairs for keyword arguments.
+ * @param {JsApiData[]} parameters - Array of parameter descriptions retrieved from the
+ * `/info` endpoint.
+ *
+ * @returns {unknown[]} - Returns an array of resolved data where each element corresponds
+ * to the expected parameter from the API. The `parameter_default` value is used where
+ * a value is not provided for a parameter, and optional parameters without defaults are
+ * set to `undefined`.
+ *
+ * @throws {Error} - Throws an error:
+ * - If more arguments are provided than are defined in the parameters.
+ * * - If no parameter value is provided for a required parameter and no default value is defined.
+ * - If an argument is provided that does not match any defined parameter.
+ */
+export declare const map_data_to_params: (data: unknown[] | Record, api_info: ApiInfo) => unknown[];
+//# sourceMappingURL=api_info.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/api_info.d.ts.map b/node_modules/@gradio/client/dist/helpers/api_info.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..e3cffc06764ffc854a568ff9de42cf859b699320
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/api_info.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"api_info.d.ts","sourceRoot":"","sources":["../../src/helpers/api_info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOvC,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGpE,eAAO,MAAM,aAAa,QAA2C,CAAC;AACtE,eAAO,MAAM,eAAe,QAAwB,CAAC;AAErD,wBAAsB,gBAAgB,CACrC,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,MAAM,EAAE,GACvB,OAAO,CAAC;IACV,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;CAClC,CAAC,CA4CD;AAED,eAAO,MAAM,SAAS,YAAa,MAAM,EAAE,KAAG,MAU7C,CAAC;AAEF,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,SAAS,CAAC,CAsFpB;AAED,wBAAgB,QAAQ,CACvB,IAAI,EAAE;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EACxC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,QAAQ,GAAG,WAAW,GACpC,MAAM,GAAG,SAAS,CAiCpB;AAED,wBAAgB,eAAe,CAC9B,IAAI,EAAE;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EACxC,UAAU,EAAE,MAAM,GAChB,MAAM,CASR;AAGD,wBAAgB,cAAc,CAC7B,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,GAC1B;IACF,IAAI,EACD,MAAM,GACN,MAAM,GACN,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,KAAK,GACL,MAAM,GACN,WAAW,GACX,kBAAkB,CAAC;IACtB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAmHA;AAGD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,eAAO,MAAM,kBAAkB,SACxB,OAAO,EAAE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,YAC/B,QAAQ,SAAS,GAAG,OAAO,CAAC,KACpC,OAAO,EA4CT,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/data.d.ts b/node_modules/@gradio/client/dist/helpers/data.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..21650e191082bbb85d3574f70acc5d0e756c37d5
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/data.d.ts
@@ -0,0 +1,22 @@
+///
+import { type ApiData, type BlobRef, type Config, type EndpointInfo, type JsApiData, type DataType, Command, type Dependency, type ComponentMeta } from "../types";
+import { FileData } from "../upload";
+export declare function update_object(object: {
+ [x: string]: any;
+}, newValue: any, stack: (string | number)[]): void;
+export declare function walk_and_store_blobs(data: DataType, type?: string | undefined, path?: string[], root?: boolean, endpoint_info?: EndpointInfo | undefined): Promise;
+export declare function skip_queue(id: number, config: Config): boolean;
+export declare function post_message(message: any, origin: string): Promise;
+export declare function handle_file(file_or_url: File | string | Blob | Buffer): FileData | Blob | Command;
+/**
+ * Handles the payload by filtering out state inputs and returning an array of resolved payload values.
+ * We send null values for state inputs to the server, but we don't want to include them in the resolved payload.
+ *
+ * @param resolved_payload - The resolved payload values received from the client or the server
+ * @param dependency - The dependency object.
+ * @param components - The array of component metadata.
+ * @param with_null_state - Optional. Specifies whether to include null values for state inputs. Default is false.
+ * @returns An array of resolved payload values, filtered based on the dependency and component metadata.
+ */
+export declare function handle_payload(resolved_payload: unknown[], dependency: Dependency, components: ComponentMeta[], type: "input" | "output", with_null_state?: boolean): unknown[];
+//# sourceMappingURL=data.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/data.d.ts.map b/node_modules/@gradio/client/dist/helpers/data.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..5209e6d3d161898e264b0a87b17d8339f2a382d1
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/data.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/helpers/data.ts"],"names":[],"mappings":";AAAA,OAAO,EACN,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,OAAO,EACP,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAKrC,wBAAgB,aAAa,CAC5B,MAAM,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAC5B,QAAQ,EAAE,GAAG,EACb,KAAK,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GACxB,IAAI,CAgBN;AAED,wBAAsB,oBAAoB,CACzC,IAAI,EAAE,QAAQ,EACd,IAAI,GAAE,MAAM,GAAG,SAAqB,EACpC,IAAI,GAAE,MAAM,EAAO,EACnB,IAAI,UAAQ,EACZ,aAAa,GAAE,YAAY,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,SAAqB,GACtE,OAAO,CAAC,OAAO,EAAE,CAAC,CAwDpB;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAM9D;AAID,wBAAgB,YAAY,CAAC,GAAG,GAAG,GAAG,EACrC,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,GAAG,CAAC,CASd;AAED,wBAAgB,WAAW,CAC1B,WAAW,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,GACxC,QAAQ,GAAG,IAAI,GAAG,OAAO,CA8C3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,gBAAgB,EAAE,OAAO,EAAE,EAC3B,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,aAAa,EAAE,EAC3B,IAAI,EAAE,OAAO,GAAG,QAAQ,EACxB,eAAe,UAAQ,GACrB,OAAO,EAAE,CAyCX"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils.d.ts b/node_modules/@gradio/client/dist/helpers/init_helpers.d.ts
similarity index 55%
rename from node_modules/@gradio/client/dist/utils.d.ts
rename to node_modules/@gradio/client/dist/helpers/init_helpers.d.ts
index c648475f8a1c1536686c70e53cba048d2548e17f..01057464325f0a88855cd3e6746e8dd81189c703 100644
--- a/node_modules/@gradio/client/dist/utils.d.ts
+++ b/node_modules/@gradio/client/dist/helpers/init_helpers.d.ts
@@ -1,4 +1,5 @@
-import type { Config } from "./types.js";
+import type { Config } from "../types";
+import { Client } from "..";
/**
* This function is used to resolve the URL for making requests when the app has a root path.
* The root path could be a path suffix like "/app" which is appended to the end of the base URL. Or
@@ -10,23 +11,15 @@ import type { Config } from "./types.js";
* @returns {string} the resolved URL
*/
export declare function resolve_root(base_url: string, root_path: string, prioritize_base: boolean): string;
+export declare function get_jwt(space: string, token: `hf_${string}`, cookies?: string | null): Promise;
+export declare function map_names_to_ids(fns: Config["dependencies"]): Record;
+export declare function resolve_config(this: Client, endpoint: string): Promise;
+export declare function resolve_cookies(this: Client): Promise;
+export declare function get_cookie_header(http_protocol: string, host: string, auth: [string, string], _fetch: typeof fetch, hf_token?: `hf_${string}`): Promise;
export declare function determine_protocol(endpoint: string): {
ws_protocol: "ws" | "wss";
http_protocol: "http:" | "https:";
host: string;
};
-export declare const RE_SPACE_NAME: RegExp;
-export declare const RE_SPACE_DOMAIN: RegExp;
-export declare function process_endpoint(app_reference: string, token?: `hf_${string}`): Promise<{
- space_id: string | false;
- host: string;
- ws_protocol: "ws" | "wss";
- http_protocol: "http:" | "https:";
-}>;
-export declare function map_names_to_ids(fns: Config["dependencies"]): Record;
-export declare function discussions_enabled(space_id: string): Promise;
-export declare function get_space_hardware(space_id: string, token: `hf_${string}`): Promise<(typeof hardware_types)[number]>;
-export declare function set_space_hardware(space_id: string, new_hardware: (typeof hardware_types)[number], token: `hf_${string}`): Promise<(typeof hardware_types)[number]>;
-export declare function set_space_timeout(space_id: string, timeout: number, token: `hf_${string}`): Promise;
-export declare const hardware_types: readonly ["cpu-basic", "cpu-upgrade", "t4-small", "t4-medium", "a10g-small", "a10g-large", "a100-large"];
-//# sourceMappingURL=utils.d.ts.map
\ No newline at end of file
+export declare const parse_and_set_cookies: (cookie_header: string) => string[];
+//# sourceMappingURL=init_helpers.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/init_helpers.d.ts.map b/node_modules/@gradio/client/dist/helpers/init_helpers.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..ef3bbba16762ff68e88d498f715eb8f4e4f995ea
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/init_helpers.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"init_helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/init_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAUvC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAG5B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,GACtB,MAAM,CAKR;AAED,wBAAsB,OAAO,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAezB;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+C7B;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBjE;AAGD,wBAAsB,iBAAiB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EACtB,MAAM,EAAE,OAAO,KAAK,EACpB,QAAQ,CAAC,EAAE,MAAM,MAAM,EAAE,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACb,CAgCA;AAED,eAAO,MAAM,qBAAqB,kBAAmB,MAAM,KAAG,MAAM,EAUnE,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/spaces.d.ts b/node_modules/@gradio/client/dist/helpers/spaces.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6efab4c905018c4529b329a18a3adc02f624e06
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/spaces.d.ts
@@ -0,0 +1,7 @@
+import type { SpaceStatusCallback } from "../types";
+export declare function check_space_status(id: string, type: "subdomain" | "space_name", status_callback: SpaceStatusCallback): Promise;
+export declare function discussions_enabled(space_id: string): Promise;
+export declare function get_space_hardware(space_id: string, hf_token?: `hf_${string}` | undefined): Promise<(typeof hardware_types)[number]>;
+export declare function set_space_timeout(space_id: string, timeout: number, hf_token?: `hf_${string}`): Promise;
+export declare const hardware_types: readonly ["cpu-basic", "cpu-upgrade", "cpu-xl", "t4-small", "t4-medium", "a10g-small", "a10g-large", "a10g-largex2", "a10g-largex4", "a100-large", "zero-a10g", "h100", "h100x8"];
+//# sourceMappingURL=spaces.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/helpers/spaces.d.ts.map b/node_modules/@gradio/client/dist/helpers/spaces.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..68cc6df3df177851b85292a10c538275c5463f03
--- /dev/null
+++ b/node_modules/@gradio/client/dist/helpers/spaces.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"spaces.d.ts","sourceRoot":"","sources":["../../src/helpers/spaces.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,wBAAsB,kBAAkB,CACvC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,WAAW,GAAG,YAAY,EAChC,eAAe,EAAE,mBAAmB,GAClC,OAAO,CAAC,IAAI,CAAC,CAqFf;AAID,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB5E;AAED,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,MAAM,EAAE,GAAG,SAAS,GACnC,OAAO,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAqB1C;AAED,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,MAAM,EAAE,GACvB,OAAO,CAAC,GAAG,CAAC,CAiCd;AAED,eAAO,MAAM,cAAc,mLAcjB,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/index.d.ts b/node_modules/@gradio/client/dist/index.d.ts
index 0c21b54f2297fb5301cfbdcf9b557ba72d5e601e..f299d40746c097942325de20fa7068c992834ccc 100644
--- a/node_modules/@gradio/client/dist/index.d.ts
+++ b/node_modules/@gradio/client/dist/index.d.ts
@@ -1,4 +1,10 @@
-export { client, post_data, upload_files, duplicate, api_factory } from "./client.js";
-export type { SpaceStatus } from "./types.js";
-export { normalise_file, FileData, upload, get_fetchable_url_or_file, prepare_files } from "./upload.js";
+export { Client } from "./client";
+export { predict } from "./utils/predict";
+export { submit } from "./utils/submit";
+export { upload_files } from "./utils/upload_files";
+export { FileData, upload, prepare_files } from "./upload";
+export { handle_file } from "./helpers/data";
+export type { SpaceStatus, StatusMessage, Status, client_return, UploadResponse, RenderMessage, LogMessage, Payload } from "./types";
+export { client } from "./client";
+export { duplicate_space as duplicate } from "./client";
//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/index.d.ts.map b/node_modules/@gradio/client/dist/index.d.ts.map
index a40541d0bf5b1dd20e19902fce17bb739086cf2d..14065ed2bcc7f3c01134ccd29160ff2f5ea9cf92 100644
--- a/node_modules/@gradio/client/dist/index.d.ts.map
+++ b/node_modules/@gradio/client/dist/index.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,MAAM,EACN,SAAS,EACT,YAAY,EACZ,SAAS,EACT,WAAW,EACX,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACN,cAAc,EACd,QAAQ,EACR,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,MAAM,aAAa,CAAC"}
\ No newline at end of file
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,YAAY,EACX,WAAW,EACX,aAAa,EACb,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/index.js b/node_modules/@gradio/client/dist/index.js
index 34ef1d61a45c279ea9cc057f52a6ce19b9418389..d83cd4ea31fea624eae86fa286cc0d9e878c2f04 100644
--- a/node_modules/@gradio/client/dist/index.js
+++ b/node_modules/@gradio/client/dist/index.js
@@ -1,18 +1,167 @@
+var __defProp = Object.defineProperty;
+var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
+var __publicField = (obj, key, value) => {
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
+ return value;
+};
+var __accessCheck = (obj, member, msg) => {
+ if (!member.has(obj))
+ throw TypeError("Cannot " + msg);
+};
+var __privateGet = (obj, member, getter) => {
+ __accessCheck(obj, member, "read from private field");
+ return getter ? getter.call(obj) : member.get(obj);
+};
+var __privateAdd = (obj, member, value) => {
+ if (member.has(obj))
+ throw TypeError("Cannot add the same private member more than once");
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
+};
+var __privateSet = (obj, member, value, setter) => {
+ __accessCheck(obj, member, "write to private field");
+ setter ? setter.call(obj, value) : member.set(obj, value);
+ return value;
+};
+var _currentLine;
var fn = new Intl.Collator(0, { numeric: 1 }).compare;
function semiver(a, b, bool) {
a = a.split(".");
b = b.split(".");
return fn(a[0], b[0]) || fn(a[1], b[1]) || (b[2] = b.slice(2).join("."), bool = /[.-]/.test(a[2] = a.slice(2).join(".")), bool == /[.-]/.test(b[2]) ? fn(a[2], b[2]) : bool ? -1 : 1);
}
+const HOST_URL = "host";
+const UPLOAD_URL = "upload";
+const LOGIN_URL = "login";
+const CONFIG_URL = "config";
+const API_INFO_URL = "info";
+const RUNTIME_URL = "runtime";
+const SLEEPTIME_URL = "sleeptime";
+const SPACE_FETCHER_URL = "https://gradio-space-api-fetcher-v2.hf.space/api";
+const QUEUE_FULL_MSG = "This application is currently busy. Please try again. ";
+const BROKEN_CONNECTION_MSG = "Connection errored out. ";
+const CONFIG_ERROR_MSG = "Could not resolve app config. ";
+const SPACE_STATUS_ERROR_MSG = "Could not get space status. ";
+const API_INFO_ERROR_MSG = "Could not get API info. ";
+const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. ";
+const INVALID_URL_MSG = "Invalid URL. A full URL path is required.";
+const UNAUTHORIZED_MSG = "Not authorized to access this space. ";
+const INVALID_CREDENTIALS_MSG = "Invalid credentials. Could not login. ";
+const MISSING_CREDENTIALS_MSG = "Login credentials are required to access this space.";
+const NODEJS_FS_ERROR_MSG = "File system access is only available in Node.js environments";
+const ROOT_URL_ERROR_MSG = "Root URL not found in client config";
+const FILE_PROCESSING_ERROR_MSG = "Error uploading file";
function resolve_root(base_url, root_path, prioritize_base) {
if (root_path.startsWith("http://") || root_path.startsWith("https://")) {
return prioritize_base ? base_url : root_path;
}
return base_url + root_path;
}
+async function get_jwt(space, token, cookies) {
+ try {
+ const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ ...cookies ? { Cookie: cookies } : {}
+ }
+ });
+ const jwt = (await r.json()).token;
+ return jwt || false;
+ } catch (e) {
+ return false;
+ }
+}
+function map_names_to_ids(fns) {
+ let apis = {};
+ fns.forEach(({ api_name, id }) => {
+ if (api_name)
+ apis[api_name] = id;
+ });
+ return apis;
+}
+async function resolve_config(endpoint) {
+ var _a;
+ const headers = this.options.hf_token ? { Authorization: `Bearer ${this.options.hf_token}` } : {};
+ headers["Content-Type"] = "application/json";
+ if (typeof window !== "undefined" && window.gradio_config && location.origin !== "http://localhost:9876" && !window.gradio_config.dev_mode) {
+ const path = window.gradio_config.root;
+ const config = window.gradio_config;
+ let config_root = resolve_root(endpoint, config.root, false);
+ config.root = config_root;
+ return { ...config, path };
+ } else if (endpoint) {
+ const config_url = join_urls(endpoint, CONFIG_URL);
+ const response = await this.fetch(config_url, {
+ headers,
+ credentials: "include"
+ });
+ if ((response == null ? void 0 : response.status) === 401 && !this.options.auth) {
+ throw new Error(MISSING_CREDENTIALS_MSG);
+ } else if ((response == null ? void 0 : response.status) === 401 && this.options.auth) {
+ throw new Error(INVALID_CREDENTIALS_MSG);
+ }
+ if ((response == null ? void 0 : response.status) === 200) {
+ let config = await response.json();
+ config.path = config.path ?? "";
+ config.root = endpoint;
+ (_a = config.dependencies) == null ? void 0 : _a.forEach((dep, i) => {
+ if (dep.id === void 0) {
+ dep.id = i;
+ }
+ });
+ return config;
+ } else if ((response == null ? void 0 : response.status) === 401) {
+ throw new Error(UNAUTHORIZED_MSG);
+ }
+ throw new Error(CONFIG_ERROR_MSG);
+ }
+ throw new Error(CONFIG_ERROR_MSG);
+}
+async function resolve_cookies() {
+ const { http_protocol, host } = await process_endpoint(
+ this.app_reference,
+ this.options.hf_token
+ );
+ try {
+ if (this.options.auth) {
+ const cookie_header = await get_cookie_header(
+ http_protocol,
+ host,
+ this.options.auth,
+ this.fetch,
+ this.options.hf_token
+ );
+ if (cookie_header)
+ this.set_cookies(cookie_header);
+ }
+ } catch (e) {
+ throw Error(e.message);
+ }
+}
+async function get_cookie_header(http_protocol, host, auth, _fetch, hf_token) {
+ const formData = new FormData();
+ formData.append("username", auth == null ? void 0 : auth[0]);
+ formData.append("password", auth == null ? void 0 : auth[1]);
+ let headers = {};
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+ const res = await _fetch(`${http_protocol}//${host}/${LOGIN_URL}`, {
+ headers,
+ method: "POST",
+ body: formData,
+ credentials: "include"
+ });
+ if (res.status === 200) {
+ return res.headers.get("set-cookie");
+ } else if (res.status === 401) {
+ throw new Error(INVALID_CREDENTIALS_MSG);
+ } else {
+ throw new Error(SPACE_METADATA_ERROR_MSG);
+ }
+}
function determine_protocol(endpoint) {
if (endpoint.startsWith("http")) {
- const { protocol, host } = new URL(endpoint);
+ const { protocol, host, pathname } = new URL(endpoint);
if (host.endsWith("hf.space")) {
return {
ws_protocol: "wss",
@@ -23,7 +172,7 @@ function determine_protocol(endpoint) {
return {
ws_protocol: protocol === "https:" ? "wss" : "ws",
http_protocol: protocol,
- host
+ host: host + (pathname !== "/" ? pathname : "")
};
} else if (endpoint.startsWith("file:")) {
return {
@@ -39,29 +188,38 @@ function determine_protocol(endpoint) {
host: endpoint
};
}
-const RE_SPACE_NAME = /^[^\/]*\/[^\/]*$/;
+const parse_and_set_cookies = (cookie_header) => {
+ let cookies = [];
+ const parts = cookie_header.split(/,(?=\s*[^\s=;]+=[^\s=;]+)/);
+ parts.forEach((cookie) => {
+ const [cookie_name, cookie_value] = cookie.split(";")[0].split("=");
+ if (cookie_name && cookie_value) {
+ cookies.push(`${cookie_name.trim()}=${cookie_value.trim()}`);
+ }
+ });
+ return cookies;
+};
+const RE_SPACE_NAME = /^[a-zA-Z0-9_\-\.]+\/[a-zA-Z0-9_\-\.]+$/;
const RE_SPACE_DOMAIN = /.*hf\.space\/{0,1}$/;
-async function process_endpoint(app_reference, token) {
+async function process_endpoint(app_reference, hf_token) {
const headers = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
}
- const _app_reference = app_reference.trim();
+ const _app_reference = app_reference.trim().replace(/\/$/, "");
if (RE_SPACE_NAME.test(_app_reference)) {
try {
const res = await fetch(
- `https://huggingface.co/api/spaces/${_app_reference}/host`,
+ `https://huggingface.co/api/spaces/${_app_reference}/${HOST_URL}`,
{ headers }
);
- if (res.status !== 200)
- throw new Error("Space metadata could not be loaded.");
const _host = (await res.json()).host;
return {
space_id: app_reference,
...determine_protocol(_host)
};
} catch (e) {
- throw new Error("Space metadata could not be loaded." + e.message);
+ throw new Error(SPACE_METADATA_ERROR_MSG);
}
}
if (RE_SPACE_DOMAIN.test(_app_reference)) {
@@ -78,161 +236,371 @@ async function process_endpoint(app_reference, token) {
...determine_protocol(_app_reference)
};
}
-function map_names_to_ids(fns) {
- let apis = {};
- fns.forEach(({ api_name }, i) => {
- if (api_name)
- apis[api_name] = i;
- });
- return apis;
-}
-const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
-async function discussions_enabled(space_id) {
+const join_urls = (...urls) => {
try {
- const r = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/discussions`,
- {
- method: "HEAD"
- }
- );
- const error = r.headers.get("x-error-message");
- if (error && RE_DISABLED_DISCUSSION.test(error))
- return false;
- return true;
+ return urls.reduce((base_url, part) => {
+ base_url = base_url.replace(/\/+$/, "");
+ part = part.replace(/^\/+/, "");
+ return new URL(part, base_url + "/").toString();
+ });
} catch (e) {
- return false;
+ throw new Error(INVALID_URL_MSG);
}
+};
+function transform_api_info(api_info, config, api_map) {
+ const transformed_info = {
+ named_endpoints: {},
+ unnamed_endpoints: {}
+ };
+ Object.keys(api_info).forEach((category) => {
+ if (category === "named_endpoints" || category === "unnamed_endpoints") {
+ transformed_info[category] = {};
+ Object.entries(api_info[category]).forEach(
+ ([endpoint, { parameters, returns }]) => {
+ var _a, _b, _c, _d;
+ const dependencyIndex = ((_a = config.dependencies.find(
+ (dep) => dep.api_name === endpoint || dep.api_name === endpoint.replace("/", "")
+ )) == null ? void 0 : _a.id) || api_map[endpoint.replace("/", "")] || -1;
+ const dependencyTypes = dependencyIndex !== -1 ? (_b = config.dependencies.find((dep) => dep.id == dependencyIndex)) == null ? void 0 : _b.types : { continuous: false, generator: false, cancel: false };
+ if (dependencyIndex !== -1 && ((_d = (_c = config.dependencies.find((dep) => dep.id == dependencyIndex)) == null ? void 0 : _c.inputs) == null ? void 0 : _d.length) !== parameters.length) {
+ const components = config.dependencies.find((dep) => dep.id == dependencyIndex).inputs.map(
+ (input) => {
+ var _a2;
+ return (_a2 = config.components.find((c) => c.id === input)) == null ? void 0 : _a2.type;
+ }
+ );
+ try {
+ components.forEach((comp, idx) => {
+ if (comp === "state") {
+ const new_param = {
+ component: "state",
+ example: null,
+ parameter_default: null,
+ parameter_has_default: true,
+ parameter_name: null,
+ hidden: true
+ };
+ parameters.splice(idx, 0, new_param);
+ }
+ });
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ const transform_type = (data, component, serializer, signature_type) => ({
+ ...data,
+ description: get_description(data == null ? void 0 : data.type, serializer),
+ type: get_type(data == null ? void 0 : data.type, component, serializer, signature_type) || ""
+ });
+ transformed_info[category][endpoint] = {
+ parameters: parameters.map(
+ (p) => transform_type(p, p == null ? void 0 : p.component, p == null ? void 0 : p.serializer, "parameter")
+ ),
+ returns: returns.map(
+ (r) => transform_type(r, r == null ? void 0 : r.component, r == null ? void 0 : r.serializer, "return")
+ ),
+ type: dependencyTypes
+ };
+ }
+ );
+ }
+ });
+ return transformed_info;
}
-async function get_space_hardware(space_id, token) {
- const headers = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
+function get_type(type, component, serializer, signature_type) {
+ switch (type == null ? void 0 : type.type) {
+ case "string":
+ return "string";
+ case "boolean":
+ return "boolean";
+ case "number":
+ return "number";
}
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/runtime`,
- { headers }
- );
- if (res.status !== 200)
- throw new Error("Space hardware could not be obtained.");
- const { hardware } = await res.json();
- return hardware;
- } catch (e) {
- throw new Error(e.message);
+ if (serializer === "JSONSerializable" || serializer === "StringSerializable") {
+ return "any";
+ } else if (serializer === "ListStringSerializable") {
+ return "string[]";
+ } else if (component === "Image") {
+ return signature_type === "parameter" ? "Blob | File | Buffer" : "string";
+ } else if (serializer === "FileSerializable") {
+ if ((type == null ? void 0 : type.type) === "array") {
+ return signature_type === "parameter" ? "(Blob | File | Buffer)[]" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
+ }
+ return signature_type === "parameter" ? "Blob | File | Buffer" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
+ } else if (serializer === "GallerySerializable") {
+ return signature_type === "parameter" ? "[(Blob | File | Buffer), (string | null)][]" : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`;
}
}
-async function set_space_hardware(space_id, new_hardware, token) {
- const headers = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
+function get_description(type, serializer) {
+ if (serializer === "GallerySerializable") {
+ return "array of [file, label] tuples";
+ } else if (serializer === "ListStringSerializable") {
+ return "array of strings";
+ } else if (serializer === "FileSerializable") {
+ return "array of files or single file";
}
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/hardware`,
- { headers, body: JSON.stringify(new_hardware) }
- );
- if (res.status !== 200)
- throw new Error(
- "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in."
- );
- const { hardware } = await res.json();
- return hardware;
- } catch (e) {
- throw new Error(e.message);
+ return type == null ? void 0 : type.description;
+}
+function handle_message(data, last_status) {
+ const queue = true;
+ switch (data.msg) {
+ case "send_data":
+ return { type: "data" };
+ case "send_hash":
+ return { type: "hash" };
+ case "queue_full":
+ return {
+ type: "update",
+ status: {
+ queue,
+ message: QUEUE_FULL_MSG,
+ stage: "error",
+ code: data.code,
+ success: data.success
+ }
+ };
+ case "heartbeat":
+ return {
+ type: "heartbeat"
+ };
+ case "unexpected_error":
+ return {
+ type: "unexpected_error",
+ status: {
+ queue,
+ message: data.message,
+ stage: "error",
+ success: false
+ }
+ };
+ case "estimation":
+ return {
+ type: "update",
+ status: {
+ queue,
+ stage: last_status || "pending",
+ code: data.code,
+ size: data.queue_size,
+ position: data.rank,
+ eta: data.rank_eta,
+ success: data.success
+ }
+ };
+ case "progress":
+ return {
+ type: "update",
+ status: {
+ queue,
+ stage: "pending",
+ code: data.code,
+ progress_data: data.progress_data,
+ success: data.success
+ }
+ };
+ case "log":
+ return { type: "log", data };
+ case "process_generating":
+ return {
+ type: "generating",
+ status: {
+ queue,
+ message: !data.success ? data.output.error : null,
+ stage: data.success ? "generating" : "error",
+ code: data.code,
+ progress_data: data.progress_data,
+ eta: data.average_duration
+ },
+ data: data.success ? data.output : null
+ };
+ case "process_completed":
+ if ("error" in data.output) {
+ return {
+ type: "update",
+ status: {
+ queue,
+ message: data.output.error,
+ stage: "error",
+ code: data.code,
+ success: data.success
+ }
+ };
+ }
+ return {
+ type: "complete",
+ status: {
+ queue,
+ message: !data.success ? data.output.error : void 0,
+ stage: data.success ? "complete" : "error",
+ code: data.code,
+ progress_data: data.progress_data,
+ changed_state_ids: data.success ? data.output.changed_state_ids : void 0
+ },
+ data: data.success ? data.output : null
+ };
+ case "process_starts":
+ return {
+ type: "update",
+ status: {
+ queue,
+ stage: "pending",
+ code: data.code,
+ size: data.rank,
+ position: 0,
+ success: data.success,
+ eta: data.eta
+ }
+ };
}
+ return { type: "none", status: { stage: "error", queue } };
}
-async function set_space_timeout(space_id, timeout, token) {
- const headers = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
+const map_data_to_params = (data, api_info) => {
+ const parameters = Object.values(api_info.named_endpoints).flatMap(
+ (values) => values.parameters
+ );
+ if (Array.isArray(data)) {
+ if (data.length > parameters.length) {
+ console.warn("Too many arguments provided for the endpoint.");
+ }
+ return data;
}
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/hardware`,
- { headers, body: JSON.stringify({ seconds: timeout }) }
- );
- if (res.status !== 200)
+ const resolved_data = [];
+ const provided_keys = Object.keys(data);
+ parameters.forEach((param, index) => {
+ if (data.hasOwnProperty(param.parameter_name)) {
+ resolved_data[index] = data[param.parameter_name];
+ } else if (param.parameter_has_default) {
+ resolved_data[index] = param.parameter_default;
+ } else {
throw new Error(
- "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in."
+ `No value provided for required parameter: ${param.parameter_name}`
);
- const { hardware } = await res.json();
- return hardware;
- } catch (e) {
- throw new Error(e.message);
- }
-}
-const hardware_types = [
- "cpu-basic",
- "cpu-upgrade",
- "t4-small",
- "t4-medium",
- "a10g-small",
- "a10g-large",
- "a100-large"
-];
-function normalise_file(file, server_url, proxy_url) {
- if (file == null) {
- return null;
- }
- if (Array.isArray(file)) {
- const normalized_file = [];
- for (const x of file) {
- if (x == null) {
- normalized_file.push(null);
- } else {
- normalized_file.push(normalise_file(x, server_url, proxy_url));
- }
}
- return normalized_file;
- }
- if (file.is_stream) {
- if (proxy_url == null) {
- return new FileData({
- ...file,
- url: server_url + "/stream/" + file.path
- });
+ });
+ provided_keys.forEach((key) => {
+ if (!parameters.some((param) => param.parameter_name === key)) {
+ throw new Error(
+ `Parameter \`${key}\` is not a valid keyword argument. Please refer to the API for usage.`
+ );
}
- return new FileData({
- ...file,
- url: "/proxy=" + proxy_url + "stream/" + file.path
- });
- }
- return new FileData({
- ...file,
- url: get_fetchable_url_or_file(file.path, server_url, proxy_url)
});
-}
-function is_url(str) {
+ resolved_data.forEach((value, idx) => {
+ if (value === void 0 && !parameters[idx].parameter_has_default) {
+ throw new Error(
+ `No value provided for required parameter: ${parameters[idx].parameter_name}`
+ );
+ }
+ });
+ return resolved_data;
+};
+async function view_api() {
+ if (this.api_info)
+ return this.api_info;
+ const { hf_token } = this.options;
+ const { config } = this;
+ const headers = { "Content-Type": "application/json" };
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+ if (!config) {
+ return;
+ }
try {
- const url = new URL(str);
- return url.protocol === "http:" || url.protocol === "https:";
- } catch {
- return false;
+ let response;
+ if (semiver((config == null ? void 0 : config.version) || "2.0.0", "3.30") < 0) {
+ response = await this.fetch(SPACE_FETCHER_URL, {
+ method: "POST",
+ body: JSON.stringify({
+ serialize: false,
+ config: JSON.stringify(config)
+ }),
+ headers,
+ credentials: "include"
+ });
+ } else {
+ const url = join_urls(config.root, API_INFO_URL);
+ response = await this.fetch(url, {
+ headers,
+ credentials: "include"
+ });
+ }
+ if (!response.ok) {
+ throw new Error(BROKEN_CONNECTION_MSG);
+ }
+ let api_info = await response.json();
+ if ("api" in api_info) {
+ api_info = api_info.api;
+ }
+ if (api_info.named_endpoints["/predict"] && !api_info.unnamed_endpoints["0"]) {
+ api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"];
+ }
+ return transform_api_info(api_info, config, this.api_map);
+ } catch (e) {
+ "Could not get API info. " + e.message;
}
}
-function get_fetchable_url_or_file(path, server_url, proxy_url) {
- if (path == null) {
- return proxy_url ? `/proxy=${proxy_url}file=` : `${server_url}/file=`;
+async function upload_files(root_url, files, upload_id) {
+ var _a;
+ const headers = {};
+ if ((_a = this == null ? void 0 : this.options) == null ? void 0 : _a.hf_token) {
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
}
- if (is_url(path)) {
- return path;
+ const chunkSize = 1e3;
+ const uploadResponses = [];
+ let response;
+ for (let i = 0; i < files.length; i += chunkSize) {
+ const chunk = files.slice(i, i + chunkSize);
+ const formData = new FormData();
+ chunk.forEach((file) => {
+ formData.append("files", file);
+ });
+ try {
+ const upload_url = upload_id ? `${root_url}/${UPLOAD_URL}?upload_id=${upload_id}` : `${root_url}/${UPLOAD_URL}`;
+ response = await this.fetch(upload_url, {
+ method: "POST",
+ body: formData,
+ headers,
+ credentials: "include"
+ });
+ } catch (e) {
+ throw new Error(BROKEN_CONNECTION_MSG + e.message);
+ }
+ if (!response.ok) {
+ const error_text = await response.text();
+ return { error: `HTTP ${response.status}: ${error_text}` };
+ }
+ const output = await response.json();
+ if (output) {
+ uploadResponses.push(...output);
+ }
}
- return proxy_url ? `/proxy=${proxy_url}file=${path}` : `${server_url}/file=${path}`;
+ return { files: uploadResponses };
}
-async function upload(file_data, root, upload_id, upload_fn = upload_files) {
+async function upload(file_data, root_url, upload_id, max_file_size) {
let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
(file_data2) => file_data2.blob
);
+ const oversized_files = files.filter(
+ (f) => f.size > (max_file_size ?? Infinity)
+ );
+ if (oversized_files.length) {
+ throw new Error(
+ `File size exceeds the maximum allowed size of ${max_file_size} bytes: ${oversized_files.map((f) => f.name).join(", ")}`
+ );
+ }
return await Promise.all(
- await upload_fn(root, files, void 0, upload_id).then(
+ await this.upload_files(root_url, files, upload_id).then(
async (response) => {
if (response.error) {
throw new Error(response.error);
} else {
if (response.files) {
return response.files.map((f, i) => {
- const file = new FileData({ ...file_data[i], path: f });
- return normalise_file(file, root, null);
+ const file = new FileData({
+ ...file_data[i],
+ path: f,
+ url: root_url + "/file=" + f
+ });
+ return file;
});
}
return [];
@@ -243,7 +611,7 @@ async function upload(file_data, root, upload_id, upload_fn = upload_files) {
}
async function prepare_files(files, is_stream) {
return files.map(
- (f, i) => new FileData({
+ (f) => new FileData({
path: f.name,
orig_name: f.name,
blob: f,
@@ -264,6 +632,15 @@ class FileData {
mime_type,
alt_text
}) {
+ __publicField(this, "path");
+ __publicField(this, "url");
+ __publicField(this, "orig_name");
+ __publicField(this, "size");
+ __publicField(this, "blob");
+ __publicField(this, "is_stream");
+ __publicField(this, "mime_type");
+ __publicField(this, "alt_text");
+ __publicField(this, "meta", { _type: "gradio.FileData" });
this.path = path;
this.url = url;
this.orig_name = orig_name;
@@ -274,1319 +651,1831 @@ class FileData {
this.alt_text = alt_text;
}
}
-const QUEUE_FULL_MSG = "This application is too busy. Keep trying!";
-const BROKEN_CONNECTION_MSG = "Connection errored out.";
-let NodeBlob;
-async function duplicate(app_reference, options) {
- const { hf_token, private: _private, hardware, timeout } = options;
- if (hardware && !hardware_types.includes(hardware)) {
- throw new Error(
- `Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.`
- );
+class Command {
+ constructor(command, meta) {
+ __publicField(this, "type");
+ __publicField(this, "command");
+ __publicField(this, "meta");
+ __publicField(this, "fileData");
+ this.type = "command";
+ this.command = command;
+ this.meta = meta;
}
- const headers = {
- Authorization: `Bearer ${hf_token}`
- };
- const user = (await (await fetch(`https://huggingface.co/api/whoami-v2`, {
- headers
- })).json()).name;
- const space_name = app_reference.split("/")[1];
- const body = {
- repository: `${user}/${space_name}`
- };
- if (_private) {
- body.private = true;
+}
+const is_node = typeof process !== "undefined" && process.versions && process.versions.node;
+function update_object(object, newValue, stack) {
+ while (stack.length > 1) {
+ const key2 = stack.shift();
+ if (typeof key2 === "string" || typeof key2 === "number") {
+ object = object[key2];
+ } else {
+ throw new Error("Invalid key type");
+ }
}
- try {
- const response = await fetch(
- `https://huggingface.co/api/spaces/${app_reference}/duplicate`,
+ const key = stack.shift();
+ if (typeof key === "string" || typeof key === "number") {
+ object[key] = newValue;
+ } else {
+ throw new Error("Invalid key type");
+ }
+}
+async function walk_and_store_blobs(data, type = void 0, path = [], root = false, endpoint_info = void 0) {
+ if (Array.isArray(data)) {
+ let blob_refs = [];
+ await Promise.all(
+ data.map(async (_, index) => {
+ var _a;
+ let new_path = path.slice();
+ new_path.push(String(index));
+ const array_refs = await walk_and_store_blobs(
+ data[index],
+ root ? ((_a = endpoint_info == null ? void 0 : endpoint_info.parameters[index]) == null ? void 0 : _a.component) || void 0 : type,
+ new_path,
+ false,
+ endpoint_info
+ );
+ blob_refs = blob_refs.concat(array_refs);
+ })
+ );
+ return blob_refs;
+ } else if (globalThis.Buffer && data instanceof globalThis.Buffer || data instanceof Blob) {
+ return [
{
- method: "POST",
- headers: { "Content-Type": "application/json", ...headers },
- body: JSON.stringify(body)
+ path,
+ blob: new Blob([data]),
+ type
}
- );
- if (response.status === 409) {
- return client(`${user}/${space_name}`, options);
- }
- const duplicated_space = await response.json();
- let original_hardware;
- if (!hardware) {
- original_hardware = await get_space_hardware(app_reference, hf_token);
+ ];
+ } else if (typeof data === "object" && data !== null) {
+ let blob_refs = [];
+ for (const key of Object.keys(data)) {
+ const new_path = [...path, key];
+ const value = data[key];
+ blob_refs = blob_refs.concat(
+ await walk_and_store_blobs(
+ value,
+ void 0,
+ new_path,
+ false,
+ endpoint_info
+ )
+ );
}
- const requested_hardware = hardware || original_hardware || "cpu-basic";
- await set_space_hardware(
- `${user}/${space_name}`,
- requested_hardware,
- hf_token
- );
- await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
- return client(duplicated_space.url, options);
- } catch (e) {
- throw new Error(e);
+ return blob_refs;
+ }
+ return [];
+}
+function skip_queue(id, config) {
+ var _a, _b;
+ let fn_queue = (_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a.find((dep) => dep.id == id)) == null ? void 0 : _b.queue;
+ if (fn_queue != null) {
+ return !fn_queue;
}
+ return !config.enable_queue;
+}
+function post_message(message, origin) {
+ return new Promise((res, _rej) => {
+ const channel = new MessageChannel();
+ channel.port1.onmessage = ({ data }) => {
+ channel.port1.close();
+ res(data);
+ };
+ window.parent.postMessage(message, origin, [channel.port2]);
+ });
}
-function api_factory(fetch_implementation, EventSource_factory) {
- return { post_data: post_data2, upload_files: upload_files2, client: client2, handle_blob: handle_blob2 };
- async function post_data2(url, body, token) {
- const headers = { "Content-Type": "application/json" };
- if (token) {
- headers.Authorization = `Bearer ${token}`;
+function handle_file(file_or_url) {
+ if (typeof file_or_url === "string") {
+ if (file_or_url.startsWith("http://") || file_or_url.startsWith("https://")) {
+ return {
+ path: file_or_url,
+ url: file_or_url,
+ orig_name: file_or_url.split("/").pop() ?? "unknown",
+ meta: { _type: "gradio.FileData" }
+ };
}
- try {
- var response = await fetch_implementation(url, {
- method: "POST",
- body: JSON.stringify(body),
- headers
+ if (is_node) {
+ return new Command("upload_file", {
+ path: file_or_url,
+ name: file_or_url,
+ orig_path: file_or_url
});
- } catch (e) {
- return [{ error: BROKEN_CONNECTION_MSG }, 500];
}
- let output;
- let status;
- try {
- output = await response.json();
- status = response.status;
- } catch (e) {
- output = { error: `Could not parse server response: ${e}` };
- status = 500;
+ } else if (typeof File !== "undefined" && file_or_url instanceof File) {
+ return {
+ path: file_or_url instanceof File ? file_or_url.name : "blob",
+ orig_name: file_or_url instanceof File ? file_or_url.name : "unknown",
+ // @ts-ignore
+ blob: file_or_url instanceof File ? file_or_url : new Blob([file_or_url]),
+ size: file_or_url instanceof Blob ? file_or_url.size : Buffer.byteLength(file_or_url),
+ mime_type: file_or_url instanceof File ? file_or_url.type : "application/octet-stream",
+ // Default MIME type for buffers
+ meta: { _type: "gradio.FileData" }
+ };
+ } else if (file_or_url instanceof Buffer) {
+ return new Blob([file_or_url]);
+ } else if (file_or_url instanceof Blob) {
+ return file_or_url;
+ }
+ throw new Error(
+ "Invalid input: must be a URL, File, Blob, or Buffer object."
+ );
+}
+function handle_payload(resolved_payload, dependency, components, type, with_null_state = false) {
+ if (type === "input" && !with_null_state) {
+ throw new Error("Invalid code path. Cannot skip state inputs for input.");
+ }
+ if (type === "output" && with_null_state) {
+ return resolved_payload;
+ }
+ let updated_payload = [];
+ let payload_index = 0;
+ for (let i = 0; i < dependency.inputs.length; i++) {
+ const input_id = dependency.inputs[i];
+ const component = components.find((c) => c.id === input_id);
+ if ((component == null ? void 0 : component.type) === "state") {
+ if (with_null_state) {
+ if (resolved_payload.length === dependency.inputs.length) {
+ const value = resolved_payload[payload_index];
+ updated_payload.push(value);
+ payload_index++;
+ } else {
+ updated_payload.push(null);
+ }
+ } else {
+ payload_index++;
+ continue;
+ }
+ continue;
+ } else {
+ const value = resolved_payload[payload_index];
+ updated_payload.push(value);
+ payload_index++;
}
- return [output, status];
}
- async function upload_files2(root, files, token, upload_id) {
- const headers = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
+ return updated_payload;
+}
+async function handle_blob(endpoint, data, api_info) {
+ const self = this;
+ await process_local_file_commands(self, data);
+ const blobRefs = await walk_and_store_blobs(
+ data,
+ void 0,
+ [],
+ true,
+ api_info
+ );
+ const results = await Promise.all(
+ blobRefs.map(async ({ path, blob, type }) => {
+ if (!blob)
+ return { path, type };
+ const response = await self.upload_files(endpoint, [blob]);
+ const file_url = response.files && response.files[0];
+ return {
+ path,
+ file_url,
+ type,
+ name: blob instanceof File ? blob == null ? void 0 : blob.name : void 0
+ };
+ })
+ );
+ results.forEach(({ path, file_url, type, name }) => {
+ if (type === "Gallery") {
+ update_object(data, file_url, path);
+ } else if (file_url) {
+ const file = new FileData({ path: file_url, orig_name: name });
+ update_object(data, file, path);
+ }
+ });
+ return data;
+}
+async function process_local_file_commands(client2, data) {
+ var _a, _b;
+ const root = ((_a = client2.config) == null ? void 0 : _a.root) || ((_b = client2.config) == null ? void 0 : _b.root_url);
+ if (!root) {
+ throw new Error(ROOT_URL_ERROR_MSG);
+ }
+ await recursively_process_commands(client2, data);
+}
+async function recursively_process_commands(client2, data, path = []) {
+ for (const key in data) {
+ if (data[key] instanceof Command) {
+ await process_single_command(client2, data, key);
+ } else if (typeof data[key] === "object" && data[key] !== null) {
+ await recursively_process_commands(client2, data[key], [...path, key]);
}
- const chunkSize = 1e3;
- const uploadResponses = [];
- for (let i = 0; i < files.length; i += chunkSize) {
- const chunk = files.slice(i, i + chunkSize);
- const formData = new FormData();
- chunk.forEach((file) => {
- formData.append("files", file);
+ }
+}
+async function process_single_command(client2, data, key) {
+ var _a, _b;
+ let cmd_item = data[key];
+ const root = ((_a = client2.config) == null ? void 0 : _a.root) || ((_b = client2.config) == null ? void 0 : _b.root_url);
+ if (!root) {
+ throw new Error(ROOT_URL_ERROR_MSG);
+ }
+ try {
+ let fileBuffer;
+ let fullPath;
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
+ const fs = await import("fs/promises");
+ const path = await import("path");
+ fullPath = path.resolve(process.cwd(), cmd_item.meta.path);
+ fileBuffer = await fs.readFile(fullPath);
+ } else {
+ throw new Error(NODEJS_FS_ERROR_MSG);
+ }
+ const file = new Blob([fileBuffer], { type: "application/octet-stream" });
+ const response = await client2.upload_files(root, [file]);
+ const file_url = response.files && response.files[0];
+ if (file_url) {
+ const fileData = new FileData({
+ path: file_url,
+ orig_name: cmd_item.meta.name || ""
});
- try {
- const upload_url = upload_id ? `${root}/upload?upload_id=${upload_id}` : `${root}/upload`;
- var response = await fetch_implementation(upload_url, {
- method: "POST",
- body: formData,
- headers
- });
- } catch (e) {
- return { error: BROKEN_CONNECTION_MSG };
- }
- const output = await response.json();
- uploadResponses.push(...output);
+ data[key] = fileData;
}
- return { files: uploadResponses };
- }
- async function client2(app_reference, options = { normalise_files: true }) {
- return new Promise(async (res) => {
- const { status_callback, hf_token, normalise_files } = options;
- const return_obj = {
- predict,
- submit,
- view_api,
- component_server
- };
- const transform_files = normalise_files ?? true;
- if ((typeof window === "undefined" || !("WebSocket" in window)) && !global.Websocket) {
- const ws = await import("./wrapper-6f348d45.js");
- NodeBlob = (await import("node:buffer")).Blob;
- global.WebSocket = ws.WebSocket;
- }
- const { ws_protocol, http_protocol, host, space_id } = await process_endpoint(app_reference, hf_token);
- const session_hash = Math.random().toString(36).substring(2);
- const last_status = {};
- let stream_open = false;
- let pending_stream_messages = {};
- let event_stream = null;
- const event_callbacks = {};
- const unclosed_events = /* @__PURE__ */ new Set();
- let config;
- let api_map = {};
- let jwt = false;
- if (hf_token && space_id) {
- jwt = await get_jwt(space_id, hf_token);
- }
- async function config_success(_config) {
- config = _config;
- api_map = map_names_to_ids((_config == null ? void 0 : _config.dependencies) || []);
- if (config.auth_required) {
- return {
- config,
- ...return_obj
- };
- }
- try {
- api = await view_api(config);
- } catch (e) {
- console.error(`Could not get api details: ${e.message}`);
+ } catch (error) {
+ console.error(FILE_PROCESSING_ERROR_MSG, error);
+ }
+}
+async function post_data(url, body, additional_headers) {
+ const headers = { "Content-Type": "application/json" };
+ if (this.options.hf_token) {
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
+ }
+ try {
+ var response = await this.fetch(url, {
+ method: "POST",
+ body: JSON.stringify(body),
+ headers: { ...headers, ...additional_headers },
+ credentials: "include"
+ });
+ } catch (e) {
+ return [{ error: BROKEN_CONNECTION_MSG }, 500];
+ }
+ let output;
+ let status;
+ try {
+ output = await response.json();
+ status = response.status;
+ } catch (e) {
+ output = { error: `Could not parse server response: ${e}` };
+ status = 500;
+ }
+ return [output, status];
+}
+async function predict(endpoint, data) {
+ let data_returned = false;
+ let status_complete = false;
+ let dependency;
+ if (!this.config) {
+ throw new Error("Could not resolve app config");
+ }
+ if (typeof endpoint === "number") {
+ dependency = this.config.dependencies.find((dep) => dep.id == endpoint);
+ } else {
+ const trimmed_endpoint = endpoint.replace(/^\//, "");
+ dependency = this.config.dependencies.find(
+ (dep) => dep.id == this.api_map[trimmed_endpoint]
+ );
+ }
+ if (dependency == null ? void 0 : dependency.types.continuous) {
+ throw new Error(
+ "Cannot call predict on this function as it may run forever. Use submit instead"
+ );
+ }
+ return new Promise(async (resolve, reject) => {
+ const app = this.submit(endpoint, data, null, null, true);
+ let result;
+ for await (const message of app) {
+ if (message.type === "data") {
+ if (status_complete) {
+ resolve(result);
}
- return {
- config,
- ...return_obj
- };
+ data_returned = true;
+ result = message;
}
- let api;
- async function handle_space_sucess(status) {
- if (status_callback)
- status_callback(status);
- if (status.status === "running")
- try {
- config = await resolve_config(
- fetch_implementation,
- `${http_protocol}//${host}`,
- hf_token
- );
- const _config = await config_success(config);
- res(_config);
- } catch (e) {
- console.error(e);
- if (status_callback) {
- status_callback({
- status: "error",
- message: "Could not load this space.",
- load_status: "error",
- detail: "NOT_FOUND"
- });
- }
+ if (message.type === "status") {
+ if (message.stage === "error")
+ reject(message);
+ if (message.stage === "complete") {
+ status_complete = true;
+ if (data_returned) {
+ resolve(result);
}
- }
- try {
- config = await resolve_config(
- fetch_implementation,
- `${http_protocol}//${host}`,
- hf_token
- );
- const _config = await config_success(config);
- res(_config);
- } catch (e) {
- console.error(e);
- if (space_id) {
- check_space_status(
- space_id,
- RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain",
- handle_space_sucess
- );
- } else {
- if (status_callback)
- status_callback({
- status: "error",
- message: "Could not load this space.",
- load_status: "error",
- detail: "NOT_FOUND"
- });
- }
- }
- function predict(endpoint, data, event_data) {
- let data_returned = false;
- let status_complete = false;
- let dependency;
- if (typeof endpoint === "number") {
- dependency = config.dependencies[endpoint];
- } else {
- const trimmed_endpoint = endpoint.replace(/^\//, "");
- dependency = config.dependencies[api_map[trimmed_endpoint]];
- }
- if (dependency.types.continuous) {
- throw new Error(
- "Cannot call predict on this function as it may run forever. Use submit instead"
- );
}
- return new Promise((res2, rej) => {
- const app = submit(endpoint, data, event_data);
- let result;
- app.on("data", (d) => {
- if (status_complete) {
- app.destroy();
- res2(d);
- }
- data_returned = true;
- result = d;
- }).on("status", (status) => {
- if (status.stage === "error")
- rej(status);
- if (status.stage === "complete") {
- status_complete = true;
- if (data_returned) {
- app.destroy();
- res2(result);
- }
- }
- });
- });
}
- function submit(endpoint, data, event_data, trigger_id = null) {
- let fn_index;
- let api_info;
- if (typeof endpoint === "number") {
- fn_index = endpoint;
- api_info = api.unnamed_endpoints[fn_index];
- } else {
- const trimmed_endpoint = endpoint.replace(/^\//, "");
- fn_index = api_map[trimmed_endpoint];
- api_info = api.named_endpoints[endpoint.trim()];
- }
- if (typeof fn_index !== "number") {
- throw new Error(
- "There is no endpoint matching that name of fn_index matching that number."
- );
- }
- let websocket;
- let eventSource;
- let protocol = config.protocol ?? "ws";
- const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
- let payload;
- let event_id = null;
- let complete = false;
- const listener_map = {};
- let url_params = "";
- if (typeof window !== "undefined") {
- url_params = new URLSearchParams(window.location.search).toString();
- }
- handle_blob2(`${config.root}`, data, api_info, hf_token).then(
- (_payload) => {
- payload = {
- data: _payload || [],
- event_data,
- fn_index,
- trigger_id
- };
- if (skip_queue(fn_index, config)) {
- fire_event({
- type: "status",
- endpoint: _endpoint,
- stage: "pending",
- queue: false,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- post_data2(
- `${config.root}/run${_endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`}${url_params ? "?" + url_params : ""}`,
- {
- ...payload,
- session_hash
- },
- hf_token
- ).then(([output, status_code]) => {
- const data2 = transform_files ? transform_output(
- output.data,
- api_info,
- config.root,
- config.root_url
- ) : output.data;
- if (status_code == 200) {
- fire_event({
- type: "data",
- endpoint: _endpoint,
- fn_index,
- data: data2,
- time: /* @__PURE__ */ new Date()
- });
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- stage: "complete",
- eta: output.average_duration,
- queue: false,
- time: /* @__PURE__ */ new Date()
- });
- } else {
- fire_event({
- type: "status",
- stage: "error",
- endpoint: _endpoint,
- fn_index,
- message: output.error,
- queue: false,
- time: /* @__PURE__ */ new Date()
- });
- }
- }).catch((e) => {
- fire_event({
- type: "status",
- stage: "error",
- message: e.message,
- endpoint: _endpoint,
- fn_index,
- queue: false,
- time: /* @__PURE__ */ new Date()
- });
- });
- } else if (protocol == "ws") {
- fire_event({
- type: "status",
- stage: "pending",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- let url = new URL(`${ws_protocol}://${resolve_root(
- host,
- config.path,
- true
- )}
- /queue/join${url_params ? "?" + url_params : ""}`);
- if (jwt) {
- url.searchParams.set("__sign", jwt);
+ }
+ });
+}
+async function check_space_status(id, type, status_callback) {
+ let endpoint = type === "subdomain" ? `https://huggingface.co/api/spaces/by-subdomain/${id}` : `https://huggingface.co/api/spaces/${id}`;
+ let response;
+ let _status;
+ try {
+ response = await fetch(endpoint);
+ _status = response.status;
+ if (_status !== 200) {
+ throw new Error();
+ }
+ response = await response.json();
+ } catch (e) {
+ status_callback({
+ status: "error",
+ load_status: "error",
+ message: SPACE_STATUS_ERROR_MSG,
+ detail: "NOT_FOUND"
+ });
+ return;
+ }
+ if (!response || _status !== 200)
+ return;
+ const {
+ runtime: { stage },
+ id: space_name
+ } = response;
+ switch (stage) {
+ case "STOPPED":
+ case "SLEEPING":
+ status_callback({
+ status: "sleeping",
+ load_status: "pending",
+ message: "Space is asleep. Waking it up...",
+ detail: stage
+ });
+ setTimeout(() => {
+ check_space_status(id, type, status_callback);
+ }, 1e3);
+ break;
+ case "PAUSED":
+ status_callback({
+ status: "paused",
+ load_status: "error",
+ message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
+ detail: stage,
+ discussions_enabled: await discussions_enabled(space_name)
+ });
+ break;
+ case "RUNNING":
+ case "RUNNING_BUILDING":
+ status_callback({
+ status: "running",
+ load_status: "complete",
+ message: "",
+ detail: stage
+ });
+ break;
+ case "BUILDING":
+ status_callback({
+ status: "building",
+ load_status: "pending",
+ message: "Space is building...",
+ detail: stage
+ });
+ setTimeout(() => {
+ check_space_status(id, type, status_callback);
+ }, 1e3);
+ break;
+ default:
+ status_callback({
+ status: "space_error",
+ load_status: "error",
+ message: "This space is experiencing an issue.",
+ detail: stage,
+ discussions_enabled: await discussions_enabled(space_name)
+ });
+ break;
+ }
+}
+const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
+async function discussions_enabled(space_id) {
+ try {
+ const r = await fetch(
+ `https://huggingface.co/api/spaces/${space_id}/discussions`,
+ {
+ method: "HEAD"
+ }
+ );
+ const error = r.headers.get("x-error-message");
+ if (!r.ok || error && RE_DISABLED_DISCUSSION.test(error))
+ return false;
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+async function get_space_hardware(space_id, hf_token) {
+ const headers = {};
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+ try {
+ const res = await fetch(
+ `https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`,
+ { headers }
+ );
+ if (res.status !== 200)
+ throw new Error("Space hardware could not be obtained.");
+ const { hardware } = await res.json();
+ return hardware.current;
+ } catch (e) {
+ throw new Error(e.message);
+ }
+}
+async function set_space_timeout(space_id, timeout, hf_token) {
+ const headers = {};
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+ const body = {
+ seconds: timeout
+ };
+ try {
+ const res = await fetch(
+ `https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`,
+ {
+ method: "POST",
+ headers: { "Content-Type": "application/json", ...headers },
+ body: JSON.stringify(body)
+ }
+ );
+ if (res.status !== 200) {
+ throw new Error(
+ "Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges."
+ );
+ }
+ const response = await res.json();
+ return response;
+ } catch (e) {
+ throw new Error(e.message);
+ }
+}
+const hardware_types = [
+ "cpu-basic",
+ "cpu-upgrade",
+ "cpu-xl",
+ "t4-small",
+ "t4-medium",
+ "a10g-small",
+ "a10g-large",
+ "a10g-largex2",
+ "a10g-largex4",
+ "a100-large",
+ "zero-a10g",
+ "h100",
+ "h100x8"
+];
+async function duplicate(app_reference, options) {
+ const { hf_token, private: _private, hardware, timeout, auth } = options;
+ if (hardware && !hardware_types.includes(hardware)) {
+ throw new Error(
+ `Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.`
+ );
+ }
+ const { http_protocol, host } = await process_endpoint(
+ app_reference,
+ hf_token
+ );
+ let cookies = null;
+ if (auth) {
+ const cookie_header = await get_cookie_header(
+ http_protocol,
+ host,
+ auth,
+ fetch
+ );
+ if (cookie_header)
+ cookies = parse_and_set_cookies(cookie_header);
+ }
+ const headers = {
+ Authorization: `Bearer ${hf_token}`,
+ "Content-Type": "application/json",
+ ...cookies ? { Cookie: cookies.join("; ") } : {}
+ };
+ const user = (await (await fetch(`https://huggingface.co/api/whoami-v2`, {
+ headers
+ })).json()).name;
+ const space_name = app_reference.split("/")[1];
+ const body = {
+ repository: `${user}/${space_name}`
+ };
+ if (_private) {
+ body.private = true;
+ }
+ let original_hardware;
+ try {
+ if (!hardware) {
+ original_hardware = await get_space_hardware(app_reference, hf_token);
+ }
+ } catch (e) {
+ throw Error(SPACE_METADATA_ERROR_MSG + e.message);
+ }
+ const requested_hardware = hardware || original_hardware || "cpu-basic";
+ body.hardware = requested_hardware;
+ try {
+ const response = await fetch(
+ `https://huggingface.co/api/spaces/${app_reference}/duplicate`,
+ {
+ method: "POST",
+ headers,
+ body: JSON.stringify(body)
+ }
+ );
+ if (response.status === 409) {
+ try {
+ const client2 = await Client.connect(`${user}/${space_name}`, options);
+ return client2;
+ } catch (error) {
+ console.error("Failed to connect Client instance:", error);
+ throw error;
+ }
+ } else if (response.status !== 200) {
+ throw new Error(response.statusText);
+ }
+ const duplicated_space = await response.json();
+ await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
+ return await Client.connect(
+ get_space_reference(duplicated_space.url),
+ options
+ );
+ } catch (e) {
+ throw new Error(e);
+ }
+}
+function get_space_reference(url) {
+ const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
+ const match = url.match(regex);
+ if (match) {
+ return match[1];
+ }
+}
+class TextLineStream extends TransformStream {
+ /** Constructs a new instance. */
+ constructor(options = { allowCR: false }) {
+ super({
+ transform: (chars, controller) => {
+ chars = __privateGet(this, _currentLine) + chars;
+ while (true) {
+ const lfIndex = chars.indexOf("\n");
+ const crIndex = options.allowCR ? chars.indexOf("\r") : -1;
+ if (crIndex !== -1 && crIndex !== chars.length - 1 && (lfIndex === -1 || lfIndex - 1 > crIndex)) {
+ controller.enqueue(chars.slice(0, crIndex));
+ chars = chars.slice(crIndex + 1);
+ continue;
+ }
+ if (lfIndex === -1)
+ break;
+ const endIndex = chars[lfIndex - 1] === "\r" ? lfIndex - 1 : lfIndex;
+ controller.enqueue(chars.slice(0, endIndex));
+ chars = chars.slice(lfIndex + 1);
+ }
+ __privateSet(this, _currentLine, chars);
+ },
+ flush: (controller) => {
+ if (__privateGet(this, _currentLine) === "")
+ return;
+ const currentLine = options.allowCR && __privateGet(this, _currentLine).endsWith("\r") ? __privateGet(this, _currentLine).slice(0, -1) : __privateGet(this, _currentLine);
+ controller.enqueue(currentLine);
+ }
+ });
+ __privateAdd(this, _currentLine, "");
+ }
+}
+_currentLine = new WeakMap();
+function stream$1(input) {
+ let decoder = new TextDecoderStream();
+ let split2 = new TextLineStream({ allowCR: true });
+ return input.pipeThrough(decoder).pipeThrough(split2);
+}
+function split(input) {
+ let rgx = /[:]\s*/;
+ let match = rgx.exec(input);
+ let idx = match && match.index;
+ if (idx) {
+ return [
+ input.substring(0, idx),
+ input.substring(idx + match[0].length)
+ ];
+ }
+}
+function fallback(headers, key, value) {
+ let tmp = headers.get(key);
+ if (!tmp)
+ headers.set(key, value);
+}
+async function* events(res, signal) {
+ if (!res.body)
+ return;
+ let iter = stream$1(res.body);
+ let line, reader = iter.getReader();
+ let event;
+ for (; ; ) {
+ if (signal && signal.aborted) {
+ return reader.cancel();
+ }
+ line = await reader.read();
+ if (line.done)
+ return;
+ if (!line.value) {
+ if (event)
+ yield event;
+ event = void 0;
+ continue;
+ }
+ let [field, value] = split(line.value) || [];
+ if (!field)
+ continue;
+ if (field === "data") {
+ event || (event = {});
+ event[field] = event[field] ? event[field] + "\n" + value : value;
+ } else if (field === "event") {
+ event || (event = {});
+ event[field] = value;
+ } else if (field === "id") {
+ event || (event = {});
+ event[field] = +value || value;
+ } else if (field === "retry") {
+ event || (event = {});
+ event[field] = +value || void 0;
+ }
+ }
+}
+async function stream(input, init) {
+ let req = new Request(input, init);
+ fallback(req.headers, "Accept", "text/event-stream");
+ fallback(req.headers, "Content-Type", "application/json");
+ let r = await fetch(req);
+ if (!r.ok)
+ throw r;
+ return events(r, req.signal);
+}
+async function open_stream() {
+ let {
+ event_callbacks,
+ unclosed_events,
+ pending_stream_messages,
+ stream_status,
+ config,
+ jwt
+ } = this;
+ const that = this;
+ if (!config) {
+ throw new Error("Could not resolve app config");
+ }
+ stream_status.open = true;
+ let stream2 = null;
+ let params = new URLSearchParams({
+ session_hash: this.session_hash
+ }).toString();
+ let url = new URL(`${config.root}/queue/data?${params}`);
+ if (jwt) {
+ url.searchParams.set("__sign", jwt);
+ }
+ stream2 = this.stream(url);
+ if (!stream2) {
+ console.warn("Cannot connect to SSE endpoint: " + url.toString());
+ return;
+ }
+ stream2.onmessage = async function(event) {
+ let _data = JSON.parse(event.data);
+ if (_data.msg === "close_stream") {
+ close_stream(stream_status, that.abort_controller);
+ return;
+ }
+ const event_id = _data.event_id;
+ if (!event_id) {
+ await Promise.all(
+ Object.keys(event_callbacks).map(
+ (event_id2) => event_callbacks[event_id2](_data)
+ )
+ );
+ } else if (event_callbacks[event_id] && config) {
+ if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1", "sse_v3"].includes(
+ config.protocol
+ )) {
+ unclosed_events.delete(event_id);
+ }
+ let fn2 = event_callbacks[event_id];
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
+ setTimeout(fn2, 0, _data);
+ } else {
+ fn2(_data);
+ }
+ } else {
+ if (!pending_stream_messages[event_id]) {
+ pending_stream_messages[event_id] = [];
+ }
+ pending_stream_messages[event_id].push(_data);
+ }
+ };
+ stream2.onerror = async function() {
+ await Promise.all(
+ Object.keys(event_callbacks).map(
+ (event_id) => event_callbacks[event_id]({
+ msg: "unexpected_error",
+ message: BROKEN_CONNECTION_MSG
+ })
+ )
+ );
+ };
+}
+function close_stream(stream_status, abort_controller) {
+ if (stream_status) {
+ stream_status.open = false;
+ abort_controller == null ? void 0 : abort_controller.abort();
+ }
+}
+function apply_diff_stream(pending_diff_streams, event_id, data) {
+ let is_first_generation = !pending_diff_streams[event_id];
+ if (is_first_generation) {
+ pending_diff_streams[event_id] = [];
+ data.data.forEach((value, i) => {
+ pending_diff_streams[event_id][i] = value;
+ });
+ } else {
+ data.data.forEach((value, i) => {
+ let new_data = apply_diff(pending_diff_streams[event_id][i], value);
+ pending_diff_streams[event_id][i] = new_data;
+ data.data[i] = new_data;
+ });
+ }
+}
+function apply_diff(obj, diff) {
+ diff.forEach(([action, path, value]) => {
+ obj = apply_edit(obj, path, action, value);
+ });
+ return obj;
+}
+function apply_edit(target, path, action, value) {
+ if (path.length === 0) {
+ if (action === "replace") {
+ return value;
+ } else if (action === "append") {
+ return target + value;
+ }
+ throw new Error(`Unsupported action: ${action}`);
+ }
+ let current = target;
+ for (let i = 0; i < path.length - 1; i++) {
+ current = current[path[i]];
+ }
+ const last_path = path[path.length - 1];
+ switch (action) {
+ case "replace":
+ current[last_path] = value;
+ break;
+ case "append":
+ current[last_path] += value;
+ break;
+ case "add":
+ if (Array.isArray(current)) {
+ current.splice(Number(last_path), 0, value);
+ } else {
+ current[last_path] = value;
+ }
+ break;
+ case "delete":
+ if (Array.isArray(current)) {
+ current.splice(Number(last_path), 1);
+ } else {
+ delete current[last_path];
+ }
+ break;
+ default:
+ throw new Error(`Unknown action: ${action}`);
+ }
+ return target;
+}
+function readable_stream(input, init = {}) {
+ const instance = {
+ close: () => {
+ throw new Error("Method not implemented.");
+ },
+ onerror: null,
+ onmessage: null,
+ onopen: null,
+ readyState: 0,
+ url: input.toString(),
+ withCredentials: false,
+ CONNECTING: 0,
+ OPEN: 1,
+ CLOSED: 2,
+ addEventListener: () => {
+ throw new Error("Method not implemented.");
+ },
+ dispatchEvent: () => {
+ throw new Error("Method not implemented.");
+ },
+ removeEventListener: () => {
+ throw new Error("Method not implemented.");
+ }
+ };
+ stream(input, init).then(async (res) => {
+ instance.readyState = instance.OPEN;
+ try {
+ for await (const chunk of res) {
+ instance.onmessage && instance.onmessage(chunk);
+ }
+ instance.readyState = instance.CLOSED;
+ } catch (e) {
+ instance.onerror && instance.onerror(e);
+ instance.readyState = instance.CLOSED;
+ }
+ }).catch((e) => {
+ console.error(e);
+ instance.onerror && instance.onerror(e);
+ instance.readyState = instance.CLOSED;
+ });
+ return instance;
+}
+function submit(endpoint, data, event_data, trigger_id, all_events) {
+ var _a;
+ try {
+ let fire_event = function(event) {
+ if (all_events || events_to_publish[event.type]) {
+ push_event(event);
+ }
+ }, close = function() {
+ done = true;
+ while (resolvers.length > 0)
+ resolvers.shift()({
+ value: void 0,
+ done: true
+ });
+ }, push = function(data2) {
+ if (done)
+ return;
+ if (resolvers.length > 0) {
+ resolvers.shift()(data2);
+ } else {
+ values.push(data2);
+ }
+ }, push_error = function(error) {
+ push(thenable_reject(error));
+ close();
+ }, push_event = function(event) {
+ push({ value: event, done: false });
+ }, next = function() {
+ if (values.length > 0)
+ return Promise.resolve(values.shift());
+ if (done)
+ return Promise.resolve({ value: void 0, done: true });
+ return new Promise((resolve) => resolvers.push(resolve));
+ };
+ const { hf_token } = this.options;
+ const {
+ fetch: fetch2,
+ app_reference,
+ config,
+ session_hash,
+ api_info,
+ api_map,
+ stream_status,
+ pending_stream_messages,
+ pending_diff_streams,
+ event_callbacks,
+ unclosed_events,
+ post_data: post_data2,
+ options
+ } = this;
+ const that = this;
+ if (!api_info)
+ throw new Error("No API found");
+ if (!config)
+ throw new Error("Could not resolve app config");
+ let { fn_index, endpoint_info, dependency } = get_endpoint_info(
+ api_info,
+ endpoint,
+ api_map,
+ config
+ );
+ let resolved_data = map_data_to_params(data, api_info);
+ let websocket;
+ let stream2;
+ let protocol = config.protocol ?? "ws";
+ const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
+ let payload;
+ let event_id = null;
+ let complete = false;
+ let last_status = {};
+ let url_params = typeof window !== "undefined" && typeof document !== "undefined" ? new URLSearchParams(window.location.search).toString() : "";
+ const events_to_publish = ((_a = options == null ? void 0 : options.events) == null ? void 0 : _a.reduce(
+ (acc, event) => {
+ acc[event] = true;
+ return acc;
+ },
+ {}
+ )) || {};
+ async function cancel() {
+ const _status = {
+ stage: "complete",
+ queue: false,
+ time: /* @__PURE__ */ new Date()
+ };
+ complete = _status;
+ fire_event({
+ ..._status,
+ type: "status",
+ endpoint: _endpoint,
+ fn_index
+ });
+ let reset_request = {};
+ let cancel_request = {};
+ if (protocol === "ws") {
+ if (websocket && websocket.readyState === 0) {
+ websocket.addEventListener("open", () => {
+ websocket.close();
+ });
+ } else {
+ websocket.close();
+ }
+ reset_request = { fn_index, session_hash };
+ } else {
+ close_stream(stream_status, that.abort_controller);
+ close();
+ reset_request = { event_id };
+ cancel_request = { event_id, session_hash, fn_index };
+ }
+ try {
+ if (!config) {
+ throw new Error("Could not resolve app config");
+ }
+ if ("event_id" in cancel_request) {
+ await fetch2(`${config.root}/cancel`, {
+ headers: { "Content-Type": "application/json" },
+ method: "POST",
+ body: JSON.stringify(cancel_request)
+ });
+ }
+ await fetch2(`${config.root}/reset`, {
+ headers: { "Content-Type": "application/json" },
+ method: "POST",
+ body: JSON.stringify(reset_request)
+ });
+ } catch (e) {
+ console.warn(
+ "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable."
+ );
+ }
+ }
+ const resolve_heartbeat = async (config2) => {
+ await this._resolve_hearbeat(config2);
+ };
+ async function handle_render_config(render_config) {
+ if (!config)
+ return;
+ let render_id = render_config.render_id;
+ config.components = [
+ ...config.components.filter((c) => c.props.rendered_in !== render_id),
+ ...render_config.components
+ ];
+ config.dependencies = [
+ ...config.dependencies.filter((d) => d.rendered_in !== render_id),
+ ...render_config.dependencies
+ ];
+ const any_state = config.components.some((c) => c.type === "state");
+ const any_unload = config.dependencies.some(
+ (d) => d.targets.some((t) => t[1] === "unload")
+ );
+ config.connect_heartbeat = any_state || any_unload;
+ await resolve_heartbeat(config);
+ fire_event({
+ type: "render",
+ data: render_config,
+ endpoint: _endpoint,
+ fn_index
+ });
+ }
+ this.handle_blob(config.root, resolved_data, endpoint_info).then(
+ async (_payload) => {
+ var _a2;
+ let input_data = handle_payload(
+ _payload,
+ dependency,
+ config.components,
+ "input",
+ true
+ );
+ payload = {
+ data: input_data || [],
+ event_data,
+ fn_index,
+ trigger_id
+ };
+ if (skip_queue(fn_index, config)) {
+ fire_event({
+ type: "status",
+ endpoint: _endpoint,
+ stage: "pending",
+ queue: false,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ post_data2(
+ `${config.root}/run${_endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`}${url_params ? "?" + url_params : ""}`,
+ {
+ ...payload,
+ session_hash
+ }
+ ).then(([output, status_code]) => {
+ const data2 = output.data;
+ if (status_code == 200) {
+ fire_event({
+ type: "data",
+ endpoint: _endpoint,
+ fn_index,
+ data: handle_payload(
+ data2,
+ dependency,
+ config.components,
+ "output",
+ options.with_null_state
+ ),
+ time: /* @__PURE__ */ new Date(),
+ event_data,
+ trigger_id
+ });
+ if (output.render_config) {
+ handle_render_config(output.render_config);
}
- websocket = new WebSocket(url);
- websocket.onclose = (evt) => {
- if (!evt.wasClean) {
- fire_event({
- type: "status",
- stage: "error",
- broken: true,
- message: BROKEN_CONNECTION_MSG,
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- }
- };
- websocket.onmessage = function(event) {
- const _data = JSON.parse(event.data);
- const { type, status, data: data2 } = handle_message(
- _data,
- last_status[fn_index]
- );
- if (type === "update" && status && !complete) {
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date(),
- ...status
- });
- if (status.stage === "error") {
- websocket.close();
- }
- } else if (type === "hash") {
- websocket.send(JSON.stringify({ fn_index, session_hash }));
- return;
- } else if (type === "data") {
- websocket.send(JSON.stringify({ ...payload, session_hash }));
- } else if (type === "complete") {
- complete = status;
- } else if (type === "log") {
- fire_event({
- type: "log",
- log: data2.log,
- level: data2.level,
- endpoint: _endpoint,
- fn_index
- });
- } else if (type === "generating") {
- fire_event({
- type: "status",
- time: /* @__PURE__ */ new Date(),
- ...status,
- stage: status == null ? void 0 : status.stage,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- if (data2) {
- fire_event({
- type: "data",
- time: /* @__PURE__ */ new Date(),
- data: transform_files ? transform_output(
- data2.data,
- api_info,
- config.root,
- config.root_url
- ) : data2.data,
- endpoint: _endpoint,
- fn_index
- });
- if (complete) {
- fire_event({
- type: "status",
- time: /* @__PURE__ */ new Date(),
- ...complete,
- stage: status == null ? void 0 : status.stage,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- websocket.close();
- }
- }
- };
- if (semiver(config.version || "2.0.0", "3.6") < 0) {
- addEventListener(
- "open",
- () => websocket.send(JSON.stringify({ hash: session_hash }))
- );
+ fire_event({
+ type: "status",
+ endpoint: _endpoint,
+ fn_index,
+ stage: "complete",
+ eta: output.average_duration,
+ queue: false,
+ time: /* @__PURE__ */ new Date()
+ });
+ } else {
+ fire_event({
+ type: "status",
+ stage: "error",
+ endpoint: _endpoint,
+ fn_index,
+ message: output.error,
+ queue: false,
+ time: /* @__PURE__ */ new Date()
+ });
+ }
+ }).catch((e) => {
+ fire_event({
+ type: "status",
+ stage: "error",
+ message: e.message,
+ endpoint: _endpoint,
+ fn_index,
+ queue: false,
+ time: /* @__PURE__ */ new Date()
+ });
+ });
+ } else if (protocol == "ws") {
+ const { ws_protocol, host } = await process_endpoint(
+ app_reference,
+ hf_token
+ );
+ fire_event({
+ type: "status",
+ stage: "pending",
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ let url = new URL(
+ `${ws_protocol}://${resolve_root(
+ host,
+ config.path,
+ true
+ )}/queue/join${url_params ? "?" + url_params : ""}`
+ );
+ if (this.jwt) {
+ url.searchParams.set("__sign", this.jwt);
+ }
+ websocket = new WebSocket(url);
+ websocket.onclose = (evt) => {
+ if (!evt.wasClean) {
+ fire_event({
+ type: "status",
+ stage: "error",
+ broken: true,
+ message: BROKEN_CONNECTION_MSG,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ }
+ };
+ websocket.onmessage = function(event) {
+ const _data = JSON.parse(event.data);
+ const { type, status, data: data2 } = handle_message(
+ _data,
+ last_status[fn_index]
+ );
+ if (type === "update" && status && !complete) {
+ fire_event({
+ type: "status",
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date(),
+ ...status
+ });
+ if (status.stage === "error") {
+ websocket.close();
+ }
+ } else if (type === "hash") {
+ websocket.send(JSON.stringify({ fn_index, session_hash }));
+ return;
+ } else if (type === "data") {
+ websocket.send(JSON.stringify({ ...payload, session_hash }));
+ } else if (type === "complete") {
+ complete = status;
+ } else if (type === "log") {
+ fire_event({
+ type: "log",
+ log: data2.log,
+ level: data2.level,
+ endpoint: _endpoint,
+ fn_index
+ });
+ } else if (type === "generating") {
+ fire_event({
+ type: "status",
+ time: /* @__PURE__ */ new Date(),
+ ...status,
+ stage: status == null ? void 0 : status.stage,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index
+ });
+ }
+ if (data2) {
+ fire_event({
+ type: "data",
+ time: /* @__PURE__ */ new Date(),
+ data: handle_payload(
+ data2.data,
+ dependency,
+ config.components,
+ "output",
+ options.with_null_state
+ ),
+ endpoint: _endpoint,
+ fn_index,
+ event_data,
+ trigger_id
+ });
+ if (complete) {
+ fire_event({
+ type: "status",
+ time: /* @__PURE__ */ new Date(),
+ ...complete,
+ stage: status == null ? void 0 : status.stage,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index
+ });
+ websocket.close();
+ }
+ }
+ };
+ if (semiver(config.version || "2.0.0", "3.6") < 0) {
+ addEventListener(
+ "open",
+ () => websocket.send(JSON.stringify({ hash: session_hash }))
+ );
+ }
+ } else if (protocol == "sse") {
+ fire_event({
+ type: "status",
+ stage: "pending",
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ var params = new URLSearchParams({
+ fn_index: fn_index.toString(),
+ session_hash
+ }).toString();
+ let url = new URL(
+ `${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}`
+ );
+ if (this.jwt) {
+ url.searchParams.set("__sign", this.jwt);
+ }
+ stream2 = this.stream(url);
+ if (!stream2) {
+ return Promise.reject(
+ new Error("Cannot connect to SSE endpoint: " + url.toString())
+ );
+ }
+ stream2.onmessage = async function(event) {
+ const _data = JSON.parse(event.data);
+ const { type, status, data: data2 } = handle_message(
+ _data,
+ last_status[fn_index]
+ );
+ if (type === "update" && status && !complete) {
+ fire_event({
+ type: "status",
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date(),
+ ...status
+ });
+ if (status.stage === "error") {
+ stream2 == null ? void 0 : stream2.close();
+ close();
+ }
+ } else if (type === "data") {
+ event_id = _data.event_id;
+ let [_, status2] = await post_data2(`${config.root}/queue/data`, {
+ ...payload,
+ session_hash,
+ event_id
+ });
+ if (status2 !== 200) {
+ fire_event({
+ type: "status",
+ stage: "error",
+ message: BROKEN_CONNECTION_MSG,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ stream2 == null ? void 0 : stream2.close();
+ close();
}
- } else if (protocol == "sse") {
+ } else if (type === "complete") {
+ complete = status;
+ } else if (type === "log") {
+ fire_event({
+ type: "log",
+ log: data2.log,
+ level: data2.level,
+ endpoint: _endpoint,
+ fn_index
+ });
+ } else if (type === "generating") {
fire_event({
type: "status",
- stage: "pending",
+ time: /* @__PURE__ */ new Date(),
+ ...status,
+ stage: status == null ? void 0 : status.stage,
queue: true,
endpoint: _endpoint,
+ fn_index
+ });
+ }
+ if (data2) {
+ fire_event({
+ type: "data",
+ time: /* @__PURE__ */ new Date(),
+ data: handle_payload(
+ data2.data,
+ dependency,
+ config.components,
+ "output",
+ options.with_null_state
+ ),
+ endpoint: _endpoint,
fn_index,
- time: /* @__PURE__ */ new Date()
+ event_data,
+ trigger_id
});
- var params = new URLSearchParams({
- fn_index: fn_index.toString(),
+ if (complete) {
+ fire_event({
+ type: "status",
+ time: /* @__PURE__ */ new Date(),
+ ...complete,
+ stage: status == null ? void 0 : status.stage,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index
+ });
+ stream2 == null ? void 0 : stream2.close();
+ close();
+ }
+ }
+ };
+ } else if (protocol == "sse_v1" || protocol == "sse_v2" || protocol == "sse_v2.1" || protocol == "sse_v3") {
+ fire_event({
+ type: "status",
+ stage: "pending",
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ let hostname = "";
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
+ hostname = (_a2 = window == null ? void 0 : window.location) == null ? void 0 : _a2.hostname;
+ }
+ let hfhubdev = "dev.spaces.huggingface.tech";
+ const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`;
+ const is_iframe = typeof window !== "undefined" && typeof document !== "undefined" && window.parent != window;
+ const is_zerogpu_space = dependency.zerogpu && config.space_id;
+ const zerogpu_auth_promise = is_iframe && is_zerogpu_space ? post_message("zerogpu-headers", origin) : Promise.resolve(null);
+ const post_data_promise = zerogpu_auth_promise.then((headers) => {
+ return post_data2(
+ `${config.root}/queue/join?${url_params}`,
+ {
+ ...payload,
session_hash
- }).toString();
- let url = new URL(
- `${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}`
- );
- eventSource = EventSource_factory(url);
- eventSource.onmessage = async function(event) {
- const _data = JSON.parse(event.data);
- const { type, status, data: data2 } = handle_message(
- _data,
- last_status[fn_index]
- );
- if (type === "update" && status && !complete) {
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date(),
- ...status
- });
- if (status.stage === "error") {
- eventSource.close();
- }
- } else if (type === "data") {
- event_id = _data.event_id;
- let [_, status2] = await post_data2(
- `${config.root}/queue/data`,
- {
- ...payload,
- session_hash,
- event_id
- },
- hf_token
+ },
+ headers
+ );
+ });
+ post_data_promise.then(async ([response, status]) => {
+ if (status === 503) {
+ fire_event({
+ type: "status",
+ stage: "error",
+ message: QUEUE_FULL_MSG,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ } else if (status !== 200) {
+ fire_event({
+ type: "status",
+ stage: "error",
+ message: BROKEN_CONNECTION_MSG,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date()
+ });
+ } else {
+ event_id = response.event_id;
+ let callback = async function(_data) {
+ try {
+ const { type, status: status2, data: data2 } = handle_message(
+ _data,
+ last_status[fn_index]
);
- if (status2 !== 200) {
+ if (type == "heartbeat") {
+ return;
+ }
+ if (type === "update" && status2 && !complete) {
+ fire_event({
+ type: "status",
+ endpoint: _endpoint,
+ fn_index,
+ time: /* @__PURE__ */ new Date(),
+ ...status2
+ });
+ } else if (type === "complete") {
+ complete = status2;
+ } else if (type == "unexpected_error") {
+ console.error("Unexpected error", status2 == null ? void 0 : status2.message);
fire_event({
type: "status",
stage: "error",
- message: BROKEN_CONNECTION_MSG,
+ message: (status2 == null ? void 0 : status2.message) || "An Unexpected Error Occurred!",
queue: true,
endpoint: _endpoint,
fn_index,
time: /* @__PURE__ */ new Date()
});
- eventSource.close();
- }
- } else if (type === "complete") {
- complete = status;
- } else if (type === "log") {
- fire_event({
- type: "log",
- log: data2.log,
- level: data2.level,
- endpoint: _endpoint,
- fn_index
- });
- } else if (type === "generating") {
- fire_event({
- type: "status",
- time: /* @__PURE__ */ new Date(),
- ...status,
- stage: status == null ? void 0 : status.stage,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- if (data2) {
- fire_event({
- type: "data",
- time: /* @__PURE__ */ new Date(),
- data: transform_files ? transform_output(
- data2.data,
- api_info,
- config.root,
- config.root_url
- ) : data2.data,
- endpoint: _endpoint,
- fn_index
- });
- if (complete) {
+ } else if (type === "log") {
+ fire_event({
+ type: "log",
+ log: data2.log,
+ level: data2.level,
+ endpoint: _endpoint,
+ fn_index
+ });
+ return;
+ } else if (type === "generating") {
fire_event({
type: "status",
time: /* @__PURE__ */ new Date(),
- ...complete,
- stage: status == null ? void 0 : status.stage,
+ ...status2,
+ stage: status2 == null ? void 0 : status2.stage,
queue: true,
endpoint: _endpoint,
fn_index
});
- eventSource.close();
+ if (data2 && ["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) {
+ apply_diff_stream(pending_diff_streams, event_id, data2);
+ }
}
- }
- };
- } else if (protocol == "sse_v1") {
- fire_event({
- type: "status",
- stage: "pending",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- post_data2(
- `${config.root}/queue/join?${url_params}`,
- {
- ...payload,
- session_hash
- },
- hf_token
- ).then(([response, status]) => {
- if (status === 503) {
- fire_event({
- type: "status",
- stage: "error",
- message: QUEUE_FULL_MSG,
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- } else if (status !== 200) {
+ if (data2) {
+ fire_event({
+ type: "data",
+ time: /* @__PURE__ */ new Date(),
+ data: handle_payload(
+ data2.data,
+ dependency,
+ config.components,
+ "output",
+ options.with_null_state
+ ),
+ endpoint: _endpoint,
+ fn_index
+ });
+ if (data2.render_config) {
+ await handle_render_config(data2.render_config);
+ }
+ if (complete) {
+ fire_event({
+ type: "status",
+ time: /* @__PURE__ */ new Date(),
+ ...complete,
+ stage: status2 == null ? void 0 : status2.stage,
+ queue: true,
+ endpoint: _endpoint,
+ fn_index
+ });
+ }
+ }
+ if ((status2 == null ? void 0 : status2.stage) === "complete" || (status2 == null ? void 0 : status2.stage) === "error") {
+ if (event_callbacks[event_id]) {
+ delete event_callbacks[event_id];
+ }
+ if (event_id in pending_diff_streams) {
+ delete pending_diff_streams[event_id];
+ }
+ }
+ } catch (e) {
+ console.error("Unexpected client exception", e);
fire_event({
type: "status",
stage: "error",
- message: BROKEN_CONNECTION_MSG,
+ message: "An Unexpected Error Occurred!",
queue: true,
endpoint: _endpoint,
fn_index,
time: /* @__PURE__ */ new Date()
});
- } else {
- event_id = response.event_id;
- let callback = async function(_data) {
- try {
- const { type, status: status2, data: data2 } = handle_message(
- _data,
- last_status[fn_index]
- );
- if (type == "heartbeat") {
- return;
- }
- if (type === "update" && status2 && !complete) {
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date(),
- ...status2
- });
- } else if (type === "complete") {
- complete = status2;
- } else if (type == "unexpected_error") {
- console.error("Unexpected error", status2 == null ? void 0 : status2.message);
- fire_event({
- type: "status",
- stage: "error",
- message: (status2 == null ? void 0 : status2.message) || "An Unexpected Error Occurred!",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- } else if (type === "log") {
- fire_event({
- type: "log",
- log: data2.log,
- level: data2.level,
- endpoint: _endpoint,
- fn_index
- });
- return;
- } else if (type === "generating") {
- fire_event({
- type: "status",
- time: /* @__PURE__ */ new Date(),
- ...status2,
- stage: status2 == null ? void 0 : status2.stage,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- if (data2) {
- fire_event({
- type: "data",
- time: /* @__PURE__ */ new Date(),
- data: transform_files ? transform_output(
- data2.data,
- api_info,
- config.root,
- config.root_url
- ) : data2.data,
- endpoint: _endpoint,
- fn_index
- });
- if (complete) {
- fire_event({
- type: "status",
- time: /* @__PURE__ */ new Date(),
- ...complete,
- stage: status2 == null ? void 0 : status2.stage,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- }
- if ((status2 == null ? void 0 : status2.stage) === "complete" || (status2 == null ? void 0 : status2.stage) === "error") {
- if (event_callbacks[event_id]) {
- delete event_callbacks[event_id];
- }
- }
- } catch (e) {
- console.error("Unexpected client exception", e);
- fire_event({
- type: "status",
- stage: "error",
- message: "An Unexpected Error Occurred!",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: /* @__PURE__ */ new Date()
- });
- close_stream();
- }
- };
- if (event_id in pending_stream_messages) {
- pending_stream_messages[event_id].forEach(
- (msg) => callback(msg)
- );
- delete pending_stream_messages[event_id];
- }
- event_callbacks[event_id] = callback;
- unclosed_events.add(event_id);
- if (!stream_open) {
- open_stream();
+ if (["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) {
+ close_stream(stream_status, that.abort_controller);
+ stream_status.open = false;
+ close();
}
}
- });
- }
- }
- );
- function fire_event(event) {
- const narrowed_listener_map = listener_map;
- const listeners = narrowed_listener_map[event.type] || [];
- listeners == null ? void 0 : listeners.forEach((l) => l(event));
- }
- function on(eventType, listener) {
- const narrowed_listener_map = listener_map;
- const listeners = narrowed_listener_map[eventType] || [];
- narrowed_listener_map[eventType] = listeners;
- listeners == null ? void 0 : listeners.push(listener);
- return { on, off, cancel, destroy };
- }
- function off(eventType, listener) {
- const narrowed_listener_map = listener_map;
- let listeners = narrowed_listener_map[eventType] || [];
- listeners = listeners == null ? void 0 : listeners.filter((l) => l !== listener);
- narrowed_listener_map[eventType] = listeners;
- return { on, off, cancel, destroy };
- }
- async function cancel() {
- const _status = {
- stage: "complete",
- queue: false,
- time: /* @__PURE__ */ new Date()
- };
- complete = _status;
- fire_event({
- ..._status,
- type: "status",
- endpoint: _endpoint,
- fn_index
- });
- let cancel_request = {};
- if (protocol === "ws") {
- if (websocket && websocket.readyState === 0) {
- websocket.addEventListener("open", () => {
- websocket.close();
- });
- } else {
- websocket.close();
- }
- cancel_request = { fn_index, session_hash };
- } else {
- eventSource.close();
- cancel_request = { event_id };
- }
- try {
- await fetch_implementation(`${config.root}/reset`, {
- headers: { "Content-Type": "application/json" },
- method: "POST",
- body: JSON.stringify(cancel_request)
- });
- } catch (e) {
- console.warn(
- "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable."
- );
- }
- }
- function destroy() {
- for (const event_type in listener_map) {
- listener_map[event_type].forEach((fn2) => {
- off(event_type, fn2);
- });
- }
- }
- return {
- on,
- off,
- cancel,
- destroy
- };
- }
- function open_stream() {
- stream_open = true;
- let params = new URLSearchParams({
- session_hash
- }).toString();
- let url = new URL(`${config.root}/queue/data?${params}`);
- event_stream = EventSource_factory(url);
- event_stream.onmessage = async function(event) {
- let _data = JSON.parse(event.data);
- const event_id = _data.event_id;
- if (!event_id) {
- await Promise.all(
- Object.keys(event_callbacks).map(
- (event_id2) => event_callbacks[event_id2](_data)
- )
- );
- } else if (event_callbacks[event_id]) {
- if (_data.msg === "process_completed") {
- unclosed_events.delete(event_id);
- if (unclosed_events.size === 0) {
- close_stream();
+ };
+ if (event_id in pending_stream_messages) {
+ pending_stream_messages[event_id].forEach(
+ (msg) => callback(msg)
+ );
+ delete pending_stream_messages[event_id];
+ }
+ event_callbacks[event_id] = callback;
+ unclosed_events.add(event_id);
+ if (!stream_status.open) {
+ await this.open_stream();
}
}
- let fn2 = event_callbacks[event_id];
- window.setTimeout(fn2, 0, _data);
- } else {
- if (!pending_stream_messages[event_id]) {
- pending_stream_messages[event_id] = [];
- }
- pending_stream_messages[event_id].push(_data);
- }
- };
- event_stream.onerror = async function(event) {
- await Promise.all(
- Object.keys(event_callbacks).map(
- (event_id) => event_callbacks[event_id]({
- msg: "unexpected_error",
- message: BROKEN_CONNECTION_MSG
- })
- )
- );
- close_stream();
- };
- }
- function close_stream() {
- stream_open = false;
- event_stream == null ? void 0 : event_stream.close();
- }
- async function component_server(component_id, fn_name, data) {
- var _a;
- const headers = { "Content-Type": "application/json" };
- if (hf_token) {
- headers.Authorization = `Bearer ${hf_token}`;
- }
- let root_url;
- let component = config.components.find(
- (comp) => comp.id === component_id
- );
- if ((_a = component == null ? void 0 : component.props) == null ? void 0 : _a.root_url) {
- root_url = component.props.root_url;
- } else {
- root_url = config.root;
- }
- const response = await fetch_implementation(
- `${root_url}/component_server/`,
- {
- method: "POST",
- body: JSON.stringify({
- data,
- component_id,
- fn_name,
- session_hash
- }),
- headers
- }
- );
- if (!response.ok) {
- throw new Error(
- "Could not connect to component server: " + response.statusText
- );
- }
- const output = await response.json();
- return output;
- }
- async function view_api(config2) {
- if (api)
- return api;
- const headers = { "Content-Type": "application/json" };
- if (hf_token) {
- headers.Authorization = `Bearer ${hf_token}`;
- }
- let response;
- if (semiver(config2.version || "2.0.0", "3.30") < 0) {
- response = await fetch_implementation(
- "https://gradio-space-api-fetcher-v2.hf.space/api",
- {
- method: "POST",
- body: JSON.stringify({
- serialize: false,
- config: JSON.stringify(config2)
- }),
- headers
- }
- );
- } else {
- response = await fetch_implementation(`${config2.root}/info`, {
- headers
});
}
- if (!response.ok) {
- throw new Error(BROKEN_CONNECTION_MSG);
- }
- let api_info = await response.json();
- if ("api" in api_info) {
- api_info = api_info.api;
- }
- if (api_info.named_endpoints["/predict"] && !api_info.unnamed_endpoints["0"]) {
- api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"];
- }
- const x = transform_api_info(api_info, config2, api_map);
- return x;
}
- });
+ );
+ let done = false;
+ const values = [];
+ const resolvers = [];
+ const iterator = {
+ [Symbol.asyncIterator]: () => iterator,
+ next,
+ throw: async (value) => {
+ push_error(value);
+ return next();
+ },
+ return: async () => {
+ close();
+ return next();
+ },
+ cancel
+ };
+ return iterator;
+ } catch (error) {
+ console.error("Submit function encountered an error:", error);
+ throw error;
}
- async function handle_blob2(endpoint, data, api_info, token) {
- const blob_refs = await walk_and_store_blobs(
- data,
- void 0,
- [],
- true,
- api_info
+}
+function thenable_reject(error) {
+ return {
+ then: (resolve, reject) => reject(error)
+ };
+}
+function get_endpoint_info(api_info, endpoint, api_map, config) {
+ let fn_index;
+ let endpoint_info;
+ let dependency;
+ if (typeof endpoint === "number") {
+ fn_index = endpoint;
+ endpoint_info = api_info.unnamed_endpoints[fn_index];
+ dependency = config.dependencies.find((dep) => dep.id == endpoint);
+ } else {
+ const trimmed_endpoint = endpoint.replace(/^\//, "");
+ fn_index = api_map[trimmed_endpoint];
+ endpoint_info = api_info.named_endpoints[endpoint.trim()];
+ dependency = config.dependencies.find(
+ (dep) => dep.id == api_map[trimmed_endpoint]
+ );
+ }
+ if (typeof fn_index !== "number") {
+ throw new Error(
+ "There is no endpoint matching that name of fn_index matching that number."
);
- return Promise.all(
- blob_refs.map(async ({ path, blob, type }) => {
- if (blob) {
- const file_url = (await upload_files2(endpoint, [blob], token)).files[0];
- return { path, file_url, type, name: blob == null ? void 0 : blob.name };
- }
- return { path, type };
- })
- ).then((r) => {
- r.forEach(({ path, file_url, type, name }) => {
- if (type === "Gallery") {
- update_object(data, file_url, path);
- } else if (file_url) {
- const file = new FileData({ path: file_url, orig_name: name });
- update_object(data, file, path);
- }
- });
- return data;
- });
}
+ return { fn_index, endpoint_info, dependency };
}
-const { post_data, upload_files, client, handle_blob } = api_factory(
- fetch,
- (...args) => new EventSource(...args)
-);
-function transform_output(data, api_info, root_url, remote_url) {
- return data.map((d, i) => {
- var _a, _b, _c, _d;
- if (((_b = (_a = api_info == null ? void 0 : api_info.returns) == null ? void 0 : _a[i]) == null ? void 0 : _b.component) === "File") {
- return normalise_file(d, root_url, remote_url);
- } else if (((_d = (_c = api_info == null ? void 0 : api_info.returns) == null ? void 0 : _c[i]) == null ? void 0 : _d.component) === "Gallery") {
- return d.map((img) => {
- return Array.isArray(img) ? [normalise_file(img[0], root_url, remote_url), img[1]] : [normalise_file(img, root_url, remote_url), null];
- });
- } else if (typeof d === "object" && d.path) {
- return normalise_file(d, root_url, remote_url);
+class Client {
+ constructor(app_reference, options = { events: ["data"] }) {
+ __publicField(this, "app_reference");
+ __publicField(this, "options");
+ __publicField(this, "config");
+ __publicField(this, "api_info");
+ __publicField(this, "api_map", {});
+ __publicField(this, "session_hash", Math.random().toString(36).substring(2));
+ __publicField(this, "jwt", false);
+ __publicField(this, "last_status", {});
+ __publicField(this, "cookies", null);
+ // streaming
+ __publicField(this, "stream_status", { open: false });
+ __publicField(this, "pending_stream_messages", {});
+ __publicField(this, "pending_diff_streams", {});
+ __publicField(this, "event_callbacks", {});
+ __publicField(this, "unclosed_events", /* @__PURE__ */ new Set());
+ __publicField(this, "heartbeat_event", null);
+ __publicField(this, "abort_controller", null);
+ __publicField(this, "stream_instance", null);
+ __publicField(this, "view_api");
+ __publicField(this, "upload_files");
+ __publicField(this, "upload");
+ __publicField(this, "handle_blob");
+ __publicField(this, "post_data");
+ __publicField(this, "submit");
+ __publicField(this, "predict");
+ __publicField(this, "open_stream");
+ __publicField(this, "resolve_config");
+ __publicField(this, "resolve_cookies");
+ this.app_reference = app_reference;
+ if (!options.events) {
+ options.events = ["data"];
}
- return d;
- });
-}
-function get_type(type, component, serializer, signature_type) {
- switch (type.type) {
- case "string":
- return "string";
- case "boolean":
- return "boolean";
- case "number":
- return "number";
+ this.options = options;
+ this.view_api = view_api.bind(this);
+ this.upload_files = upload_files.bind(this);
+ this.handle_blob = handle_blob.bind(this);
+ this.post_data = post_data.bind(this);
+ this.submit = submit.bind(this);
+ this.predict = predict.bind(this);
+ this.open_stream = open_stream.bind(this);
+ this.resolve_config = resolve_config.bind(this);
+ this.resolve_cookies = resolve_cookies.bind(this);
+ this.upload = upload.bind(this);
}
- if (serializer === "JSONSerializable" || serializer === "StringSerializable") {
- return "any";
- } else if (serializer === "ListStringSerializable") {
- return "string[]";
- } else if (component === "Image") {
- return signature_type === "parameter" ? "Blob | File | Buffer" : "string";
- } else if (serializer === "FileSerializable") {
- if ((type == null ? void 0 : type.type) === "array") {
- return signature_type === "parameter" ? "(Blob | File | Buffer)[]" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
+ fetch(input, init) {
+ const headers = new Headers((init == null ? void 0 : init.headers) || {});
+ if (this && this.cookies) {
+ headers.append("Cookie", this.cookies);
}
- return signature_type === "parameter" ? "Blob | File | Buffer" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
- } else if (serializer === "GallerySerializable") {
- return signature_type === "parameter" ? "[(Blob | File | Buffer), (string | null)][]" : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`;
+ return fetch(input, { ...init, headers });
}
-}
-function get_description(type, serializer) {
- if (serializer === "GallerySerializable") {
- return "array of [file, label] tuples";
- } else if (serializer === "ListStringSerializable") {
- return "array of strings";
- } else if (serializer === "FileSerializable") {
- return "array of files or single file";
+ stream(url) {
+ this.abort_controller = new AbortController();
+ this.stream_instance = readable_stream(url.toString(), {
+ signal: this.abort_controller.signal
+ });
+ return this.stream_instance;
}
- return type.description;
-}
-function transform_api_info(api_info, config, api_map) {
- const new_data = {
- named_endpoints: {},
- unnamed_endpoints: {}
- };
- for (const key in api_info) {
- const cat = api_info[key];
- for (const endpoint in cat) {
- const dep_index = config.dependencies[endpoint] ? endpoint : api_map[endpoint.replace("/", "")];
- const info = cat[endpoint];
- new_data[key][endpoint] = {};
- new_data[key][endpoint].parameters = {};
- new_data[key][endpoint].returns = {};
- new_data[key][endpoint].type = config.dependencies[dep_index].types;
- new_data[key][endpoint].parameters = info.parameters.map(
- ({ label, component, type, serializer }) => ({
- label,
- component,
- type: get_type(type, component, serializer, "parameter"),
- description: get_description(type, serializer)
- })
- );
- new_data[key][endpoint].returns = info.returns.map(
- ({ label, component, type, serializer }) => ({
- label,
- component,
- type: get_type(type, component, serializer, "return"),
- description: get_description(type, serializer)
- })
+ async init() {
+ var _a;
+ if ((typeof window === "undefined" || !("WebSocket" in window)) && !global.WebSocket) {
+ const ws = await import("./wrapper-CviSselG.js");
+ global.WebSocket = ws.WebSocket;
+ }
+ try {
+ if (this.options.auth) {
+ await this.resolve_cookies();
+ }
+ await this._resolve_config().then(
+ ({ config }) => this._resolve_hearbeat(config)
);
+ } catch (e) {
+ throw Error(e);
}
+ this.api_info = await this.view_api();
+ this.api_map = map_names_to_ids(((_a = this.config) == null ? void 0 : _a.dependencies) || []);
}
- return new_data;
-}
-async function get_jwt(space, token) {
- try {
- const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, {
- headers: {
- Authorization: `Bearer ${token}`
+ async _resolve_hearbeat(_config) {
+ if (_config) {
+ this.config = _config;
+ if (this.config && this.config.connect_heartbeat) {
+ if (this.config.space_id && this.options.hf_token) {
+ this.jwt = await get_jwt(
+ this.config.space_id,
+ this.options.hf_token,
+ this.cookies
+ );
+ }
}
- });
- const jwt = (await r.json()).token;
- return jwt || false;
- } catch (e) {
- console.error(e);
- return false;
+ }
+ if (_config.space_id && this.options.hf_token) {
+ this.jwt = await get_jwt(_config.space_id, this.options.hf_token);
+ }
+ if (this.config && this.config.connect_heartbeat) {
+ const heartbeat_url = new URL(
+ `${this.config.root}/heartbeat/${this.session_hash}`
+ );
+ if (this.jwt) {
+ heartbeat_url.searchParams.set("__sign", this.jwt);
+ }
+ if (!this.heartbeat_event) {
+ this.heartbeat_event = this.stream(heartbeat_url);
+ }
+ }
}
-}
-function update_object(object, newValue, stack) {
- while (stack.length > 1) {
- object = object[stack.shift()];
+ static async connect(app_reference, options = {
+ events: ["data"]
+ }) {
+ const client2 = new this(app_reference, options);
+ await client2.init();
+ return client2;
+ }
+ close() {
+ var _a;
+ (_a = this.heartbeat_event) == null ? void 0 : _a.close();
}
- object[stack.shift()] = newValue;
-}
-async function walk_and_store_blobs(param, type = void 0, path = [], root = false, api_info = void 0) {
- if (Array.isArray(param)) {
- let blob_refs = [];
- await Promise.all(
- param.map(async (v, i) => {
- var _a;
- let new_path = path.slice();
- new_path.push(i);
- const array_refs = await walk_and_store_blobs(
- param[i],
- root ? ((_a = api_info == null ? void 0 : api_info.parameters[i]) == null ? void 0 : _a.component) || void 0 : type,
- new_path,
- false,
- api_info
- );
- blob_refs = blob_refs.concat(array_refs);
- })
+ static async duplicate(app_reference, options = {
+ events: ["data"]
+ }) {
+ return duplicate(app_reference, options);
+ }
+ async _resolve_config() {
+ const { http_protocol, host, space_id } = await process_endpoint(
+ this.app_reference,
+ this.options.hf_token
);
- return blob_refs;
- } else if (globalThis.Buffer && param instanceof globalThis.Buffer) {
- const is_image = type === "Image";
- return [
- {
- path,
- blob: is_image ? false : new NodeBlob([param]),
- type
+ const { status_callback } = this.options;
+ let config;
+ try {
+ config = await this.resolve_config(`${http_protocol}//${host}`);
+ if (!config) {
+ throw new Error(CONFIG_ERROR_MSG);
}
- ];
- } else if (typeof param === "object") {
- let blob_refs = [];
- for (let key in param) {
- if (param.hasOwnProperty(key)) {
- let new_path = path.slice();
- new_path.push(key);
- blob_refs = blob_refs.concat(
- await walk_and_store_blobs(
- param[key],
- void 0,
- new_path,
- false,
- api_info
- )
+ return this.config_success(config);
+ } catch (e) {
+ if (space_id && status_callback) {
+ check_space_status(
+ space_id,
+ RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain",
+ this.handle_space_success
);
+ } else {
+ if (status_callback)
+ status_callback({
+ status: "error",
+ message: "Could not load this space.",
+ load_status: "error",
+ detail: "NOT_FOUND"
+ });
+ throw Error(e);
}
}
- return blob_refs;
- }
- return [];
-}
-function skip_queue(id, config) {
- var _a, _b, _c, _d;
- return !(((_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a[id]) == null ? void 0 : _b.queue) === null ? config.enable_queue : (_d = (_c = config == null ? void 0 : config.dependencies) == null ? void 0 : _c[id]) == null ? void 0 : _d.queue) || false;
-}
-async function resolve_config(fetch_implementation, endpoint, token) {
- const headers = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
}
- if (typeof window !== "undefined" && window.gradio_config && location.origin !== "http://localhost:9876" && !window.gradio_config.dev_mode) {
- const path = window.gradio_config.root;
- const config = window.gradio_config;
- config.root = resolve_root(endpoint, config.root, false);
- return { ...config, path };
- } else if (endpoint) {
- let response = await fetch_implementation(`${endpoint}/config`, {
- headers
- });
- if (response.status === 200) {
- const config = await response.json();
- config.path = config.path ?? "";
- config.root = endpoint;
- return config;
+ async config_success(_config) {
+ this.config = _config;
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
+ if (window.location.protocol === "https:") {
+ this.config.root = this.config.root.replace("http://", "https://");
+ }
+ }
+ if (this.config.auth_required) {
+ return this.prepare_return_obj();
}
- throw new Error("Could not get config.");
+ try {
+ this.api_info = await this.view_api();
+ } catch (e) {
+ console.error(API_INFO_ERROR_MSG + e.message);
+ }
+ return this.prepare_return_obj();
}
- throw new Error("No config or app endpoint found");
-}
-async function check_space_status(id, type, status_callback) {
- let endpoint = type === "subdomain" ? `https://huggingface.co/api/spaces/by-subdomain/${id}` : `https://huggingface.co/api/spaces/${id}`;
- let response;
- let _status;
- try {
- response = await fetch(endpoint);
- _status = response.status;
- if (_status !== 200) {
- throw new Error();
+ async handle_space_success(status) {
+ if (!this) {
+ throw new Error(CONFIG_ERROR_MSG);
+ }
+ const { status_callback } = this.options;
+ if (status_callback)
+ status_callback(status);
+ if (status.status === "running") {
+ try {
+ this.config = await this._resolve_config();
+ if (!this.config) {
+ throw new Error(CONFIG_ERROR_MSG);
+ }
+ const _config = await this.config_success(this.config);
+ return _config;
+ } catch (e) {
+ if (status_callback) {
+ status_callback({
+ status: "error",
+ message: "Could not load this space.",
+ load_status: "error",
+ detail: "NOT_FOUND"
+ });
+ }
+ throw e;
+ }
}
- response = await response.json();
- } catch (e) {
- status_callback({
- status: "error",
- load_status: "error",
- message: "Could not get space status",
- detail: "NOT_FOUND"
- });
- return;
}
- if (!response || _status !== 200)
- return;
- const {
- runtime: { stage },
- id: space_name
- } = response;
- switch (stage) {
- case "STOPPED":
- case "SLEEPING":
- status_callback({
- status: "sleeping",
- load_status: "pending",
- message: "Space is asleep. Waking it up...",
- detail: stage
- });
- setTimeout(() => {
- check_space_status(id, type, status_callback);
- }, 1e3);
- break;
- case "PAUSED":
- status_callback({
- status: "paused",
- load_status: "error",
- message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
- detail: stage,
- discussions_enabled: await discussions_enabled(space_name)
- });
- break;
- case "RUNNING":
- case "RUNNING_BUILDING":
- status_callback({
- status: "running",
- load_status: "complete",
- message: "",
- detail: stage
- });
- break;
- case "BUILDING":
- status_callback({
- status: "building",
- load_status: "pending",
- message: "Space is building...",
- detail: stage
+ async component_server(component_id, fn_name, data) {
+ var _a;
+ if (!this.config) {
+ throw new Error(CONFIG_ERROR_MSG);
+ }
+ const headers = {};
+ const { hf_token } = this.options;
+ const { session_hash } = this;
+ if (hf_token) {
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
+ }
+ let root_url;
+ let component = this.config.components.find(
+ (comp) => comp.id === component_id
+ );
+ if ((_a = component == null ? void 0 : component.props) == null ? void 0 : _a.root_url) {
+ root_url = component.props.root_url;
+ } else {
+ root_url = this.config.root;
+ }
+ let body;
+ if ("binary" in data) {
+ body = new FormData();
+ for (const key in data.data) {
+ if (key === "binary")
+ continue;
+ body.append(key, data.data[key]);
+ }
+ body.set("component_id", component_id.toString());
+ body.set("fn_name", fn_name);
+ body.set("session_hash", session_hash);
+ } else {
+ body = JSON.stringify({
+ data,
+ component_id,
+ fn_name,
+ session_hash
});
- setTimeout(() => {
- check_space_status(id, type, status_callback);
- }, 1e3);
- break;
- default:
- status_callback({
- status: "space_error",
- load_status: "error",
- message: "This space is experiencing an issue.",
- detail: stage,
- discussions_enabled: await discussions_enabled(space_name)
+ headers["Content-Type"] = "application/json";
+ }
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+ try {
+ const response = await this.fetch(`${root_url}/component_server/`, {
+ method: "POST",
+ body,
+ headers,
+ credentials: "include"
});
- break;
- }
-}
-function handle_message(data, last_status) {
- const queue = true;
- switch (data.msg) {
- case "send_data":
- return { type: "data" };
- case "send_hash":
- return { type: "hash" };
- case "queue_full":
- return {
- type: "update",
- status: {
- queue,
- message: QUEUE_FULL_MSG,
- stage: "error",
- code: data.code,
- success: data.success
- }
- };
- case "heartbeat":
- return {
- type: "heartbeat"
- };
- case "unexpected_error":
- return {
- type: "unexpected_error",
- status: {
- queue,
- message: data.message,
- stage: "error",
- success: false
- }
- };
- case "estimation":
- return {
- type: "update",
- status: {
- queue,
- stage: last_status || "pending",
- code: data.code,
- size: data.queue_size,
- position: data.rank,
- eta: data.rank_eta,
- success: data.success
- }
- };
- case "progress":
- return {
- type: "update",
- status: {
- queue,
- stage: "pending",
- code: data.code,
- progress_data: data.progress_data,
- success: data.success
- }
- };
- case "log":
- return { type: "log", data };
- case "process_generating":
- return {
- type: "generating",
- status: {
- queue,
- message: !data.success ? data.output.error : null,
- stage: data.success ? "generating" : "error",
- code: data.code,
- progress_data: data.progress_data,
- eta: data.average_duration
- },
- data: data.success ? data.output : null
- };
- case "process_completed":
- if ("error" in data.output) {
- return {
- type: "update",
- status: {
- queue,
- message: data.output.error,
- stage: "error",
- code: data.code,
- success: data.success
- }
- };
+ if (!response.ok) {
+ throw new Error(
+ "Could not connect to component server: " + response.statusText
+ );
}
- return {
- type: "complete",
- status: {
- queue,
- message: !data.success ? data.output.error : void 0,
- stage: data.success ? "complete" : "error",
- code: data.code,
- progress_data: data.progress_data
- },
- data: data.success ? data.output : null
- };
- case "process_starts":
- return {
- type: "update",
- status: {
- queue,
- stage: "pending",
- code: data.code,
- size: data.rank,
- position: 0,
- success: data.success,
- eta: data.eta
- }
- };
+ const output = await response.json();
+ return output;
+ } catch (e) {
+ console.warn(e);
+ }
}
- return { type: "none", status: { stage: "error", queue } };
+ set_cookies(raw_cookies) {
+ this.cookies = parse_and_set_cookies(raw_cookies).join("; ");
+ }
+ prepare_return_obj() {
+ return {
+ config: this.config,
+ predict: this.predict,
+ submit: this.submit,
+ view_api: this.view_api,
+ component_server: this.component_server
+ };
+ }
+}
+async function client(app_reference, options = {
+ events: ["data"]
+}) {
+ return await Client.connect(app_reference, options);
+}
+async function duplicate_space(app_reference, options) {
+ return await Client.duplicate(app_reference, options);
}
export {
+ Client,
FileData,
- api_factory,
client,
- duplicate,
- get_fetchable_url_or_file,
- normalise_file,
- post_data,
+ duplicate_space as duplicate,
+ handle_file,
+ predict,
prepare_files,
+ submit,
upload,
upload_files
};
diff --git a/node_modules/@gradio/client/dist/test/handlers.d.ts b/node_modules/@gradio/client/dist/test/handlers.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..379dbe7871f6d0e74290139b977598640ed6e2a3
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/handlers.d.ts
@@ -0,0 +1,4 @@
+import { RequestHandler } from "msw";
+export declare const direct_space_url = "https://hmb-hello-world.hf.space";
+export declare const handlers: RequestHandler[];
+//# sourceMappingURL=handlers.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/handlers.d.ts.map b/node_modules/@gradio/client/dist/test/handlers.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..af40fffe69b02ab37140d82f30cf211e48a63467
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/handlers.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/test/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,cAAc,EAAE,MAAM,KAAK,CAAC;AAuBzD,eAAO,MAAM,gBAAgB,qCAAqC,CAAC;AAqBnE,eAAO,MAAM,QAAQ,EAAE,cAAc,EAwoBpC,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/mock_eventsource.d.ts b/node_modules/@gradio/client/dist/test/mock_eventsource.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fecaa636c8deed45b2f0cebced58e709815d94db
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/mock_eventsource.d.ts
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=mock_eventsource.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/mock_eventsource.d.ts.map b/node_modules/@gradio/client/dist/test/mock_eventsource.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..5a249f5a4ae9c0a41b8a6f26d27eb2d227927793
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/mock_eventsource.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"mock_eventsource.d.ts","sourceRoot":"","sources":["../../src/test/mock_eventsource.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/server.d.ts b/node_modules/@gradio/client/dist/test/server.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e7b6d7385d7c54cc5ccea7f30f30ab24ce407242
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/server.d.ts
@@ -0,0 +1,2 @@
+export declare function initialise_server(): any;
+//# sourceMappingURL=server.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/server.d.ts.map b/node_modules/@gradio/client/dist/test/server.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..da108d064bf287d0e7756476543e476bf7dcc8e6
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/server.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/test/server.ts"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,IAAI,GAAG,CAEvC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/test_data.d.ts b/node_modules/@gradio/client/dist/test/test_data.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..992f31d292809e5ee921bf176724a75553a68f9f
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/test_data.d.ts
@@ -0,0 +1,76 @@
+import { ApiData, ApiInfo, Config, EndpointInfo } from "../types";
+export declare const runtime_response: {
+ stage: string;
+ hardware: {
+ current: string;
+ requested: string;
+ };
+ storage: {
+ current: null;
+ requested: null;
+ };
+ gcTimeout: number;
+ replicas: {
+ current: number;
+ requested: number;
+ };
+ devMode: boolean;
+ domains: {
+ domain: string;
+ isCustom: boolean;
+ stage: string;
+ }[];
+};
+export declare const transformed_api_info: ApiInfo;
+export declare const response_api_info: ApiInfo;
+export declare const config_response: Config;
+export declare const whoami_response: {
+ type: string;
+ id: string;
+ name: string;
+ fullname: string;
+ email: string;
+ emailVerified: boolean;
+ canPay: boolean;
+ periodEnd: number;
+ isPro: boolean;
+ avatarUrl: string;
+ orgs: never[];
+ auth: {
+ type: string;
+ accessToken: {
+ displayName: string;
+ role: string;
+ };
+ };
+};
+export declare const duplicate_response: {
+ url: string;
+};
+export declare const hardware_sleeptime_response: {
+ stage: string;
+ hardware: {
+ current: string;
+ requested: string;
+ };
+ storage: null;
+ gcTimeout: number;
+ replicas: {
+ current: number;
+ requested: number;
+ };
+ devMode: boolean;
+ domains: {
+ domain: string;
+ isCustom: boolean;
+ stage: string;
+ }[];
+};
+export declare const endpoint_info: EndpointInfo;
+export declare const discussions_response: {
+ discussions: never[];
+ count: number;
+ start: number;
+ numClosedDiscussions: number;
+};
+//# sourceMappingURL=test_data.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/test/test_data.d.ts.map b/node_modules/@gradio/client/dist/test/test_data.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..b61d61155c4b680fd7a0ae7d4d567a0c58289d75
--- /dev/null
+++ b/node_modules/@gradio/client/dist/test/test_data.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"test_data.d.ts","sourceRoot":"","sources":["../../src/test/test_data.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAElE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;CAuB5B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,OAAO,CA6CjD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAiC9C,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,MAkW7B,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;CAmB3B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;CAE9B,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;CAoBvC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YAAY,CAAC,OAAO,CA0C/C,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;CAKhC,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/types.d.ts b/node_modules/@gradio/client/dist/types.d.ts
index d21788db9648a1fdb51a69ba5bb95e6f6bebb7a2..0d441fc4ac0e9accaef588646f6e2775dbc812d7 100644
--- a/node_modules/@gradio/client/dist/types.d.ts
+++ b/node_modules/@gradio/client/dist/types.d.ts
@@ -1,13 +1,117 @@
+///
+import { hardware_types } from "./helpers/spaces";
+import type { SvelteComponent } from "svelte";
+import type { ComponentType } from "svelte";
+export interface ApiData {
+ label: string;
+ parameter_name: string;
+ parameter_default?: any;
+ parameter_has_default?: boolean;
+ type: {
+ type: any;
+ description: string;
+ };
+ component: string;
+ example_input?: any;
+ python_type: {
+ type: string;
+ description: string;
+ };
+ serializer: string;
+}
+export interface JsApiData {
+ label: string;
+ parameter_name: string;
+ parameter_default?: any;
+ parameter_has_default?: boolean;
+ type: string;
+ description: string;
+ component: string;
+ example_input?: any;
+ serializer: string;
+ python_type: {
+ type: string;
+ description: string;
+ };
+}
+export interface EndpointInfo {
+ parameters: T[];
+ returns: T[];
+ type?: DependencyTypes;
+}
+export interface ApiInfo {
+ named_endpoints: Record>;
+ unnamed_endpoints: Record>;
+}
+export interface BlobRef {
+ path: string[];
+ type: string | undefined;
+ blob: Blob | File | false;
+}
+export type DataType = string | Buffer | Record | any[];
+export declare class Command {
+ type: string;
+ command: string;
+ meta: {
+ path: string;
+ name: string;
+ orig_path: string;
+ };
+ fileData?: FileData;
+ constructor(command: string, meta: {
+ path: string;
+ name: string;
+ orig_path: string;
+ });
+}
+export type SubmitFunction = (endpoint: string | number, data: unknown[] | Record, event_data?: unknown, trigger_id?: number | null) => SubmitIterable;
+export type PredictFunction = (endpoint: string | number, data: unknown[] | Record, event_data?: unknown) => Promise;
+export type client_return = {
+ config: Config | undefined;
+ predict: PredictFunction;
+ submit: SubmitFunction;
+ component_server: (component_id: number, fn_name: string, data: unknown[]) => any;
+ view_api: (_fetch: typeof fetch) => Promise>;
+};
+export interface SubmitIterable extends AsyncIterable {
+ [Symbol.asyncIterator](): AsyncIterator;
+ cancel: () => Promise;
+}
+export type PredictReturn = {
+ type: EventType;
+ time: Date;
+ data: unknown;
+ endpoint: string;
+ fn_index: number;
+};
+export type SpaceStatus = SpaceStatusNormal | SpaceStatusError;
+export interface SpaceStatusNormal {
+ status: "sleeping" | "running" | "building" | "error" | "stopped";
+ detail: "SLEEPING" | "RUNNING" | "RUNNING_BUILDING" | "BUILDING" | "NOT_FOUND";
+ load_status: "pending" | "error" | "complete" | "generating";
+ message: string;
+}
+export interface SpaceStatusError {
+ status: "space_error" | "paused";
+ detail: "NO_APP_FILE" | "CONFIG_ERROR" | "BUILD_ERROR" | "RUNTIME_ERROR" | "PAUSED";
+ load_status: "error";
+ message: string;
+ discussions_enabled: boolean;
+}
+export type SpaceStatusCallback = (a: SpaceStatus) => void;
export interface Config {
- auth_required: boolean | undefined;
+ auth_required: boolean;
+ analytics_enabled: boolean;
+ connect_heartbeat: boolean;
auth_message: string;
- components: any[];
+ components: ComponentMeta[];
css: string | null;
js: string | null;
head: string | null;
- dependencies: any[];
+ dependencies: Dependency[];
dev_mode: boolean;
enable_queue: boolean;
+ show_error: boolean;
layout: any;
mode: "blocks" | "interface";
root: string;
@@ -16,17 +120,89 @@ export interface Config {
title: string;
version: string;
space_id: string | null;
+ is_space: boolean;
is_colab: boolean;
show_api: boolean;
stylesheets: string[];
path: string;
- protocol?: "sse_v1" | "sse" | "ws";
+ protocol: "sse_v3" | "sse_v2.1" | "sse_v2" | "sse_v1" | "sse" | "ws";
+ max_file_size?: number;
+ theme_hash?: number;
+}
+export interface ComponentMeta {
+ type: string;
+ id: number;
+ has_modes: boolean;
+ props: SharedProps;
+ instance: SvelteComponent;
+ component: ComponentType;
+ documentation?: Documentation;
+ children?: ComponentMeta[];
+ parent?: ComponentMeta;
+ value?: any;
+ component_class_id: string;
+ key: string | number | null;
+ rendered_in?: number;
+}
+interface SharedProps {
+ elem_id?: string;
+ elem_classes?: string[];
+ components?: string[];
+ server_fns?: string[];
+ interactive: boolean;
+ [key: string]: unknown;
+ root_url?: string;
+}
+export interface Documentation {
+ type?: TypeDescription;
+ description?: TypeDescription;
+ example_data?: string;
+}
+interface TypeDescription {
+ input_payload?: string;
+ response_object?: string;
+ payload?: string;
+}
+export interface Dependency {
+ id: number;
+ targets: [number, string][];
+ inputs: number[];
+ outputs: number[];
+ backend_fn: boolean;
+ js: string | null;
+ scroll_to_output: boolean;
+ trigger: "click" | "load" | string;
+ max_batch_size: number;
+ show_progress: "full" | "minimal" | "hidden";
+ frontend_fn: ((...args: unknown[]) => Promise) | null;
+ status?: string;
+ queue: boolean | null;
+ every: number | null;
+ batch: boolean;
+ api_name: string | null;
+ cancels: number[];
+ types: DependencyTypes;
+ collects_event_data: boolean;
+ pending_request?: boolean;
+ trigger_after?: number;
+ trigger_only_on_success?: boolean;
+ trigger_mode: "once" | "multiple" | "always_last";
+ final_event: Payload | null;
+ show_api: boolean;
+ zerogpu?: boolean;
+ rendered_in: number | null;
+}
+export interface DependencyTypes {
+ continuous: boolean;
+ generator: boolean;
+ cancel: boolean;
}
export interface Payload {
+ fn_index: number;
data: unknown[];
- fn_index?: number;
- event_data?: unknown;
time?: Date;
+ event_data?: unknown;
+ trigger_id?: number | null;
}
export interface PostResponse {
error?: string;
@@ -36,6 +212,50 @@ export interface UploadResponse {
error?: string;
files?: string[];
}
+export interface DuplicateOptions extends ClientOptions {
+ private?: boolean;
+ hardware?: (typeof hardware_types)[number];
+ timeout?: number;
+}
+export interface ClientOptions {
+ hf_token?: `hf_${string}`;
+ status_callback?: SpaceStatusCallback | null;
+ auth?: [string, string] | null;
+ with_null_state?: boolean;
+ events?: EventType[];
+}
+export interface FileData {
+ name: string;
+ orig_name?: string;
+ size?: number;
+ data: string;
+ blob?: File;
+ is_file?: boolean;
+ mime_type?: string;
+ alt_text?: string;
+}
+export type EventType = "data" | "status" | "log" | "render";
+export interface EventMap {
+ data: PayloadMessage;
+ status: StatusMessage;
+ log: LogMessage;
+ render: RenderMessage;
+}
+export type GradioEvent = {
+ [P in EventType]: EventMap[P];
+}[EventType];
+export interface Log {
+ log: string;
+ level: "warning" | "info";
+}
+export interface Render {
+ data: {
+ components: any[];
+ layout: any;
+ dependencies: Dependency[];
+ render_id: number;
+ };
+}
export interface Status {
queue: boolean;
code?: string;
@@ -54,52 +274,27 @@ export interface Status {
desc: string | null;
}[];
time?: Date;
+ changed_state_ids?: number[];
}
-export interface LogMessage {
- log: string;
- level: "warning" | "info";
-}
-export interface SpaceStatusNormal {
- status: "sleeping" | "running" | "building" | "error" | "stopped";
- detail: "SLEEPING" | "RUNNING" | "RUNNING_BUILDING" | "BUILDING" | "NOT_FOUND";
- load_status: "pending" | "error" | "complete" | "generating";
- message: string;
+export interface StatusMessage extends Status {
+ type: "status";
+ endpoint: string;
+ fn_index: number;
}
-export interface SpaceStatusError {
- status: "space_error" | "paused";
- detail: "NO_APP_FILE" | "CONFIG_ERROR" | "BUILD_ERROR" | "RUNTIME_ERROR" | "PAUSED";
- load_status: "error";
- message: string;
- discussions_enabled: boolean;
+export interface PayloadMessage extends Payload {
+ type: "data";
+ endpoint: string;
+ fn_index: number;
}
-export type SpaceStatus = SpaceStatusNormal | SpaceStatusError;
-export type status_callback_function = (a: Status) => void;
-export type SpaceStatusCallback = (a: SpaceStatus) => void;
-export type EventType = "data" | "status" | "log";
-export interface EventMap {
- data: Payload;
- status: Status;
- log: LogMessage;
+export interface LogMessage extends Log {
+ type: "log";
+ endpoint: string;
+ fn_index: number;
}
-export type Event = {
- [P in K]: EventMap[P] & {
- type: P;
- endpoint: string;
- fn_index: number;
- };
-}[K];
-export type EventListener = (event: Event) => void;
-export type ListenerMap = {
- [P in K]?: EventListener[];
-};
-export interface FileData {
- name: string;
- orig_name?: string;
- size?: number;
- data: string;
- blob?: File;
- is_file?: boolean;
- mime_type?: string;
- alt_text?: string;
+export interface RenderMessage extends Render {
+ type: "render";
+ endpoint: string;
+ fn_index: number;
}
+export {};
//# sourceMappingURL=types.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/types.d.ts.map b/node_modules/@gradio/client/dist/types.d.ts.map
index aa3e5c67abce350a819f9778b4712588ce979427..3af060093be8bd61b7885088b76eb041c3082fff 100644
--- a/node_modules/@gradio/client/dist/types.d.ts.map
+++ b/node_modules/@gradio/client/dist/types.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/upload.d.ts b/node_modules/@gradio/client/dist/upload.d.ts
index ae951c0c89d33d7b94898354f1d16bf965ba6781..b88fbaa343ab9426f9463358d0991b7d2a1242d7 100644
--- a/node_modules/@gradio/client/dist/upload.d.ts
+++ b/node_modules/@gradio/client/dist/upload.d.ts
@@ -1,10 +1,5 @@
-import { upload_files } from "./client";
-export declare function normalise_file(file: FileData | null, server_url: string, proxy_url: string | null): FileData | null;
-export declare function normalise_file(file: FileData[] | null, server_url: string, proxy_url: string | null): FileData[] | null;
-export declare function normalise_file(file: FileData[] | FileData | null, server_url: string, // root: string,
-proxy_url: string | null): FileData[] | FileData | null;
-export declare function get_fetchable_url_or_file(path: string | null, server_url: string, proxy_url: string | null): string;
-export declare function upload(file_data: FileData[], root: string, upload_id?: string, upload_fn?: typeof upload_files): Promise<(FileData | null)[] | null>;
+import type { Client } from "./client";
+export declare function upload(this: Client, file_data: FileData[], root_url: string, upload_id?: string, max_file_size?: number): Promise<(FileData | null)[] | null>;
export declare function prepare_files(files: File[], is_stream?: boolean): Promise;
export declare class FileData {
path: string;
@@ -15,6 +10,9 @@ export declare class FileData {
is_stream?: boolean;
mime_type?: string;
alt_text?: string;
+ readonly meta: {
+ _type: string;
+ };
constructor({ path, url, orig_name, size, blob, is_stream, mime_type, alt_text }: {
path: string;
url?: string;
diff --git a/node_modules/@gradio/client/dist/upload.d.ts.map b/node_modules/@gradio/client/dist/upload.d.ts.map
index 171bcb37faac09e061b28a2666735eb8bcae6a4c..dd3eb79e34fa8f5b642c8ae2097353607f1efae6 100644
--- a/node_modules/@gradio/client/dist/upload.d.ts.map
+++ b/node_modules/@gradio/client/dist/upload.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,wBAAgB,cAAc,CAC7B,IAAI,EAAE,QAAQ,GAAG,IAAI,EACrB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,GACtB,QAAQ,GAAG,IAAI,CAAC;AAEnB,wBAAgB,cAAc,CAC7B,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,GACtB,QAAQ,EAAE,GAAG,IAAI,CAAC;AAErB,wBAAgB,cAAc,CAC7B,IAAI,EAAE,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI,EAClC,UAAU,EAAE,MAAM,EAAE,gBAAgB;AACpC,SAAS,EAAE,MAAM,GAAG,IAAI,GACtB,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC;AAqDhC,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAUR;AAED,wBAAsB,MAAM,CAC3B,SAAS,EAAE,QAAQ,EAAE,EACrB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,GAAE,OAAO,YAA2B,GAC3C,OAAO,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAwBrC;AAED,wBAAsB,aAAa,CAClC,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAYrB;AAED,qBAAa,QAAQ;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;gBAEN,EACX,IAAI,EACJ,GAAG,EACH,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,SAAS,EACT,QAAQ,EACR,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB;CAUD"}
\ No newline at end of file
+{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,wBAAsB,MAAM,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,QAAQ,EAAE,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAsCrC;AAED,wBAAsB,aAAa,CAClC,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAYrB;AAED,qBAAa,QAAQ;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,IAAI;;MAAgC;gBAEjC,EACX,IAAI,EACJ,GAAG,EACH,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,SAAS,EACT,QAAQ,EACR,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB;CAUD"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils.d.ts.map b/node_modules/@gradio/client/dist/utils.d.ts.map
deleted file mode 100644
index c8e6010f70f6421ccff8f6d56625c53e837c5a1c..0000000000000000000000000000000000000000
--- a/node_modules/@gradio/client/dist/utils.d.ts.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,GACtB,MAAM,CAKR;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACb,CAgCA;AAED,eAAO,MAAM,aAAa,QAAqB,CAAC;AAChD,eAAO,MAAM,eAAe,QAAwB,CAAC;AACrD,wBAAsB,gBAAgB,CACrC,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,MAAM,EAAE,GACpB,OAAO,CAAC;IACV,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;CAClC,CAAC,CA4CD;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB;AAID,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAe5E;AAED,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,MAAM,EAAE,GACnB,OAAO,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAqB1C;AAED,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,EAC7C,KAAK,EAAE,MAAM,MAAM,EAAE,GACnB,OAAO,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAuB1C;AAED,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,MAAM,EAAE,GACnB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED,eAAO,MAAM,cAAc,0GAQjB,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/duplicate.d.ts b/node_modules/@gradio/client/dist/utils/duplicate.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2db4e1f6aed77c8ef0ac705cf467fd8d0c3a1083
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/duplicate.d.ts
@@ -0,0 +1,4 @@
+import type { DuplicateOptions } from "../types";
+import { Client } from "../client";
+export declare function duplicate(app_reference: string, options: DuplicateOptions): Promise;
+//# sourceMappingURL=duplicate.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/duplicate.d.ts.map b/node_modules/@gradio/client/dist/utils/duplicate.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..d13451ab2c1d2b1adddcb79165b1d936e3e384d6
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/duplicate.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../src/utils/duplicate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAQnC,wBAAsB,SAAS,CAC9B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,MAAM,CAAC,CAuGjB"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/handle_blob.d.ts b/node_modules/@gradio/client/dist/utils/handle_blob.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42fb43d0da8c8506c52ec47bd0196163f7f359a9
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/handle_blob.d.ts
@@ -0,0 +1,5 @@
+import { type ApiData, type EndpointInfo, type JsApiData } from "../types";
+import type { Client } from "..";
+export declare function handle_blob(this: Client, endpoint: string, data: unknown[], api_info: EndpointInfo): Promise;
+export declare function process_local_file_commands(client: Client, data: unknown[]): Promise;
+//# sourceMappingURL=handle_blob.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/handle_blob.d.ts.map b/node_modules/@gradio/client/dist/utils/handle_blob.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..9336156c7c8d83efd7b623ba7b981b2e5f0fef6a
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/handle_blob.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"handle_blob.d.ts","sourceRoot":"","sources":["../../src/utils/handle_blob.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAOjC,wBAAsB,WAAW,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EAAE,EACf,QAAQ,EAAE,YAAY,CAAC,SAAS,GAAG,OAAO,CAAC,GACzC,OAAO,CAAC,OAAO,EAAE,CAAC,CAsCpB;AAED,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CAQf"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/post_data.d.ts b/node_modules/@gradio/client/dist/utils/post_data.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b08b61ae99d1c05d29b14f7413bc36358379e271
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/post_data.d.ts
@@ -0,0 +1,4 @@
+import type { PostResponse } from "../types";
+import { Client } from "..";
+export declare function post_data(this: Client, url: string, body: unknown, additional_headers?: any): Promise<[PostResponse, number]>;
+//# sourceMappingURL=post_data.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/post_data.d.ts.map b/node_modules/@gradio/client/dist/utils/post_data.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..1803a88c5bbdaeb717922e5e1d82d7b4d623a0c5
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/post_data.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"post_data.d.ts","sourceRoot":"","sources":["../../src/utils/post_data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAE5B,wBAAsB,SAAS,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,kBAAkB,CAAC,EAAE,GAAG,GACtB,OAAO,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CA4BjC"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/predict.d.ts b/node_modules/@gradio/client/dist/utils/predict.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..69ea43c6d7cce55ba438ba203d2062c37143cadf
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/predict.d.ts
@@ -0,0 +1,4 @@
+import { Client } from "../client";
+import type { PredictReturn } from "../types";
+export declare function predict(this: Client, endpoint: string | number, data: unknown[] | Record): Promise;
+//# sourceMappingURL=predict.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/predict.d.ts.map b/node_modules/@gradio/client/dist/utils/predict.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..e84337f2a219ab4a4534334f1733849d9c91a727
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/predict.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"predict.d.ts","sourceRoot":"","sources":["../../src/utils/predict.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,UAAU,CAAC;AAE1D,wBAAsB,OAAO,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvC,OAAO,CAAC,aAAa,CAAC,CAiDxB"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/stream.d.ts b/node_modules/@gradio/client/dist/utils/stream.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..de5337bc3cba1b86bb38f2d0be720bd68b150d9d
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/stream.d.ts
@@ -0,0 +1,9 @@
+import type { Client } from "../client";
+export declare function open_stream(this: Client): Promise;
+export declare function close_stream(stream_status: {
+ open: boolean;
+}, abort_controller: AbortController | null): void;
+export declare function apply_diff_stream(pending_diff_streams: Record, event_id: string, data: any): void;
+export declare function apply_diff(obj: any, diff: [string, (number | string)[], any][]): any;
+export declare function readable_stream(input: RequestInfo | URL, init?: RequestInit): EventSource;
+//# sourceMappingURL=stream.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/stream.d.ts.map b/node_modules/@gradio/client/dist/utils/stream.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..2b4217b1d8efc3f614e1d95749ad9ec19ba89f80
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/stream.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/utils/stream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGxC,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF7D;AAED,wBAAgB,YAAY,CAC3B,aAAa,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,EAChC,gBAAgB,EAAE,eAAe,GAAG,IAAI,GACtC,IAAI,CAKN;AAED,wBAAgB,iBAAiB,CAChC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,EAC7C,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,GACP,IAAI,CAcN;AAED,wBAAgB,UAAU,CACzB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,GACxC,GAAG,CAML;AAkDD,wBAAgB,eAAe,CAC9B,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,GAAE,WAAgB,GACpB,WAAW,CA8Cb"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/submit.d.ts b/node_modules/@gradio/client/dist/utils/submit.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cd3a611dffdbbc4acf42c65dfe75129690edce15
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/submit.d.ts
@@ -0,0 +1,4 @@
+import type { GradioEvent, SubmitIterable } from "../types";
+import { Client } from "../client";
+export declare function submit(this: Client, endpoint: string | number, data: unknown[] | Record, event_data?: unknown, trigger_id?: number | null, all_events?: boolean): SubmitIterable;
+//# sourceMappingURL=submit.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/submit.d.ts.map b/node_modules/@gradio/client/dist/utils/submit.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..cd661695b9077268483d7ebd3b4fdc131b909a25
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/submit.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/utils/submit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGX,WAAW,EAMX,cAAc,EACd,MAAM,UAAU,CAAC;AAYlB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,wBAAgB,MAAM,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzC,UAAU,CAAC,EAAE,OAAO,EACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,EAC1B,UAAU,CAAC,EAAE,OAAO,GAClB,cAAc,CAAC,WAAW,CAAC,CAwvB7B"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/upload_files.d.ts b/node_modules/@gradio/client/dist/utils/upload_files.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9696aae9fd3e8cd1d7e4eb0fe2927430d37a692f
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/upload_files.d.ts
@@ -0,0 +1,4 @@
+import type { Client } from "..";
+import type { UploadResponse } from "../types";
+export declare function upload_files(this: Client, root_url: string, files: (Blob | File)[], upload_id?: string): Promise;
+//# sourceMappingURL=upload_files.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/upload_files.d.ts.map b/node_modules/@gradio/client/dist/utils/upload_files.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..a73856c66c15eb074dba1d2b737104dcd40aae62
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/upload_files.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"upload_files.d.ts","sourceRoot":"","sources":["../../src/utils/upload_files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAEjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,EACtB,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CA0CzB"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/view_api.d.ts b/node_modules/@gradio/client/dist/utils/view_api.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0110c2bf57fa9f618868c490c5df71d8e2906ee7
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/view_api.d.ts
@@ -0,0 +1,3 @@
+import { Client } from "../client";
+export declare function view_api(this: Client): Promise;
+//# sourceMappingURL=view_api.d.ts.map
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/utils/view_api.d.ts.map b/node_modules/@gradio/client/dist/utils/view_api.d.ts.map
new file mode 100644
index 0000000000000000000000000000000000000000..4c6145fb7502dfead21011d46cc69ed5f53a839b
--- /dev/null
+++ b/node_modules/@gradio/client/dist/utils/view_api.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"view_api.d.ts","sourceRoot":"","sources":["../../src/utils/view_api.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAInC,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA8DzD"}
\ No newline at end of file
diff --git a/node_modules/@gradio/client/dist/wrapper-6f348d45.js b/node_modules/@gradio/client/dist/wrapper-CviSselG.js
similarity index 92%
rename from node_modules/@gradio/client/dist/wrapper-6f348d45.js
rename to node_modules/@gradio/client/dist/wrapper-CviSselG.js
index 4c7627d28002f2a8a6aee066f8025c118298437e..f8f357ba505fbfd749fa757bd944f3d02b654031 100644
--- a/node_modules/@gradio/client/dist/wrapper-6f348d45.js
+++ b/node_modules/@gradio/client/dist/wrapper-CviSselG.js
@@ -1,12 +1,15 @@
import require$$0 from "stream";
-import require$$0$1 from "zlib";
-import require$$0$2 from "buffer";
+import require$$0$2 from "zlib";
+import require$$0$1 from "fs";
+import require$$1$1 from "path";
+import require$$2 from "os";
+import require$$0$3 from "buffer";
import require$$3 from "net";
import require$$4 from "tls";
import require$$5 from "crypto";
-import require$$0$3 from "events";
-import require$$1$1 from "https";
-import require$$2 from "http";
+import require$$0$4 from "events";
+import require$$1$2 from "https";
+import require$$2$1 from "http";
import require$$7 from "url";
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -18,10 +21,7 @@ function getAugmentedNamespace(n) {
if (typeof f == "function") {
var a = function a2() {
if (this instanceof a2) {
- var args = [null];
- args.push.apply(args, arguments);
- var Ctor = Function.bind.apply(f, args);
- return new Ctor();
+ return Reflect.construct(f, arguments, this.constructor);
}
return f.apply(this, arguments);
};
@@ -151,6 +151,248 @@ var constants = {
NOOP: () => {
}
};
+var bufferutil = { exports: {} };
+var nodeGypBuild$1 = { exports: {} };
+function commonjsRequire(path) {
+ throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
+}
+var nodeGypBuild;
+var hasRequiredNodeGypBuild$1;
+function requireNodeGypBuild$1() {
+ if (hasRequiredNodeGypBuild$1)
+ return nodeGypBuild;
+ hasRequiredNodeGypBuild$1 = 1;
+ var fs = require$$0$1;
+ var path = require$$1$1;
+ var os = require$$2;
+ var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : commonjsRequire;
+ var vars = process.config && process.config.variables || {};
+ var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
+ var abi = process.versions.modules;
+ var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
+ var arch = process.env.npm_config_arch || os.arch();
+ var platform = process.env.npm_config_platform || os.platform();
+ var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
+ var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
+ var uv = (process.versions.uv || "").split(".")[0];
+ nodeGypBuild = load;
+ function load(dir) {
+ return runtimeRequire(load.resolve(dir));
+ }
+ load.resolve = load.path = function(dir) {
+ dir = path.resolve(dir || ".");
+ try {
+ var name = runtimeRequire(path.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
+ if (process.env[name + "_PREBUILD"])
+ dir = process.env[name + "_PREBUILD"];
+ } catch (err) {
+ }
+ if (!prebuildsOnly) {
+ var release = getFirst(path.join(dir, "build/Release"), matchBuild);
+ if (release)
+ return release;
+ var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
+ if (debug)
+ return debug;
+ }
+ var prebuild = resolve(dir);
+ if (prebuild)
+ return prebuild;
+ var nearby = resolve(path.dirname(process.execPath));
+ if (nearby)
+ return nearby;
+ var target = [
+ "platform=" + platform,
+ "arch=" + arch,
+ "runtime=" + runtime,
+ "abi=" + abi,
+ "uv=" + uv,
+ armv ? "armv=" + armv : "",
+ "libc=" + libc,
+ "node=" + process.versions.node,
+ process.versions.electron ? "electron=" + process.versions.electron : "",
+ typeof __webpack_require__ === "function" ? "webpack=true" : ""
+ // eslint-disable-line
+ ].filter(Boolean).join(" ");
+ throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
+ function resolve(dir2) {
+ var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
+ var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
+ if (!tuple)
+ return;
+ var prebuilds = path.join(dir2, "prebuilds", tuple.name);
+ var parsed = readdirSync(prebuilds).map(parseTags);
+ var candidates = parsed.filter(matchTags(runtime, abi));
+ var winner = candidates.sort(compareTags(runtime))[0];
+ if (winner)
+ return path.join(prebuilds, winner.file);
+ }
+ };
+ function readdirSync(dir) {
+ try {
+ return fs.readdirSync(dir);
+ } catch (err) {
+ return [];
+ }
+ }
+ function getFirst(dir, filter) {
+ var files = readdirSync(dir).filter(filter);
+ return files[0] && path.join(dir, files[0]);
+ }
+ function matchBuild(name) {
+ return /\.node$/.test(name);
+ }
+ function parseTuple(name) {
+ var arr = name.split("-");
+ if (arr.length !== 2)
+ return;
+ var platform2 = arr[0];
+ var architectures = arr[1].split("+");
+ if (!platform2)
+ return;
+ if (!architectures.length)
+ return;
+ if (!architectures.every(Boolean))
+ return;
+ return { name, platform: platform2, architectures };
+ }
+ function matchTuple(platform2, arch2) {
+ return function(tuple) {
+ if (tuple == null)
+ return false;
+ if (tuple.platform !== platform2)
+ return false;
+ return tuple.architectures.includes(arch2);
+ };
+ }
+ function compareTuples(a, b) {
+ return a.architectures.length - b.architectures.length;
+ }
+ function parseTags(file) {
+ var arr = file.split(".");
+ var extension2 = arr.pop();
+ var tags = { file, specificity: 0 };
+ if (extension2 !== "node")
+ return;
+ for (var i = 0; i < arr.length; i++) {
+ var tag = arr[i];
+ if (tag === "node" || tag === "electron" || tag === "node-webkit") {
+ tags.runtime = tag;
+ } else if (tag === "napi") {
+ tags.napi = true;
+ } else if (tag.slice(0, 3) === "abi") {
+ tags.abi = tag.slice(3);
+ } else if (tag.slice(0, 2) === "uv") {
+ tags.uv = tag.slice(2);
+ } else if (tag.slice(0, 4) === "armv") {
+ tags.armv = tag.slice(4);
+ } else if (tag === "glibc" || tag === "musl") {
+ tags.libc = tag;
+ } else {
+ continue;
+ }
+ tags.specificity++;
+ }
+ return tags;
+ }
+ function matchTags(runtime2, abi2) {
+ return function(tags) {
+ if (tags == null)
+ return false;
+ if (tags.runtime !== runtime2 && !runtimeAgnostic(tags))
+ return false;
+ if (tags.abi !== abi2 && !tags.napi)
+ return false;
+ if (tags.uv && tags.uv !== uv)
+ return false;
+ if (tags.armv && tags.armv !== armv)
+ return false;
+ if (tags.libc && tags.libc !== libc)
+ return false;
+ return true;
+ };
+ }
+ function runtimeAgnostic(tags) {
+ return tags.runtime === "node" && tags.napi;
+ }
+ function compareTags(runtime2) {
+ return function(a, b) {
+ if (a.runtime !== b.runtime) {
+ return a.runtime === runtime2 ? -1 : 1;
+ } else if (a.abi !== b.abi) {
+ return a.abi ? -1 : 1;
+ } else if (a.specificity !== b.specificity) {
+ return a.specificity > b.specificity ? -1 : 1;
+ } else {
+ return 0;
+ }
+ };
+ }
+ function isNwjs() {
+ return !!(process.versions && process.versions.nw);
+ }
+ function isElectron() {
+ if (process.versions && process.versions.electron)
+ return true;
+ if (process.env.ELECTRON_RUN_AS_NODE)
+ return true;
+ return typeof window !== "undefined" && window.process && window.process.type === "renderer";
+ }
+ function isAlpine(platform2) {
+ return platform2 === "linux" && fs.existsSync("/etc/alpine-release");
+ }
+ load.parseTags = parseTags;
+ load.matchTags = matchTags;
+ load.compareTags = compareTags;
+ load.parseTuple = parseTuple;
+ load.matchTuple = matchTuple;
+ load.compareTuples = compareTuples;
+ return nodeGypBuild;
+}
+var hasRequiredNodeGypBuild;
+function requireNodeGypBuild() {
+ if (hasRequiredNodeGypBuild)
+ return nodeGypBuild$1.exports;
+ hasRequiredNodeGypBuild = 1;
+ if (typeof process.addon === "function") {
+ nodeGypBuild$1.exports = process.addon.bind(process);
+ } else {
+ nodeGypBuild$1.exports = requireNodeGypBuild$1();
+ }
+ return nodeGypBuild$1.exports;
+}
+var fallback;
+var hasRequiredFallback;
+function requireFallback() {
+ if (hasRequiredFallback)
+ return fallback;
+ hasRequiredFallback = 1;
+ const mask2 = (source, mask3, output, offset, length) => {
+ for (var i = 0; i < length; i++) {
+ output[offset + i] = source[i] ^ mask3[i & 3];
+ }
+ };
+ const unmask2 = (buffer, mask3) => {
+ const length = buffer.length;
+ for (var i = 0; i < length; i++) {
+ buffer[i] ^= mask3[i & 3];
+ }
+ };
+ fallback = { mask: mask2, unmask: unmask2 };
+ return fallback;
+}
+var hasRequiredBufferutil;
+function requireBufferutil() {
+ if (hasRequiredBufferutil)
+ return bufferutil.exports;
+ hasRequiredBufferutil = 1;
+ try {
+ bufferutil.exports = requireNodeGypBuild()(__dirname);
+ } catch (e) {
+ bufferutil.exports = requireFallback();
+ }
+ return bufferutil.exports;
+}
var unmask$1;
var mask;
const { EMPTY_BUFFER: EMPTY_BUFFER$3 } = constants;
@@ -212,7 +454,7 @@ bufferUtil$1.exports = {
};
if (!process.env.WS_NO_BUFFER_UTIL) {
try {
- const bufferUtil2 = require("bufferutil");
+ const bufferUtil2 = requireBufferutil();
mask = bufferUtil$1.exports.mask = function(source, mask2, output, offset, length) {
if (length < 48)
_mask(source, mask2, output, offset, length);
@@ -273,7 +515,7 @@ let Limiter$1 = class Limiter {
}
};
var limiter = Limiter$1;
-const zlib = require$$0$1;
+const zlib = require$$0$2;
const bufferUtil = bufferUtilExports;
const Limiter2 = limiter;
const { kStatusCode: kStatusCode$2 } = constants;
@@ -654,7 +896,7 @@ const __viteOptionalPeerDep_utf8Validate_ws$1 = /* @__PURE__ */ Object.freeze(/*
}, Symbol.toStringTag, { value: "Module" }));
const require$$1 = /* @__PURE__ */ getAugmentedNamespace(__viteOptionalPeerDep_utf8Validate_ws$1);
var isValidUTF8_1;
-const { isUtf8 } = require$$0$2;
+const { isUtf8 } = require$$0$3;
const tokenChars$2 = [
0,
0,
@@ -2159,9 +2401,9 @@ function format$1(extensions) {
}).join(", ");
}
var extension$1 = { format: format$1, parse: parse$2 };
-const EventEmitter$1 = require$$0$3;
-const https = require$$1$1;
-const http$1 = require$$2;
+const EventEmitter$1 = require$$0$4;
+const https = require$$1$2;
+const http$1 = require$$2$1;
const net = require$$3;
const tls = require$$4;
const { randomBytes, createHash: createHash$1 } = require$$5;
@@ -3065,8 +3307,8 @@ function parse(header) {
return protocols;
}
var subprotocol$1 = { parse };
-const EventEmitter = require$$0$3;
-const http = require$$2;
+const EventEmitter = require$$0$4;
+const http = require$$2$1;
const { createHash } = require$$5;
const extension = extension$1;
const PerMessageDeflate2 = permessageDeflate;
diff --git a/node_modules/@gradio/client/index.html b/node_modules/@gradio/client/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..1afd437873ac0e0ad160a577a5fb325dcb07142b
--- /dev/null
+++ b/node_modules/@gradio/client/index.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ Client
+
+
+
+
+
+
diff --git a/node_modules/@gradio/client/package.json b/node_modules/@gradio/client/package.json
index fba80007e51d742c76c3489c837570591b027e15..024af1390848353e1e6a542b86ada70fffb42f25 100644
--- a/node_modules/@gradio/client/package.json
+++ b/node_modules/@gradio/client/package.json
@@ -1,33 +1,86 @@
{
- "name": "@gradio/client",
- "version": "0.10.1",
- "description": "Gradio API client",
- "type": "module",
- "main": "dist/index.js",
- "author": "",
- "license": "ISC",
- "exports": {
- ".": {
- "import": "./dist/index.js"
- },
- "./package.json": "./package.json"
+ "_from": "@gradio/client",
+ "_id": "@gradio/client@1.1.1",
+ "_inBundle": false,
+ "_integrity": "sha512-6Hzc+/wmNRkodefp0bvfOBQbEakwg31Ye9IVOjfoHkvunHoIzjupM+1m7VwhQXt8pMCjOw8Hc7zhvwnwy6f5GQ==",
+ "_location": "/@gradio/client",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "tag",
+ "registry": true,
+ "raw": "@gradio/client",
+ "name": "@gradio/client",
+ "escapedName": "@gradio%2fclient",
+ "scope": "@gradio",
+ "rawSpec": "",
+ "saveSpec": null,
+ "fetchSpec": "latest"
},
+ "_requiredBy": [
+ "#USER",
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/@gradio/client/-/client-1.1.1.tgz",
+ "_shasum": "4cd2b0769d0ef1d6b5cda8cf6d3209ed0e4364ec",
+ "_spec": "@gradio/client",
+ "_where": "/Users/sylvainfiloni/Documents/HuggingFace_Projects/live-vision",
+ "author": "",
+ "bundleDependencies": false,
"dependencies": {
+ "@types/eventsource": "^1.1.15",
"bufferutil": "^4.0.7",
+ "eventsource": "^2.0.2",
+ "fetch-event-stream": "^0.1.5",
+ "msw": "^2.2.1",
"semiver": "^1.1.0",
+ "textlinestream": "^1.1.1",
+ "typescript": "^5.0.0",
"ws": "^8.13.0"
},
+ "deprecated": false,
+ "description": "Gradio API client",
"devDependencies": {
- "@types/ws": "^8.5.4",
- "esbuild": "^0.19.0"
+ "@types/ws": "^8.5.10",
+ "esbuild": "^0.21.0"
},
"engines": {
"node": ">=18.0.0"
},
+ "exports": {
+ ".": {
+ "import": "./dist/index.js"
+ },
+ "./package.json": "./package.json"
+ },
+ "license": "ISC",
+ "main": "dist/index.js",
"main_changeset": true,
+ "name": "@gradio/client",
"scripts": {
+ "build": "pnpm bundle && pnpm generate_types",
"bundle": "vite build --ssr",
"generate_types": "tsc",
- "build": "pnpm bundle && pnpm generate_types"
- }
-}
\ No newline at end of file
+ "preview:browser": "vite dev --mode=preview",
+ "test": "pnpm test:client && pnpm test:client:node",
+ "test:client": "vitest run -c vite.config.js",
+ "test:client:node": "TEST_MODE=node vitest run -c vite.config.js"
+ },
+ "type": "module",
+ "version": "1.1.1",
+ "warnings": [
+ {
+ "code": "ENOTSUP",
+ "required": {
+ "node": ">=18.0.0"
+ },
+ "pkgid": "@gradio/client@1.1.1"
+ },
+ {
+ "code": "ENOTSUP",
+ "required": {
+ "node": ">=18.0.0"
+ },
+ "pkgid": "@gradio/client@1.1.1"
+ }
+ ]
+}
diff --git a/node_modules/@gradio/client/src/client.node-test.ts b/node_modules/@gradio/client/src/client.node-test.ts
deleted file mode 100644
index 9964583b4558d55a62b0fbf78a440e572e5a204f..0000000000000000000000000000000000000000
--- a/node_modules/@gradio/client/src/client.node-test.ts
+++ /dev/null
@@ -1,172 +0,0 @@
-import { test, describe, assert } from "vitest";
-import { readFileSync } from "fs";
-import { join, dirname } from "path";
-import { fileURLToPath } from "url";
-import { Blob } from "node:buffer";
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const image_path = join(
- __dirname,
- "..",
- "..",
- "..",
- "demo",
- "kitchen_sink",
- "files",
- "lion.jpg"
-);
-
-import { walk_and_store_blobs, client, handle_blob } from "./client";
-
-describe.skip("extract blob parts", () => {
- test("convert Buffer to Blob", async () => {
- const image = readFileSync(image_path);
- await client("gradio/hello_world_main");
- const parts = walk_and_store_blobs({
- data: {
- image
- }
- });
-
- assert.isTrue(parts[0].blob instanceof Blob);
- });
-
- test("leave node Blob as Blob", async () => {
- const image = new Blob([readFileSync(image_path)]);
-
- await client("gradio/hello_world_main");
- const parts = walk_and_store_blobs({
- data: {
- image
- }
- });
-
- assert.isTrue(parts[0].blob instanceof Blob);
- });
-
- test("handle deep structures", async () => {
- const image = new Blob([readFileSync(image_path)]);
-
- await client("gradio/hello_world_main");
- const parts = walk_and_store_blobs({
- a: {
- b: {
- data: {
- image
- }
- }
- }
- });
-
- assert.isTrue(parts[0].blob instanceof Blob);
- });
-
- test("handle deep structures with arrays", async () => {
- const image = new Blob([readFileSync(image_path)]);
-
- await client("gradio/hello_world_main");
- const parts = walk_and_store_blobs({
- a: [
- {
- b: [
- {
- data: [
- {
- image
- }
- ]
- }
- ]
- }
- ]
- });
-
- assert.isTrue(parts[0].blob instanceof Blob);
- });
-
- test("handle deep structures with arrays 2", async () => {
- const image = new Blob([readFileSync(image_path)]);
-
- await client("gradio/hello_world_main");
- const obj = {
- a: [
- {
- b: [
- {
- data: [[image], image, [image, [image]]]
- }
- ]
- }
- ]
- };
- const parts = walk_and_store_blobs(obj);
-
- function map_path(
- obj: Record,
- parts: { path: string[]; blob: any }[]
- ) {
- const { path, blob } = parts[parts.length - 1];
- let ref = obj;
- path.forEach((p) => (ref = ref[p]));
-
- return ref === blob;
- }
-
- assert.isTrue(parts[0].blob instanceof Blob);
- // assert.isTrue(map_path(obj, parts));
- });
-});
-
-describe("handle_blob", () => {
- test("handle blobs", async () => {
- const image = new Blob([readFileSync(image_path)]);
-
- const app = await client("gradio/hello_world_main");
- const obj = [
- {
- a: [
- {
- b: [
- {
- data: [[image], image, [image, [image]]]
- }
- ]
- }
- ]
- }
- ];
-
- const parts = await handle_blob(app.config.root, obj, undefined);
- //@ts-ignore
- // assert.isString(parts.data[0].a[0].b[0].data[0][0]);
- });
-});
-
-describe.skip("private space", () => {
- test("can access a private space", async () => {
- const image = new Blob([readFileSync(image_path)]);
-
- const app = await client("pngwn/hello_world", {
- hf_token: "hf_"
- });
-
- console.log(app);
- const obj = [
- {
- a: [
- {
- b: [
- {
- data: [[image], image, [image, [image]]]
- }
- ]
- }
- ]
- }
- ];
-
- const parts = await handle_blob(app.config.root, obj, "hf_");
- //@ts-ignore
- assert.isString(parts.data[0].a[0].b[0].data[0][0]);
- });
-});
diff --git a/node_modules/@gradio/client/src/client.ts b/node_modules/@gradio/client/src/client.ts
index 6355d5a04cadee5dcb057a73eefd2b7e0eeabbf5..0d694fd7bdc09b7fc25ebb082485566b710d6510 100644
--- a/node_modules/@gradio/client/src/client.ts
+++ b/node_modules/@gradio/client/src/client.ts
@@ -1,1727 +1,440 @@
-//@ts-nocheck
-
-import semiver from "semiver";
-
-import {
- process_endpoint,
- RE_SPACE_NAME,
- map_names_to_ids,
- discussions_enabled,
- get_space_hardware,
- set_space_hardware,
- set_space_timeout,
- hardware_types,
- resolve_root
-} from "./utils.js";
-
import type {
- EventType,
- EventListener,
- ListenerMap,
- Event,
- Payload,
- PostResponse,
- UploadResponse,
- Status,
+ ApiData,
+ ApiInfo,
+ ClientOptions,
+ Config,
+ DuplicateOptions,
+ EndpointInfo,
+ JsApiData,
+ PredictReturn,
SpaceStatus,
- SpaceStatusCallback
-} from "./types.js";
-
-import { FileData, normalise_file } from "./upload";
-
-import type { Config } from "./types.js";
-
-type event = (
- eventType: K,
- listener: EventListener
-) => SubmitReturn;
-type predict = (
- endpoint: string | number,
- data?: unknown[],
- event_data?: unknown
-) => Promise;
-
-type client_return = {
- predict: predict;
- config: Config;
- submit: (
- endpoint: string | number,
- data?: unknown[],
- event_data?: unknown,
- trigger_id?: number | null
- ) => SubmitReturn;
- component_server: (
- component_id: number,
- fn_name: string,
- data: unknown[]
- ) => any;
- view_api: (c?: Config) => Promise>;
-};
-
-type SubmitReturn = {
- on: event;
- off: event;
- cancel: () => Promise;
- destroy: () => void;
-};
-
-const QUEUE_FULL_MSG = "This application is too busy. Keep trying!";
-const BROKEN_CONNECTION_MSG = "Connection errored out.";
-
-export let NodeBlob;
-
-export async function duplicate(
- app_reference: string,
- options: {
- hf_token: `hf_${string}`;
- private?: boolean;
- status_callback: SpaceStatusCallback;
- hardware?: (typeof hardware_types)[number];
- timeout?: number;
- }
-): Promise {
- const { hf_token, private: _private, hardware, timeout } = options;
-
- if (hardware && !hardware_types.includes(hardware)) {
- throw new Error(
- `Invalid hardware type provided. Valid types are: ${hardware_types
- .map((v) => `"${v}"`)
- .join(",")}.`
- );
- }
- const headers = {
- Authorization: `Bearer ${hf_token}`
- };
-
- const user = (
- await (
- await fetch(`https://huggingface.co/api/whoami-v2`, {
- headers
- })
- ).json()
- ).name;
-
- const space_name = app_reference.split("/")[1];
- const body: {
- repository: string;
- private?: boolean;
- } = {
- repository: `${user}/${space_name}`
- };
-
- if (_private) {
- body.private = true;
- }
-
- try {
- const response = await fetch(
- `https://huggingface.co/api/spaces/${app_reference}/duplicate`,
- {
- method: "POST",
- headers: { "Content-Type": "application/json", ...headers },
- body: JSON.stringify(body)
- }
- );
-
- if (response.status === 409) {
- return client(`${user}/${space_name}`, options);
+ Status,
+ UploadResponse,
+ client_return,
+ SubmitIterable,
+ GradioEvent
+} from "./types";
+import { view_api } from "./utils/view_api";
+import { upload_files } from "./utils/upload_files";
+import { upload, FileData } from "./upload";
+import { handle_blob } from "./utils/handle_blob";
+import { post_data } from "./utils/post_data";
+import { predict } from "./utils/predict";
+import { duplicate } from "./utils/duplicate";
+import { submit } from "./utils/submit";
+import { RE_SPACE_NAME, process_endpoint } from "./helpers/api_info";
+import {
+ map_names_to_ids,
+ resolve_cookies,
+ resolve_config,
+ get_jwt,
+ parse_and_set_cookies
+} from "./helpers/init_helpers";
+import { check_space_status } from "./helpers/spaces";
+import { open_stream, readable_stream } from "./utils/stream";
+import { API_INFO_ERROR_MSG, CONFIG_ERROR_MSG } from "./constants";
+
+export class Client {
+ app_reference: string;
+ options: ClientOptions;
+
+ config: Config | undefined;
+ api_info: ApiInfo | undefined;
+ api_map: Record = {};
+ session_hash: string = Math.random().toString(36).substring(2);
+ jwt: string | false = false;
+ last_status: Record = {};
+
+ private cookies: string | null = null;
+
+ // streaming
+ stream_status = { open: false };
+ pending_stream_messages: Record = {};
+ pending_diff_streams: Record = {};
+ event_callbacks: Record Promise> = {};
+ unclosed_events: Set = new Set();
+ heartbeat_event: EventSource | null = null;
+ abort_controller: AbortController | null = null;
+ stream_instance: EventSource | null = null;
+
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise {
+ const headers = new Headers(init?.headers || {});
+ if (this && this.cookies) {
+ headers.append("Cookie", this.cookies);
}
- const duplicated_space = await response.json();
- let original_hardware;
+ return fetch(input, { ...init, headers });
+ }
- if (!hardware) {
- original_hardware = await get_space_hardware(app_reference, hf_token);
- }
+ stream(url: URL): EventSource {
+ this.abort_controller = new AbortController();
- const requested_hardware = hardware || original_hardware || "cpu-basic";
- await set_space_hardware(
- `${user}/${space_name}`,
- requested_hardware,
- hf_token
- );
+ this.stream_instance = readable_stream(url.toString(), {
+ signal: this.abort_controller.signal
+ });
- await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
- return client(duplicated_space.url, options);
- } catch (e: any) {
- throw new Error(e);
+ return this.stream_instance;
}
-}
-interface Client {
- post_data: (
- url: string,
- body: unknown,
- token?: `hf_${string}`
- ) => Promise<[PostResponse, number]>;
+ view_api: () => Promise>;
upload_files: (
- root: string,
- files: File[],
- token?: `hf_${string}`,
+ root_url: string,
+ files: (Blob | File)[],
upload_id?: string
) => Promise;
- client: (
- app_reference: string,
- options: {
- hf_token?: `hf_${string}`;
- status_callback?: SpaceStatusCallback;
- normalise_files?: boolean;
- }
- ) => Promise;
+ upload: (
+ file_data: FileData[],
+ root_url: string,
+ upload_id?: string,
+ max_file_size?: number
+ ) => Promise<(FileData | null)[] | null>;
handle_blob: (
endpoint: string,
data: unknown[],
- api_info: ApiInfo,
- token?: `hf_${string}`
+ endpoint_info: EndpointInfo
) => Promise;
-}
-
-export function api_factory(
- fetch_implementation: typeof fetch,
- EventSource_factory: (url: URL) => EventSource
-): Client {
- return { post_data, upload_files, client, handle_blob };
-
- async function post_data(
+ post_data: (
url: string,
body: unknown,
- token?: `hf_${string}`
- ): Promise<[PostResponse, number]> {
- const headers: {
- Authorization?: string;
- "Content-Type": "application/json";
- } = { "Content-Type": "application/json" };
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
- try {
- var response = await fetch_implementation(url, {
- method: "POST",
- body: JSON.stringify(body),
- headers
- });
- } catch (e) {
- return [{ error: BROKEN_CONNECTION_MSG }, 500];
- }
- let output: PostResponse;
- let status: int;
- try {
- output = await response.json();
- status = response.status;
- } catch (e) {
- output = { error: `Could not parse server response: ${e}` };
- status = 500;
+ additional_headers?: any
+ ) => Promise;
+ submit: (
+ endpoint: string | number,
+ data: unknown[] | Record,
+ event_data?: unknown,
+ trigger_id?: number | null,
+ all_events?: boolean
+ ) => SubmitIterable;
+ predict: (
+ endpoint: string | number,
+ data: unknown[] | Record,
+ event_data?: unknown
+ ) => Promise;
+ open_stream: () => Promise;
+ private resolve_config: (endpoint: string) => Promise;
+ private resolve_cookies: () => Promise;
+ constructor(
+ app_reference: string,
+ options: ClientOptions = { events: ["data"] }
+ ) {
+ this.app_reference = app_reference;
+ if (!options.events) {
+ options.events = ["data"];
}
- return [output, status];
- }
- async function upload_files(
- root: string,
- files: (Blob | File)[],
- token?: `hf_${string}`,
- upload_id?: string
- ): Promise {
- const headers: {
- Authorization?: string;
- } = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
- const chunkSize = 1000;
- const uploadResponses = [];
- for (let i = 0; i < files.length; i += chunkSize) {
- const chunk = files.slice(i, i + chunkSize);
- const formData = new FormData();
- chunk.forEach((file) => {
- formData.append("files", file);
- });
- try {
- const upload_url = upload_id
- ? `${root}/upload?upload_id=${upload_id}`
- : `${root}/upload`;
- var response = await fetch_implementation(upload_url, {
- method: "POST",
- body: formData,
- headers
- });
- } catch (e) {
- return { error: BROKEN_CONNECTION_MSG };
- }
- const output: UploadResponse["files"] = await response.json();
- uploadResponses.push(...output);
- }
- return { files: uploadResponses };
+ this.options = options;
+
+ this.view_api = view_api.bind(this);
+ this.upload_files = upload_files.bind(this);
+ this.handle_blob = handle_blob.bind(this);
+ this.post_data = post_data.bind(this);
+ this.submit = submit.bind(this);
+ this.predict = predict.bind(this);
+ this.open_stream = open_stream.bind(this);
+ this.resolve_config = resolve_config.bind(this);
+ this.resolve_cookies = resolve_cookies.bind(this);
+ this.upload = upload.bind(this);
}
- async function client(
- app_reference: string,
- options: {
- hf_token?: `hf_${string}`;
- status_callback?: SpaceStatusCallback;
- normalise_files?: boolean;
- } = { normalise_files: true }
- ): Promise {
- return new Promise(async (res) => {
- const { status_callback, hf_token, normalise_files } = options;
- const return_obj = {
- predict,
- submit,
- view_api,
- component_server
- };
-
- const transform_files = normalise_files ?? true;
- if (
- (typeof window === "undefined" || !("WebSocket" in window)) &&
- !global.Websocket
- ) {
- const ws = await import("ws");
- NodeBlob = (await import("node:buffer")).Blob;
- //@ts-ignore
- global.WebSocket = ws.WebSocket;
- }
-
- const { ws_protocol, http_protocol, host, space_id } =
- await process_endpoint(app_reference, hf_token);
-
- const session_hash = Math.random().toString(36).substring(2);
- const last_status: Record = {};
- let stream_open = false;
- let pending_stream_messages: Record = {}; // Event messages may be received by the SSE stream before the initial data POST request is complete. To resolve this race condition, we store the messages in a dictionary and process them when the POST request is complete.
- let event_stream: EventSource | null = null;
- const event_callbacks: Record Promise> = {};
- const unclosed_events: Set = new Set();
- let config: Config;
- let api_map: Record = {};
-
- let jwt: false | string = false;
-
- if (hf_token && space_id) {
- jwt = await get_jwt(space_id, hf_token);
- }
-
- async function config_success(_config: Config): Promise {
- config = _config;
- api_map = map_names_to_ids(_config?.dependencies || []);
- if (config.auth_required) {
- return {
- config,
- ...return_obj
- };
- }
- try {
- api = await view_api(config);
- } catch (e) {
- console.error(`Could not get api details: ${e.message}`);
- }
+ private async init(): Promise {
+ if (
+ (typeof window === "undefined" || !("WebSocket" in window)) &&
+ !global.WebSocket
+ ) {
+ const ws = await import("ws");
+ global.WebSocket = ws.WebSocket as unknown as typeof WebSocket;
+ }
- return {
- config,
- ...return_obj
- };
+ try {
+ if (this.options.auth) {
+ await this.resolve_cookies();
}
- let api: ApiInfo;
- async function handle_space_sucess(status: SpaceStatus): Promise {
- if (status_callback) status_callback(status);
- if (status.status === "running")
- try {
- config = await resolve_config(
- fetch_implementation,
- `${http_protocol}//${host}`,
- hf_token
- );
- const _config = await config_success(config);
- res(_config);
- } catch (e) {
- console.error(e);
- if (status_callback) {
- status_callback({
- status: "error",
- message: "Could not load this space.",
- load_status: "error",
- detail: "NOT_FOUND"
- });
- }
- }
- }
+ await this._resolve_config().then(({ config }) =>
+ this._resolve_hearbeat(config)
+ );
+ } catch (e: any) {
+ throw Error(e);
+ }
- try {
- config = await resolve_config(
- fetch_implementation,
- `${http_protocol}//${host}`,
- hf_token
- );
+ this.api_info = await this.view_api();
+ this.api_map = map_names_to_ids(this.config?.dependencies || []);
+ }
- const _config = await config_success(config);
- res(_config);
- } catch (e) {
- console.error(e);
- if (space_id) {
- check_space_status(
- space_id,
- RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain",
- handle_space_sucess
+ async _resolve_hearbeat(_config: Config): Promise {
+ if (_config) {
+ this.config = _config;
+ if (this.config && this.config.connect_heartbeat) {
+ if (this.config.space_id && this.options.hf_token) {
+ this.jwt = await get_jwt(
+ this.config.space_id,
+ this.options.hf_token,
+ this.cookies
);
- } else {
- if (status_callback)
- status_callback({
- status: "error",
- message: "Could not load this space.",
- load_status: "error",
- detail: "NOT_FOUND"
- });
}
}
+ }
- function predict(
- endpoint: string,
- data: unknown[],
- event_data?: unknown
- ): Promise {
- let data_returned = false;
- let status_complete = false;
- let dependency;
- if (typeof endpoint === "number") {
- dependency = config.dependencies[endpoint];
- } else {
- const trimmed_endpoint = endpoint.replace(/^\//, "");
- dependency = config.dependencies[api_map[trimmed_endpoint]];
- }
-
- if (dependency.types.continuous) {
- throw new Error(
- "Cannot call predict on this function as it may run forever. Use submit instead"
- );
- }
+ if (_config.space_id && this.options.hf_token) {
+ this.jwt = await get_jwt(_config.space_id, this.options.hf_token);
+ }
- return new Promise((res, rej) => {
- const app = submit(endpoint, data, event_data);
- let result;
+ if (this.config && this.config.connect_heartbeat) {
+ // connect to the heartbeat endpoint via GET request
+ const heartbeat_url = new URL(
+ `${this.config.root}/heartbeat/${this.session_hash}`
+ );
- app
- .on("data", (d) => {
- // if complete message comes before data, resolve here
- if (status_complete) {
- app.destroy();
- res(d);
- }
- data_returned = true;
- result = d;
- })
- .on("status", (status) => {
- if (status.stage === "error") rej(status);
- if (status.stage === "complete") {
- status_complete = true;
- // if complete message comes after data, resolve here
- if (data_returned) {
- app.destroy();
- res(result);
- }
- }
- });
- });
+ // if the jwt is available, add it to the query params
+ if (this.jwt) {
+ heartbeat_url.searchParams.set("__sign", this.jwt);
}
- function submit(
- endpoint: string | number,
- data: unknown[],
- event_data?: unknown,
- trigger_id: number | null = null
- ): SubmitReturn {
- let fn_index: number;
- let api_info;
-
- if (typeof endpoint === "number") {
- fn_index = endpoint;
- api_info = api.unnamed_endpoints[fn_index];
- } else {
- const trimmed_endpoint = endpoint.replace(/^\//, "");
-
- fn_index = api_map[trimmed_endpoint];
- api_info = api.named_endpoints[endpoint.trim()];
- }
-
- if (typeof fn_index !== "number") {
- throw new Error(
- "There is no endpoint matching that name of fn_index matching that number."
- );
- }
-
- let websocket: WebSocket;
- let eventSource: EventSource;
- let protocol = config.protocol ?? "ws";
-
- const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
- let payload: Payload;
- let event_id: string | null = null;
- let complete: false | Record = false;
- const listener_map: ListenerMap = {};
- let url_params = "";
- if (typeof window !== "undefined") {
- url_params = new URLSearchParams(window.location.search).toString();
- }
-
- handle_blob(`${config.root}`, data, api_info, hf_token).then(
- (_payload) => {
- payload = {
- data: _payload || [],
- event_data,
- fn_index,
- trigger_id
- };
- if (skip_queue(fn_index, config)) {
- fire_event({
- type: "status",
- endpoint: _endpoint,
- stage: "pending",
- queue: false,
- fn_index,
- time: new Date()
- });
-
- post_data(
- `${config.root}/run${
- _endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`
- }${url_params ? "?" + url_params : ""}`,
- {
- ...payload,
- session_hash
- },
- hf_token
- )
- .then(([output, status_code]) => {
- const data = transform_files
- ? transform_output(
- output.data,
- api_info,
- config.root,
- config.root_url
- )
- : output.data;
- if (status_code == 200) {
- fire_event({
- type: "data",
- endpoint: _endpoint,
- fn_index,
- data: data,
- time: new Date()
- });
-
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- stage: "complete",
- eta: output.average_duration,
- queue: false,
- time: new Date()
- });
- } else {
- fire_event({
- type: "status",
- stage: "error",
- endpoint: _endpoint,
- fn_index,
- message: output.error,
- queue: false,
- time: new Date()
- });
- }
- })
- .catch((e) => {
- fire_event({
- type: "status",
- stage: "error",
- message: e.message,
- endpoint: _endpoint,
- fn_index,
- queue: false,
- time: new Date()
- });
- });
- } else if (protocol == "ws") {
- fire_event({
- type: "status",
- stage: "pending",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- let url = new URL(`${ws_protocol}://${resolve_root(
- host,
- config.path,
- true
- )}
- /queue/join${url_params ? "?" + url_params : ""}`);
-
- if (jwt) {
- url.searchParams.set("__sign", jwt);
- }
-
- websocket = new WebSocket(url);
-
- websocket.onclose = (evt) => {
- if (!evt.wasClean) {
- fire_event({
- type: "status",
- stage: "error",
- broken: true,
- message: BROKEN_CONNECTION_MSG,
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- }
- };
-
- websocket.onmessage = function (event) {
- const _data = JSON.parse(event.data);
- const { type, status, data } = handle_message(
- _data,
- last_status[fn_index]
- );
-
- if (type === "update" && status && !complete) {
- // call 'status' listeners
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- time: new Date(),
- ...status
- });
- if (status.stage === "error") {
- websocket.close();
- }
- } else if (type === "hash") {
- websocket.send(JSON.stringify({ fn_index, session_hash }));
- return;
- } else if (type === "data") {
- websocket.send(JSON.stringify({ ...payload, session_hash }));
- } else if (type === "complete") {
- complete = status;
- } else if (type === "log") {
- fire_event({
- type: "log",
- log: data.log,
- level: data.level,
- endpoint: _endpoint,
- fn_index
- });
- } else if (type === "generating") {
- fire_event({
- type: "status",
- time: new Date(),
- ...status,
- stage: status?.stage!,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- if (data) {
- fire_event({
- type: "data",
- time: new Date(),
- data: transform_files
- ? transform_output(
- data.data,
- api_info,
- config.root,
- config.root_url
- )
- : data.data,
- endpoint: _endpoint,
- fn_index
- });
-
- if (complete) {
- fire_event({
- type: "status",
- time: new Date(),
- ...complete,
- stage: status?.stage!,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- websocket.close();
- }
- }
- };
-
- // different ws contract for gradio versions older than 3.6.0
- //@ts-ignore
- if (semiver(config.version || "2.0.0", "3.6") < 0) {
- addEventListener("open", () =>
- websocket.send(JSON.stringify({ hash: session_hash }))
- );
- }
- } else if (protocol == "sse") {
- fire_event({
- type: "status",
- stage: "pending",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- var params = new URLSearchParams({
- fn_index: fn_index.toString(),
- session_hash: session_hash
- }).toString();
- let url = new URL(
- `${config.root}/queue/join?${
- url_params ? url_params + "&" : ""
- }${params}`
- );
-
- eventSource = EventSource_factory(url);
+ // Just connect to the endpoint without parsing the response. Ref: https://github.com/gradio-app/gradio/pull/7974#discussion_r1557717540
+ if (!this.heartbeat_event) {
+ this.heartbeat_event = this.stream(heartbeat_url);
+ }
+ }
+ }
- eventSource.onmessage = async function (event) {
- const _data = JSON.parse(event.data);
- const { type, status, data } = handle_message(
- _data,
- last_status[fn_index]
- );
+ static async connect(
+ app_reference: string,
+ options: ClientOptions = {
+ events: ["data"]
+ }
+ ): Promise {
+ const client = new this(app_reference, options); // this refers to the class itself, not the instance
+ await client.init();
+ return client;
+ }
- if (type === "update" && status && !complete) {
- // call 'status' listeners
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- time: new Date(),
- ...status
- });
- if (status.stage === "error") {
- eventSource.close();
- }
- } else if (type === "data") {
- event_id = _data.event_id as string;
- let [_, status] = await post_data(
- `${config.root}/queue/data`,
- {
- ...payload,
- session_hash,
- event_id
- },
- hf_token
- );
- if (status !== 200) {
- fire_event({
- type: "status",
- stage: "error",
- message: BROKEN_CONNECTION_MSG,
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- eventSource.close();
- }
- } else if (type === "complete") {
- complete = status;
- } else if (type === "log") {
- fire_event({
- type: "log",
- log: data.log,
- level: data.level,
- endpoint: _endpoint,
- fn_index
- });
- } else if (type === "generating") {
- fire_event({
- type: "status",
- time: new Date(),
- ...status,
- stage: status?.stage!,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- if (data) {
- fire_event({
- type: "data",
- time: new Date(),
- data: transform_files
- ? transform_output(
- data.data,
- api_info,
- config.root,
- config.root_url
- )
- : data.data,
- endpoint: _endpoint,
- fn_index
- });
+ close(): void {
+ this.heartbeat_event?.close();
+ }
- if (complete) {
- fire_event({
- type: "status",
- time: new Date(),
- ...complete,
- stage: status?.stage!,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- eventSource.close();
- }
- }
- };
- } else if (protocol == "sse_v1") {
- fire_event({
- type: "status",
- stage: "pending",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
+ static async duplicate(
+ app_reference: string,
+ options: DuplicateOptions = {
+ events: ["data"]
+ }
+ ): Promise {
+ return duplicate(app_reference, options);
+ }
- post_data(
- `${config.root}/queue/join?${url_params}`,
- {
- ...payload,
- session_hash
- },
- hf_token
- ).then(([response, status]) => {
- if (status === 503) {
- fire_event({
- type: "status",
- stage: "error",
- message: QUEUE_FULL_MSG,
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- } else if (status !== 200) {
- fire_event({
- type: "status",
- stage: "error",
- message: BROKEN_CONNECTION_MSG,
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- } else {
- event_id = response.event_id as string;
- let callback = async function (_data: object): void {
- try {
- const { type, status, data } = handle_message(
- _data,
- last_status[fn_index]
- );
+ private async _resolve_config(): Promise {
+ const { http_protocol, host, space_id } = await process_endpoint(
+ this.app_reference,
+ this.options.hf_token
+ );
- if (type == "heartbeat") {
- return;
- }
+ const { status_callback } = this.options;
+ let config: Config | undefined;
- if (type === "update" && status && !complete) {
- // call 'status' listeners
- fire_event({
- type: "status",
- endpoint: _endpoint,
- fn_index,
- time: new Date(),
- ...status
- });
- } else if (type === "complete") {
- complete = status;
- } else if (type == "unexpected_error") {
- console.error("Unexpected error", status?.message);
- fire_event({
- type: "status",
- stage: "error",
- message:
- status?.message || "An Unexpected Error Occurred!",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- } else if (type === "log") {
- fire_event({
- type: "log",
- log: data.log,
- level: data.level,
- endpoint: _endpoint,
- fn_index
- });
- return;
- } else if (type === "generating") {
- fire_event({
- type: "status",
- time: new Date(),
- ...status,
- stage: status?.stage!,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- if (data) {
- fire_event({
- type: "data",
- time: new Date(),
- data: transform_files
- ? transform_output(
- data.data,
- api_info,
- config.root,
- config.root_url
- )
- : data.data,
- endpoint: _endpoint,
- fn_index
- });
+ try {
+ config = await this.resolve_config(`${http_protocol}//${host}`);
- if (complete) {
- fire_event({
- type: "status",
- time: new Date(),
- ...complete,
- stage: status?.stage!,
- queue: true,
- endpoint: _endpoint,
- fn_index
- });
- }
- }
+ if (!config) {
+ throw new Error(CONFIG_ERROR_MSG);
+ }
- if (
- status?.stage === "complete" ||
- status?.stage === "error"
- ) {
- if (event_callbacks[event_id]) {
- delete event_callbacks[event_id];
- }
- }
- } catch (e) {
- console.error("Unexpected client exception", e);
- fire_event({
- type: "status",
- stage: "error",
- message: "An Unexpected Error Occurred!",
- queue: true,
- endpoint: _endpoint,
- fn_index,
- time: new Date()
- });
- close_stream();
- }
- };
- if (event_id in pending_stream_messages) {
- pending_stream_messages[event_id].forEach((msg) =>
- callback(msg)
- );
- delete pending_stream_messages[event_id];
- }
- event_callbacks[event_id] = callback;
- unclosed_events.add(event_id);
- if (!stream_open) {
- open_stream();
- }
- }
- });
- }
- }
+ return this.config_success(config);
+ } catch (e: any) {
+ if (space_id && status_callback) {
+ check_space_status(
+ space_id,
+ RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain",
+ this.handle_space_success
);
-
- function fire_event(event: Event): void {
- const narrowed_listener_map: ListenerMap = listener_map;
- const listeners = narrowed_listener_map[event.type] || [];
- listeners?.forEach((l) => l(event));
- }
-
- function on(
- eventType: K,
- listener: EventListener
- ): SubmitReturn {
- const narrowed_listener_map: ListenerMap = listener_map;
- const listeners = narrowed_listener_map[eventType] || [];
- narrowed_listener_map[eventType] = listeners;
- listeners?.push(listener);
-
- return { on, off, cancel, destroy };
- }
-
- function off(
- eventType: K,
- listener: EventListener
- ): SubmitReturn {
- const narrowed_listener_map: ListenerMap = listener_map;
- let listeners = narrowed_listener_map[eventType] || [];
- listeners = listeners?.filter((l) => l !== listener);
- narrowed_listener_map[eventType] = listeners;
-
- return { on, off, cancel, destroy };
- }
-
- async function cancel(): Promise {
- const _status: Status = {
- stage: "complete",
- queue: false,
- time: new Date()
- };
- complete = _status;
- fire_event({
- ..._status,
- type: "status",
- endpoint: _endpoint,
- fn_index: fn_index
+ } else {
+ if (status_callback)
+ status_callback({
+ status: "error",
+ message: "Could not load this space.",
+ load_status: "error",
+ detail: "NOT_FOUND"
});
-
- let cancel_request = {};
- if (protocol === "ws") {
- if (websocket && websocket.readyState === 0) {
- websocket.addEventListener("open", () => {
- websocket.close();
- });
- } else {
- websocket.close();
- }
- cancel_request = { fn_index, session_hash };
- } else {
- eventSource.close();
- cancel_request = { event_id };
- }
-
- try {
- await fetch_implementation(`${config.root}/reset`, {
- headers: { "Content-Type": "application/json" },
- method: "POST",
- body: JSON.stringify(cancel_request)
- });
- } catch (e) {
- console.warn(
- "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable."
- );
- }
- }
-
- function destroy(): void {
- for (const event_type in listener_map) {
- listener_map[event_type as "data" | "status"].forEach((fn) => {
- off(event_type as "data" | "status", fn);
- });
- }
- }
-
- return {
- on,
- off,
- cancel,
- destroy
- };
+ throw Error(e);
}
+ }
+ }
- function open_stream(): void {
- stream_open = true;
- let params = new URLSearchParams({
- session_hash: session_hash
- }).toString();
- let url = new URL(`${config.root}/queue/data?${params}`);
- event_stream = EventSource_factory(url);
- event_stream.onmessage = async function (event) {
- let _data = JSON.parse(event.data);
- const event_id = _data.event_id;
- if (!event_id) {
- await Promise.all(
- Object.keys(event_callbacks).map((event_id) =>
- event_callbacks[event_id](_data)
- )
- );
- } else if (event_callbacks[event_id]) {
- if (_data.msg === "process_completed") {
- unclosed_events.delete(event_id);
- if (unclosed_events.size === 0) {
- close_stream();
- }
- }
- let fn = event_callbacks[event_id];
- window.setTimeout(fn, 0, _data); // need to do this to put the event on the end of the event loop, so the browser can refresh between callbacks and not freeze in case of quick generations. See https://github.com/gradio-app/gradio/pull/7055
- } else {
- if (!pending_stream_messages[event_id]) {
- pending_stream_messages[event_id] = [];
- }
- pending_stream_messages[event_id].push(_data);
- }
- };
- event_stream.onerror = async function (event) {
- await Promise.all(
- Object.keys(event_callbacks).map((event_id) =>
- event_callbacks[event_id]({
- msg: "unexpected_error",
- message: BROKEN_CONNECTION_MSG
- })
- )
- );
- close_stream();
- };
- }
+ private async config_success(
+ _config: Config
+ ): Promise {
+ this.config = _config;
- function close_stream(): void {
- stream_open = false;
- event_stream?.close();
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
+ if (window.location.protocol === "https:") {
+ this.config.root = this.config.root.replace("http://", "https://");
}
+ }
- async function component_server(
- component_id: number,
- fn_name: string,
- data: unknown[]
- ): Promise {
- const headers: {
- Authorization?: string;
- "Content-Type": "application/json";
- } = { "Content-Type": "application/json" };
- if (hf_token) {
- headers.Authorization = `Bearer ${hf_token}`;
- }
- let root_url: string;
- let component = config.components.find(
- (comp) => comp.id === component_id
- );
- if (component?.props?.root_url) {
- root_url = component.props.root_url;
- } else {
- root_url = config.root;
- }
- const response = await fetch_implementation(
- `${root_url}/component_server/`,
- {
- method: "POST",
- body: JSON.stringify({
- data: data,
- component_id: component_id,
- fn_name: fn_name,
- session_hash: session_hash
- }),
- headers
- }
- );
-
- if (!response.ok) {
- throw new Error(
- "Could not connect to component server: " + response.statusText
- );
- }
-
- const output = await response.json();
- return output;
- }
+ if (this.config.auth_required) {
+ return this.prepare_return_obj();
+ }
- async function view_api(config?: Config): Promise> {
- if (api) return api;
+ try {
+ this.api_info = await this.view_api();
+ } catch (e) {
+ console.error(API_INFO_ERROR_MSG + (e as Error).message);
+ }
- const headers: {
- Authorization?: string;
- "Content-Type": "application/json";
- } = { "Content-Type": "application/json" };
- if (hf_token) {
- headers.Authorization = `Bearer ${hf_token}`;
- }
- let response: Response;
- // @ts-ignore
- if (semiver(config.version || "2.0.0", "3.30") < 0) {
- response = await fetch_implementation(
- "https://gradio-space-api-fetcher-v2.hf.space/api",
- {
- method: "POST",
- body: JSON.stringify({
- serialize: false,
- config: JSON.stringify(config)
- }),
- headers
- }
- );
- } else {
- response = await fetch_implementation(`${config.root}/info`, {
- headers
- });
- }
+ return this.prepare_return_obj();
+ }
- if (!response.ok) {
- throw new Error(BROKEN_CONNECTION_MSG);
+ async handle_space_success(status: SpaceStatus): Promise {
+ if (!this) {
+ throw new Error(CONFIG_ERROR_MSG);
+ }
+ const { status_callback } = this.options;
+ if (status_callback) status_callback(status);
+ if (status.status === "running") {
+ try {
+ this.config = await this._resolve_config();
+ if (!this.config) {
+ throw new Error(CONFIG_ERROR_MSG);
}
- let api_info = (await response.json()) as
- | ApiInfo
- | { api: ApiInfo };
- if ("api" in api_info) {
- api_info = api_info.api;
- }
+ const _config = await this.config_success(this.config);
- if (
- api_info.named_endpoints["/predict"] &&
- !api_info.unnamed_endpoints["0"]
- ) {
- api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"];
+ return _config as Config;
+ } catch (e) {
+ if (status_callback) {
+ status_callback({
+ status: "error",
+ message: "Could not load this space.",
+ load_status: "error",
+ detail: "NOT_FOUND"
+ });
}
-
- const x = transform_api_info(api_info, config, api_map);
- return x;
+ throw e;
}
- });
- }
-
- async function handle_blob(
- endpoint: string,
- data: unknown[],
- api_info: ApiInfo,
- token?: `hf_${string}`
- ): Promise {
- const blob_refs = await walk_and_store_blobs(
- data,
- undefined,
- [],
- true,
- api_info
- );
-
- return Promise.all(
- blob_refs.map(async ({ path, blob, type }) => {
- if (blob) {
- const file_url = (await upload_files(endpoint, [blob], token))
- .files[0];
- return { path, file_url, type, name: blob?.name };
- }
- return { path, type };
- })
- ).then((r) => {
- r.forEach(({ path, file_url, type, name }) => {
- if (type === "Gallery") {
- update_object(data, file_url, path);
- } else if (file_url) {
- const file = new FileData({ path: file_url, orig_name: name });
- update_object(data, file, path);
- }
- });
-
- return data;
- });
- }
-}
-
-export const { post_data, upload_files, client, handle_blob } = api_factory(
- fetch,
- (...args) => new EventSource(...args)
-);
-
-function transform_output(
- data: any[],
- api_info: any,
- root_url: string,
- remote_url?: string
-): unknown[] {
- return data.map((d, i) => {
- if (api_info?.returns?.[i]?.component === "File") {
- return normalise_file(d, root_url, remote_url);
- } else if (api_info?.returns?.[i]?.component === "Gallery") {
- return d.map((img) => {
- return Array.isArray(img)
- ? [normalise_file(img[0], root_url, remote_url), img[1]]
- : [normalise_file(img, root_url, remote_url), null];
- });
- } else if (typeof d === "object" && d.path) {
- return normalise_file(d, root_url, remote_url);
}
- return d;
- });
-}
-
-interface ApiData {
- label: string;
- type: {
- type: any;
- description: string;
- };
- component: string;
- example_input?: any;
-}
-
-interface JsApiData {
- label: string;
- type: string;
- component: string;
- example_input: any;
-}
-
-interface EndpointInfo {
- parameters: T[];
- returns: T[];
-}
-interface ApiInfo {
- named_endpoints: {
- [key: string]: EndpointInfo;
- };
- unnamed_endpoints: {
- [key: string]: EndpointInfo;
- };
-}
-
-function get_type(
- type: { [key: string]: any },
- component: string,
- serializer: string,
- signature_type: "return" | "parameter"
-): string {
- switch (type.type) {
- case "string":
- return "string";
- case "boolean":
- return "boolean";
- case "number":
- return "number";
}
- if (
- serializer === "JSONSerializable" ||
- serializer === "StringSerializable"
- ) {
- return "any";
- } else if (serializer === "ListStringSerializable") {
- return "string[]";
- } else if (component === "Image") {
- return signature_type === "parameter" ? "Blob | File | Buffer" : "string";
- } else if (serializer === "FileSerializable") {
- if (type?.type === "array") {
- return signature_type === "parameter"
- ? "(Blob | File | Buffer)[]"
- : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
+ public async component_server(
+ component_id: number,
+ fn_name: string,
+ data: unknown[] | { binary: boolean; data: Record }
+ ): Promise {
+ if (!this.config) {
+ throw new Error(CONFIG_ERROR_MSG);
}
- return signature_type === "parameter"
- ? "Blob | File | Buffer"
- : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
- } else if (serializer === "GallerySerializable") {
- return signature_type === "parameter"
- ? "[(Blob | File | Buffer), (string | null)][]"
- : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`;
- }
-}
-function get_description(
- type: { type: any; description: string },
- serializer: string
-): string {
- if (serializer === "GallerySerializable") {
- return "array of [file, label] tuples";
- } else if (serializer === "ListStringSerializable") {
- return "array of strings";
- } else if (serializer === "FileSerializable") {
- return "array of files or single file";
- }
- return type.description;
-}
-
-function transform_api_info(
- api_info: ApiInfo,
- config: Config,
- api_map: Record
-): ApiInfo {
- const new_data = {
- named_endpoints: {},
- unnamed_endpoints: {}
- };
- for (const key in api_info) {
- const cat = api_info[key];
+ const headers: {
+ Authorization?: string;
+ "Content-Type"?: "application/json";
+ } = {};
- for (const endpoint in cat) {
- const dep_index = config.dependencies[endpoint]
- ? endpoint
- : api_map[endpoint.replace("/", "")];
+ const { hf_token } = this.options;
+ const { session_hash } = this;
- const info = cat[endpoint];
- new_data[key][endpoint] = {};
- new_data[key][endpoint].parameters = {};
- new_data[key][endpoint].returns = {};
- new_data[key][endpoint].type = config.dependencies[dep_index].types;
- new_data[key][endpoint].parameters = info.parameters.map(
- ({ label, component, type, serializer }) => ({
- label,
- component,
- type: get_type(type, component, serializer, "parameter"),
- description: get_description(type, serializer)
- })
- );
+ if (hf_token) {
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
+ }
- new_data[key][endpoint].returns = info.returns.map(
- ({ label, component, type, serializer }) => ({
- label,
- component,
- type: get_type(type, component, serializer, "return"),
- description: get_description(type, serializer)
- })
- );
+ let root_url: string;
+ let component = this.config.components.find(
+ (comp) => comp.id === component_id
+ );
+ if (component?.props?.root_url) {
+ root_url = component.props.root_url;
+ } else {
+ root_url = this.config.root;
}
- }
- return new_data;
-}
+ let body: FormData | string;
-async function get_jwt(
- space: string,
- token: `hf_${string}`
-): Promise {
- try {
- const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, {
- headers: {
- Authorization: `Bearer ${token}`
+ if ("binary" in data) {
+ body = new FormData();
+ for (const key in data.data) {
+ if (key === "binary") continue;
+ body.append(key, data.data[key]);
}
- });
-
- const jwt = (await r.json()).token;
-
- return jwt || false;
- } catch (e) {
- console.error(e);
- return false;
- }
-}
-
-function update_object(object, newValue, stack): void {
- while (stack.length > 1) {
- object = object[stack.shift()];
- }
-
- object[stack.shift()] = newValue;
-}
-
-export async function walk_and_store_blobs(
- param,
- type = undefined,
- path = [],
- root = false,
- api_info = undefined
-): Promise<
- {
- path: string[];
- type: string;
- blob: Blob | false;
- }[]
-> {
- if (Array.isArray(param)) {
- let blob_refs = [];
+ body.set("component_id", component_id.toString());
+ body.set("fn_name", fn_name);
+ body.set("session_hash", session_hash);
+ } else {
+ body = JSON.stringify({
+ data: data,
+ component_id,
+ fn_name,
+ session_hash
+ });
- await Promise.all(
- param.map(async (v, i) => {
- let new_path = path.slice();
- new_path.push(i);
+ headers["Content-Type"] = "application/json";
+ }
- const array_refs = await walk_and_store_blobs(
- param[i],
- root ? api_info?.parameters[i]?.component || undefined : type,
- new_path,
- false,
- api_info
- );
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
- blob_refs = blob_refs.concat(array_refs);
- })
- );
+ try {
+ const response = await this.fetch(`${root_url}/component_server/`, {
+ method: "POST",
+ body: body,
+ headers,
+ credentials: "include"
+ });
- return blob_refs;
- } else if (globalThis.Buffer && param instanceof globalThis.Buffer) {
- const is_image = type === "Image";
- return [
- {
- path: path,
- blob: is_image ? false : new NodeBlob([param]),
- type
- }
- ];
- } else if (typeof param === "object") {
- let blob_refs = [];
- for (let key in param) {
- if (param.hasOwnProperty(key)) {
- let new_path = path.slice();
- new_path.push(key);
- blob_refs = blob_refs.concat(
- await walk_and_store_blobs(
- param[key],
- undefined,
- new_path,
- false,
- api_info
- )
+ if (!response.ok) {
+ throw new Error(
+ "Could not connect to component server: " + response.statusText
);
}
- }
- return blob_refs;
- }
- return [];
-}
-
-function image_to_data_uri(blob: Blob): Promise {
- return new Promise((resolve, _) => {
- const reader = new FileReader();
- reader.onloadend = () => resolve(reader.result);
- reader.readAsDataURL(blob);
- });
-}
-
-function skip_queue(id: number, config: Config): boolean {
- return (
- !(config?.dependencies?.[id]?.queue === null
- ? config.enable_queue
- : config?.dependencies?.[id]?.queue) || false
- );
-}
-
-async function resolve_config(
- fetch_implementation: typeof fetch,
- endpoint?: string,
- token?: `hf_${string}`
-): Promise {
- const headers: { Authorization?: string } = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
- if (
- typeof window !== "undefined" &&
- window.gradio_config &&
- location.origin !== "http://localhost:9876" &&
- !window.gradio_config.dev_mode
- ) {
- const path = window.gradio_config.root;
- const config = window.gradio_config;
- config.root = resolve_root(endpoint, config.root, false);
- return { ...config, path: path };
- } else if (endpoint) {
- let response = await fetch_implementation(`${endpoint}/config`, {
- headers
- });
- if (response.status === 200) {
- const config = await response.json();
- config.path = config.path ?? "";
- config.root = endpoint;
- return config;
+ const output = await response.json();
+ return output;
+ } catch (e) {
+ console.warn(e);
}
- throw new Error("Could not get config.");
}
- throw new Error("No config or app endpoint found");
-}
-
-async function check_space_status(
- id: string,
- type: "subdomain" | "space_name",
- status_callback: SpaceStatusCallback
-): Promise {
- let endpoint =
- type === "subdomain"
- ? `https://huggingface.co/api/spaces/by-subdomain/${id}`
- : `https://huggingface.co/api/spaces/${id}`;
- let response;
- let _status;
- try {
- response = await fetch(endpoint);
- _status = response.status;
- if (_status !== 200) {
- throw new Error();
- }
- response = await response.json();
- } catch (e) {
- status_callback({
- status: "error",
- load_status: "error",
- message: "Could not get space status",
- detail: "NOT_FOUND"
- });
- return;
+ public set_cookies(raw_cookies: string): void {
+ this.cookies = parse_and_set_cookies(raw_cookies).join("; ");
}
- if (!response || _status !== 200) return;
- const {
- runtime: { stage },
- id: space_name
- } = response;
-
- switch (stage) {
- case "STOPPED":
- case "SLEEPING":
- status_callback({
- status: "sleeping",
- load_status: "pending",
- message: "Space is asleep. Waking it up...",
- detail: stage
- });
-
- setTimeout(() => {
- check_space_status(id, type, status_callback);
- }, 1000); // poll for status
- break;
- case "PAUSED":
- status_callback({
- status: "paused",
- load_status: "error",
- message:
- "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
- detail: stage,
- discussions_enabled: await discussions_enabled(space_name)
- });
- break;
- case "RUNNING":
- case "RUNNING_BUILDING":
- status_callback({
- status: "running",
- load_status: "complete",
- message: "",
- detail: stage
- });
- // load_config(source);
- // launch
- break;
- case "BUILDING":
- status_callback({
- status: "building",
- load_status: "pending",
- message: "Space is building...",
- detail: stage
- });
-
- setTimeout(() => {
- check_space_status(id, type, status_callback);
- }, 1000);
- break;
- default:
- status_callback({
- status: "space_error",
- load_status: "error",
- message: "This space is experiencing an issue.",
- detail: stage,
- discussions_enabled: await discussions_enabled(space_name)
- });
- break;
+ private prepare_return_obj(): client_return {
+ return {
+ config: this.config,
+ predict: this.predict,
+ submit: this.submit,
+ view_api: this.view_api,
+ component_server: this.component_server
+ };
}
}
-function handle_message(
- data: any,
- last_status: Status["stage"]
-): {
- type: "hash" | "data" | "update" | "complete" | "generating" | "log" | "none";
- data?: any;
- status?: Status;
-} {
- const queue = true;
- switch (data.msg) {
- case "send_data":
- return { type: "data" };
- case "send_hash":
- return { type: "hash" };
- case "queue_full":
- return {
- type: "update",
- status: {
- queue,
- message: QUEUE_FULL_MSG,
- stage: "error",
- code: data.code,
- success: data.success
- }
- };
- case "heartbeat":
- return {
- type: "heartbeat"
- };
- case "unexpected_error":
- return {
- type: "unexpected_error",
- status: {
- queue,
- message: data.message,
- stage: "error",
- success: false
- }
- };
- case "estimation":
- return {
- type: "update",
- status: {
- queue,
- stage: last_status || "pending",
- code: data.code,
- size: data.queue_size,
- position: data.rank,
- eta: data.rank_eta,
- success: data.success
- }
- };
- case "progress":
- return {
- type: "update",
- status: {
- queue,
- stage: "pending",
- code: data.code,
- progress_data: data.progress_data,
- success: data.success
- }
- };
- case "log":
- return { type: "log", data: data };
- case "process_generating":
- return {
- type: "generating",
- status: {
- queue,
- message: !data.success ? data.output.error : null,
- stage: data.success ? "generating" : "error",
- code: data.code,
- progress_data: data.progress_data,
- eta: data.average_duration
- },
- data: data.success ? data.output : null
- };
- case "process_completed":
- if ("error" in data.output) {
- return {
- type: "update",
- status: {
- queue,
- message: data.output.error as string,
- stage: "error",
- code: data.code,
- success: data.success
- }
- };
- }
- return {
- type: "complete",
- status: {
- queue,
- message: !data.success ? data.output.error : undefined,
- stage: data.success ? "complete" : "error",
- code: data.code,
- progress_data: data.progress_data
- },
- data: data.success ? data.output : null
- };
-
- case "process_starts":
- return {
- type: "update",
- status: {
- queue,
- stage: "pending",
- code: data.code,
- size: data.rank,
- position: 0,
- success: data.success,
- eta: data.eta
- }
- };
+/**
+ * @deprecated This method will be removed in v1.0. Use `Client.connect()` instead.
+ * Creates a client instance for interacting with Gradio apps.
+ *
+ * @param {string} app_reference - The reference or URL to a Gradio space or app.
+ * @param {ClientOptions} options - Configuration options for the client.
+ * @returns {Promise} A promise that resolves to a `Client` instance.
+ */
+export async function client(
+ app_reference: string,
+ options: ClientOptions = {
+ events: ["data"]
}
+): Promise {
+ return await Client.connect(app_reference, options);
+}
- return { type: "none", status: { stage: "error", queue } };
+/**
+ * @deprecated This method will be removed in v1.0. Use `Client.duplicate()` instead.
+ * Creates a duplicate of a space and returns a client instance for the duplicated space.
+ *
+ * @param {string} app_reference - The reference or URL to a Gradio space or app to duplicate.
+ * @param {DuplicateOptions} options - Configuration options for the client.
+ * @returns {Promise} A promise that resolves to a `Client` instance.
+ */
+export async function duplicate_space(
+ app_reference: string,
+ options: DuplicateOptions
+): Promise {
+ return await Client.duplicate(app_reference, options);
}
+
+export type ClientInstance = Client;
diff --git a/node_modules/@gradio/client/src/constants.ts b/node_modules/@gradio/client/src/constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..488ae760b110a6e176261cb32fd22339f9a3a5b0
--- /dev/null
+++ b/node_modules/@gradio/client/src/constants.ts
@@ -0,0 +1,36 @@
+// endpoints
+export const HOST_URL = "host";
+export const API_URL = "api/predict/";
+export const SSE_URL_V0 = "queue/join";
+export const SSE_DATA_URL_V0 = "queue/data";
+export const SSE_URL = "queue/data";
+export const SSE_DATA_URL = "queue/join";
+export const UPLOAD_URL = "upload";
+export const LOGIN_URL = "login";
+export const CONFIG_URL = "config";
+export const API_INFO_URL = "info";
+export const RUNTIME_URL = "runtime";
+export const SLEEPTIME_URL = "sleeptime";
+export const RAW_API_INFO_URL = "info?serialize=False";
+export const SPACE_FETCHER_URL =
+ "https://gradio-space-api-fetcher-v2.hf.space/api";
+export const RESET_URL = "reset";
+export const SPACE_URL = "https://hf.space/{}";
+
+// messages
+export const QUEUE_FULL_MSG =
+ "This application is currently busy. Please try again. ";
+export const BROKEN_CONNECTION_MSG = "Connection errored out. ";
+export const CONFIG_ERROR_MSG = "Could not resolve app config. ";
+export const SPACE_STATUS_ERROR_MSG = "Could not get space status. ";
+export const API_INFO_ERROR_MSG = "Could not get API info. ";
+export const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. ";
+export const INVALID_URL_MSG = "Invalid URL. A full URL path is required.";
+export const UNAUTHORIZED_MSG = "Not authorized to access this space. ";
+export const INVALID_CREDENTIALS_MSG = "Invalid credentials. Could not login. ";
+export const MISSING_CREDENTIALS_MSG =
+ "Login credentials are required to access this space.";
+export const NODEJS_FS_ERROR_MSG =
+ "File system access is only available in Node.js environments";
+export const ROOT_URL_ERROR_MSG = "Root URL not found in client config";
+export const FILE_PROCESSING_ERROR_MSG = "Error uploading file";
diff --git a/node_modules/@gradio/client/src/globals.d.ts b/node_modules/@gradio/client/src/globals.d.ts
index 64966293360c00b9b6c18a347259650b92c93b91..8125a0bf370f45a1ea2041fcb51f4d726a4eb350 100644
--- a/node_modules/@gradio/client/src/globals.d.ts
+++ b/node_modules/@gradio/client/src/globals.d.ts
@@ -1,3 +1,5 @@
+import { Config } from "./types";
+
declare global {
interface Window {
__gradio_mode__: "app" | "website";
@@ -6,24 +8,3 @@ declare global {
__gradio_space__: string | null;
}
}
-
-export interface Config {
- auth_required: boolean | undefined;
- auth_message: string;
- components: any[];
- css: string | null;
- dependencies: any[];
- dev_mode: boolean;
- enable_queue: boolean;
- layout: any;
- mode: "blocks" | "interface";
- root: string;
- theme: string;
- title: string;
- version: string;
- space_id: string | null;
- is_colab: boolean;
- show_api: boolean;
- stylesheets: string[];
- path: string;
-}
diff --git a/node_modules/@gradio/client/src/helpers/api_info.ts b/node_modules/@gradio/client/src/helpers/api_info.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0c4efcc4fa9df0c89a31f541a5442552c4e8c3d4
--- /dev/null
+++ b/node_modules/@gradio/client/src/helpers/api_info.ts
@@ -0,0 +1,430 @@
+import type { Status } from "../types";
+import {
+ HOST_URL,
+ INVALID_URL_MSG,
+ QUEUE_FULL_MSG,
+ SPACE_METADATA_ERROR_MSG
+} from "../constants";
+import type { ApiData, ApiInfo, Config, JsApiData } from "../types";
+import { determine_protocol } from "./init_helpers";
+
+export const RE_SPACE_NAME = /^[a-zA-Z0-9_\-\.]+\/[a-zA-Z0-9_\-\.]+$/;
+export const RE_SPACE_DOMAIN = /.*hf\.space\/{0,1}$/;
+
+export async function process_endpoint(
+ app_reference: string,
+ hf_token?: `hf_${string}`
+): Promise<{
+ space_id: string | false;
+ host: string;
+ ws_protocol: "ws" | "wss";
+ http_protocol: "http:" | "https:";
+}> {
+ const headers: { Authorization?: string } = {};
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+
+ const _app_reference = app_reference.trim().replace(/\/$/, "");
+
+ if (RE_SPACE_NAME.test(_app_reference)) {
+ // app_reference is a HF space name
+ try {
+ const res = await fetch(
+ `https://huggingface.co/api/spaces/${_app_reference}/${HOST_URL}`,
+ { headers }
+ );
+
+ const _host = (await res.json()).host;
+
+ return {
+ space_id: app_reference,
+ ...determine_protocol(_host)
+ };
+ } catch (e) {
+ throw new Error(SPACE_METADATA_ERROR_MSG);
+ }
+ }
+
+ if (RE_SPACE_DOMAIN.test(_app_reference)) {
+ // app_reference is a direct HF space domain
+ const { ws_protocol, http_protocol, host } =
+ determine_protocol(_app_reference);
+
+ return {
+ space_id: host.replace(".hf.space", ""),
+ ws_protocol,
+ http_protocol,
+ host
+ };
+ }
+
+ return {
+ space_id: false,
+ ...determine_protocol(_app_reference)
+ };
+}
+
+export const join_urls = (...urls: string[]): string => {
+ try {
+ return urls.reduce((base_url: string, part: string) => {
+ base_url = base_url.replace(/\/+$/, "");
+ part = part.replace(/^\/+/, "");
+ return new URL(part, base_url + "/").toString();
+ });
+ } catch (e) {
+ throw new Error(INVALID_URL_MSG);
+ }
+};
+
+export function transform_api_info(
+ api_info: ApiInfo,
+ config: Config,
+ api_map: Record
+): ApiInfo {
+ const transformed_info: ApiInfo = {
+ named_endpoints: {},
+ unnamed_endpoints: {}
+ };
+
+ Object.keys(api_info).forEach((category) => {
+ if (category === "named_endpoints" || category === "unnamed_endpoints") {
+ transformed_info[category] = {};
+
+ Object.entries(api_info[category]).forEach(
+ ([endpoint, { parameters, returns }]) => {
+ const dependencyIndex =
+ config.dependencies.find(
+ (dep) =>
+ dep.api_name === endpoint ||
+ dep.api_name === endpoint.replace("/", "")
+ )?.id ||
+ api_map[endpoint.replace("/", "")] ||
+ -1;
+
+ const dependencyTypes =
+ dependencyIndex !== -1
+ ? config.dependencies.find((dep) => dep.id == dependencyIndex)
+ ?.types
+ : { continuous: false, generator: false, cancel: false };
+
+ if (
+ dependencyIndex !== -1 &&
+ config.dependencies.find((dep) => dep.id == dependencyIndex)?.inputs
+ ?.length !== parameters.length
+ ) {
+ const components = config.dependencies
+ .find((dep) => dep.id == dependencyIndex)!
+ .inputs.map(
+ (input) => config.components.find((c) => c.id === input)?.type
+ );
+
+ try {
+ components.forEach((comp, idx) => {
+ if (comp === "state") {
+ const new_param = {
+ component: "state",
+ example: null,
+ parameter_default: null,
+ parameter_has_default: true,
+ parameter_name: null,
+ hidden: true
+ };
+
+ // @ts-ignore
+ parameters.splice(idx, 0, new_param);
+ }
+ });
+ } catch (e) {
+ console.error(e);
+ }
+ }
+
+ const transform_type = (
+ data: ApiData,
+ component: string,
+ serializer: string,
+ signature_type: "return" | "parameter"
+ ): JsApiData => ({
+ ...data,
+ description: get_description(data?.type, serializer),
+ type:
+ get_type(data?.type, component, serializer, signature_type) || ""
+ });
+
+ transformed_info[category][endpoint] = {
+ parameters: parameters.map((p: ApiData) =>
+ transform_type(p, p?.component, p?.serializer, "parameter")
+ ),
+ returns: returns.map((r: ApiData) =>
+ transform_type(r, r?.component, r?.serializer, "return")
+ ),
+ type: dependencyTypes
+ };
+ }
+ );
+ }
+ });
+
+ return transformed_info;
+}
+
+export function get_type(
+ type: { type: any; description: string },
+ component: string,
+ serializer: string,
+ signature_type: "return" | "parameter"
+): string | undefined {
+ switch (type?.type) {
+ case "string":
+ return "string";
+ case "boolean":
+ return "boolean";
+ case "number":
+ return "number";
+ }
+
+ if (
+ serializer === "JSONSerializable" ||
+ serializer === "StringSerializable"
+ ) {
+ return "any";
+ } else if (serializer === "ListStringSerializable") {
+ return "string[]";
+ } else if (component === "Image") {
+ return signature_type === "parameter" ? "Blob | File | Buffer" : "string";
+ } else if (serializer === "FileSerializable") {
+ if (type?.type === "array") {
+ return signature_type === "parameter"
+ ? "(Blob | File | Buffer)[]"
+ : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
+ }
+ return signature_type === "parameter"
+ ? "Blob | File | Buffer"
+ : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
+ } else if (serializer === "GallerySerializable") {
+ return signature_type === "parameter"
+ ? "[(Blob | File | Buffer), (string | null)][]"
+ : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`;
+ }
+}
+
+export function get_description(
+ type: { type: any; description: string },
+ serializer: string
+): string {
+ if (serializer === "GallerySerializable") {
+ return "array of [file, label] tuples";
+ } else if (serializer === "ListStringSerializable") {
+ return "array of strings";
+ } else if (serializer === "FileSerializable") {
+ return "array of files or single file";
+ }
+ return type?.description;
+}
+
+/* eslint-disable complexity */
+export function handle_message(
+ data: any,
+ last_status: Status["stage"]
+): {
+ type:
+ | "hash"
+ | "data"
+ | "update"
+ | "complete"
+ | "generating"
+ | "log"
+ | "none"
+ | "heartbeat"
+ | "unexpected_error";
+ data?: any;
+ status?: Status;
+} {
+ const queue = true;
+ switch (data.msg) {
+ case "send_data":
+ return { type: "data" };
+ case "send_hash":
+ return { type: "hash" };
+ case "queue_full":
+ return {
+ type: "update",
+ status: {
+ queue,
+ message: QUEUE_FULL_MSG,
+ stage: "error",
+ code: data.code,
+ success: data.success
+ }
+ };
+ case "heartbeat":
+ return {
+ type: "heartbeat"
+ };
+ case "unexpected_error":
+ return {
+ type: "unexpected_error",
+ status: {
+ queue,
+ message: data.message,
+ stage: "error",
+ success: false
+ }
+ };
+ case "estimation":
+ return {
+ type: "update",
+ status: {
+ queue,
+ stage: last_status || "pending",
+ code: data.code,
+ size: data.queue_size,
+ position: data.rank,
+ eta: data.rank_eta,
+ success: data.success
+ }
+ };
+ case "progress":
+ return {
+ type: "update",
+ status: {
+ queue,
+ stage: "pending",
+ code: data.code,
+ progress_data: data.progress_data,
+ success: data.success
+ }
+ };
+ case "log":
+ return { type: "log", data: data };
+ case "process_generating":
+ return {
+ type: "generating",
+ status: {
+ queue,
+ message: !data.success ? data.output.error : null,
+ stage: data.success ? "generating" : "error",
+ code: data.code,
+ progress_data: data.progress_data,
+ eta: data.average_duration
+ },
+ data: data.success ? data.output : null
+ };
+ case "process_completed":
+ if ("error" in data.output) {
+ return {
+ type: "update",
+ status: {
+ queue,
+ message: data.output.error as string,
+ stage: "error",
+ code: data.code,
+ success: data.success
+ }
+ };
+ }
+ return {
+ type: "complete",
+ status: {
+ queue,
+ message: !data.success ? data.output.error : undefined,
+ stage: data.success ? "complete" : "error",
+ code: data.code,
+ progress_data: data.progress_data,
+ changed_state_ids: data.success
+ ? data.output.changed_state_ids
+ : undefined
+ },
+ data: data.success ? data.output : null
+ };
+
+ case "process_starts":
+ return {
+ type: "update",
+ status: {
+ queue,
+ stage: "pending",
+ code: data.code,
+ size: data.rank,
+ position: 0,
+ success: data.success,
+ eta: data.eta
+ }
+ };
+ }
+
+ return { type: "none", status: { stage: "error", queue } };
+}
+/* eslint-enable complexity */
+
+/**
+ * Maps the provided `data` to the parameters defined by the `/info` endpoint response.
+ * This allows us to support both positional and keyword arguments passed to the client
+ * and ensures that all parameters are either directly provided or have default values assigned.
+ *
+ * @param {unknown[] | Record} data - The input data for the function,
+ * which can be either an array of values for positional arguments or an object
+ * with key-value pairs for keyword arguments.
+ * @param {JsApiData[]} parameters - Array of parameter descriptions retrieved from the
+ * `/info` endpoint.
+ *
+ * @returns {unknown[]} - Returns an array of resolved data where each element corresponds
+ * to the expected parameter from the API. The `parameter_default` value is used where
+ * a value is not provided for a parameter, and optional parameters without defaults are
+ * set to `undefined`.
+ *
+ * @throws {Error} - Throws an error:
+ * - If more arguments are provided than are defined in the parameters.
+ * * - If no parameter value is provided for a required parameter and no default value is defined.
+ * - If an argument is provided that does not match any defined parameter.
+ */
+
+export const map_data_to_params = (
+ data: unknown[] | Record,
+ api_info: ApiInfo
+): unknown[] => {
+ const parameters = Object.values(api_info.named_endpoints).flatMap(
+ (values) => values.parameters
+ );
+
+ if (Array.isArray(data)) {
+ if (data.length > parameters.length) {
+ console.warn("Too many arguments provided for the endpoint.");
+ }
+ return data;
+ }
+
+ const resolved_data: unknown[] = [];
+ const provided_keys = Object.keys(data);
+
+ parameters.forEach((param, index) => {
+ if (data.hasOwnProperty(param.parameter_name)) {
+ resolved_data[index] = data[param.parameter_name];
+ } else if (param.parameter_has_default) {
+ resolved_data[index] = param.parameter_default;
+ } else {
+ throw new Error(
+ `No value provided for required parameter: ${param.parameter_name}`
+ );
+ }
+ });
+
+ provided_keys.forEach((key) => {
+ if (!parameters.some((param) => param.parameter_name === key)) {
+ throw new Error(
+ `Parameter \`${key}\` is not a valid keyword argument. Please refer to the API for usage.`
+ );
+ }
+ });
+
+ resolved_data.forEach((value, idx) => {
+ if (value === undefined && !parameters[idx].parameter_has_default) {
+ throw new Error(
+ `No value provided for required parameter: ${parameters[idx].parameter_name}`
+ );
+ }
+ });
+
+ return resolved_data;
+};
diff --git a/node_modules/@gradio/client/src/helpers/data.ts b/node_modules/@gradio/client/src/helpers/data.ts
new file mode 100644
index 0000000000000000000000000000000000000000..03bcb4cf52496f3cf03ecfb827087960f0d8527b
--- /dev/null
+++ b/node_modules/@gradio/client/src/helpers/data.ts
@@ -0,0 +1,234 @@
+import {
+ type ApiData,
+ type BlobRef,
+ type Config,
+ type EndpointInfo,
+ type JsApiData,
+ type DataType,
+ Command,
+ type Dependency,
+ type ComponentMeta
+} from "../types";
+import { FileData } from "../upload";
+
+const is_node =
+ typeof process !== "undefined" && process.versions && process.versions.node;
+
+export function update_object(
+ object: { [x: string]: any },
+ newValue: any,
+ stack: (string | number)[]
+): void {
+ while (stack.length > 1) {
+ const key = stack.shift();
+ if (typeof key === "string" || typeof key === "number") {
+ object = object[key];
+ } else {
+ throw new Error("Invalid key type");
+ }
+ }
+
+ const key = stack.shift();
+ if (typeof key === "string" || typeof key === "number") {
+ object[key] = newValue;
+ } else {
+ throw new Error("Invalid key type");
+ }
+}
+
+export async function walk_and_store_blobs(
+ data: DataType,
+ type: string | undefined = undefined,
+ path: string[] = [],
+ root = false,
+ endpoint_info: EndpointInfo | undefined = undefined
+): Promise {
+ if (Array.isArray(data)) {
+ let blob_refs: BlobRef[] = [];
+
+ await Promise.all(
+ data.map(async (_, index) => {
+ let new_path = path.slice();
+ new_path.push(String(index));
+
+ const array_refs = await walk_and_store_blobs(
+ data[index],
+ root
+ ? endpoint_info?.parameters[index]?.component || undefined
+ : type,
+ new_path,
+ false,
+ endpoint_info
+ );
+
+ blob_refs = blob_refs.concat(array_refs);
+ })
+ );
+
+ return blob_refs;
+ } else if (
+ (globalThis.Buffer && data instanceof globalThis.Buffer) ||
+ data instanceof Blob
+ ) {
+ return [
+ {
+ path: path,
+ blob: new Blob([data]),
+ type
+ }
+ ];
+ } else if (typeof data === "object" && data !== null) {
+ let blob_refs: BlobRef[] = [];
+ for (const key of Object.keys(data) as (keyof typeof data)[]) {
+ const new_path = [...path, key];
+ const value = data[key];
+
+ blob_refs = blob_refs.concat(
+ await walk_and_store_blobs(
+ value,
+ undefined,
+ new_path,
+ false,
+ endpoint_info
+ )
+ );
+ }
+
+ return blob_refs;
+ }
+
+ return [];
+}
+
+export function skip_queue(id: number, config: Config): boolean {
+ let fn_queue = config?.dependencies?.find((dep) => dep.id == id)?.queue;
+ if (fn_queue != null) {
+ return !fn_queue;
+ }
+ return !config.enable_queue;
+}
+
+// todo: add jsdoc for this function
+
+export function post_message(
+ message: any,
+ origin: string
+): Promise {
+ return new Promise((res, _rej) => {
+ const channel = new MessageChannel();
+ channel.port1.onmessage = (({ data }) => {
+ channel.port1.close();
+ res(data);
+ }) as (ev: MessageEvent) => void;
+ window.parent.postMessage(message, origin, [channel.port2]);
+ });
+}
+
+export function handle_file(
+ file_or_url: File | string | Blob | Buffer
+): FileData | Blob | Command {
+ if (typeof file_or_url === "string") {
+ if (
+ file_or_url.startsWith("http://") ||
+ file_or_url.startsWith("https://")
+ ) {
+ return {
+ path: file_or_url,
+ url: file_or_url,
+ orig_name: file_or_url.split("/").pop() ?? "unknown",
+ meta: { _type: "gradio.FileData" }
+ };
+ }
+
+ if (is_node) {
+ // Handle local file paths
+ return new Command("upload_file", {
+ path: file_or_url,
+ name: file_or_url,
+ orig_path: file_or_url
+ });
+ }
+ } else if (typeof File !== "undefined" && file_or_url instanceof File) {
+ return {
+ path: file_or_url instanceof File ? file_or_url.name : "blob",
+ orig_name: file_or_url instanceof File ? file_or_url.name : "unknown",
+ // @ts-ignore
+ blob: file_or_url instanceof File ? file_or_url : new Blob([file_or_url]),
+ size:
+ file_or_url instanceof Blob
+ ? file_or_url.size
+ : Buffer.byteLength(file_or_url as Buffer),
+ mime_type:
+ file_or_url instanceof File
+ ? file_or_url.type
+ : "application/octet-stream", // Default MIME type for buffers
+ meta: { _type: "gradio.FileData" }
+ };
+ } else if (file_or_url instanceof Buffer) {
+ return new Blob([file_or_url]);
+ } else if (file_or_url instanceof Blob) {
+ return file_or_url;
+ }
+ throw new Error(
+ "Invalid input: must be a URL, File, Blob, or Buffer object."
+ );
+}
+
+/**
+ * Handles the payload by filtering out state inputs and returning an array of resolved payload values.
+ * We send null values for state inputs to the server, but we don't want to include them in the resolved payload.
+ *
+ * @param resolved_payload - The resolved payload values received from the client or the server
+ * @param dependency - The dependency object.
+ * @param components - The array of component metadata.
+ * @param with_null_state - Optional. Specifies whether to include null values for state inputs. Default is false.
+ * @returns An array of resolved payload values, filtered based on the dependency and component metadata.
+ */
+export function handle_payload(
+ resolved_payload: unknown[],
+ dependency: Dependency,
+ components: ComponentMeta[],
+ type: "input" | "output",
+ with_null_state = false
+): unknown[] {
+ if (type === "input" && !with_null_state) {
+ throw new Error("Invalid code path. Cannot skip state inputs for input.");
+ }
+ // data comes from the server with null state values so we skip
+ if (type === "output" && with_null_state) {
+ return resolved_payload;
+ }
+
+ let updated_payload: unknown[] = [];
+ let payload_index = 0;
+ for (let i = 0; i < dependency.inputs.length; i++) {
+ const input_id = dependency.inputs[i];
+ const component = components.find((c) => c.id === input_id);
+
+ if (component?.type === "state") {
+ // input + with_null_state needs us to fill state with null values
+ if (with_null_state) {
+ if (resolved_payload.length === dependency.inputs.length) {
+ const value = resolved_payload[payload_index];
+ updated_payload.push(value);
+ payload_index++;
+ } else {
+ updated_payload.push(null);
+ }
+ } else {
+ // this is output & !with_null_state, we skip state inputs
+ // the server payload always comes with null state values so we move along the payload index
+ payload_index++;
+ continue;
+ }
+ // input & !with_null_state isn't a case we care about, server needs null
+ continue;
+ } else {
+ const value = resolved_payload[payload_index];
+ updated_payload.push(value);
+ payload_index++;
+ }
+ }
+
+ return updated_payload;
+}
diff --git a/node_modules/@gradio/client/src/helpers/init_helpers.ts b/node_modules/@gradio/client/src/helpers/init_helpers.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4945a5acaf3bdccdfabfadcfc461db10dd1c93f
--- /dev/null
+++ b/node_modules/@gradio/client/src/helpers/init_helpers.ts
@@ -0,0 +1,224 @@
+import type { Config } from "../types";
+import {
+ CONFIG_ERROR_MSG,
+ CONFIG_URL,
+ INVALID_CREDENTIALS_MSG,
+ LOGIN_URL,
+ MISSING_CREDENTIALS_MSG,
+ SPACE_METADATA_ERROR_MSG,
+ UNAUTHORIZED_MSG
+} from "../constants";
+import { Client } from "..";
+import { join_urls, process_endpoint } from "./api_info";
+
+/**
+ * This function is used to resolve the URL for making requests when the app has a root path.
+ * The root path could be a path suffix like "/app" which is appended to the end of the base URL. Or
+ * it could be a full URL like "https://abidlabs-test-client-replica--gqf2x.hf.space" which is used when hosting
+ * Gradio apps on Hugging Face Spaces.
+ * @param {string} base_url The base URL at which the Gradio server is hosted
+ * @param {string} root_path The root path, which could be a path suffix (e.g. mounted in FastAPI app) or a full URL (e.g. hosted on Hugging Face Spaces)
+ * @param {boolean} prioritize_base Whether to prioritize the base URL over the root path. This is used when both the base path and root paths are full URLs. For example, for fetching files the root path should be prioritized, but for making requests, the base URL should be prioritized.
+ * @returns {string} the resolved URL
+ */
+export function resolve_root(
+ base_url: string,
+ root_path: string,
+ prioritize_base: boolean
+): string {
+ if (root_path.startsWith("http://") || root_path.startsWith("https://")) {
+ return prioritize_base ? base_url : root_path;
+ }
+ return base_url + root_path;
+}
+
+export async function get_jwt(
+ space: string,
+ token: `hf_${string}`,
+ cookies?: string | null
+): Promise {
+ try {
+ const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ ...(cookies ? { Cookie: cookies } : {})
+ }
+ });
+
+ const jwt = (await r.json()).token;
+
+ return jwt || false;
+ } catch (e) {
+ return false;
+ }
+}
+
+export function map_names_to_ids(
+ fns: Config["dependencies"]
+): Record {
+ let apis: Record = {};
+
+ fns.forEach(({ api_name, id }) => {
+ if (api_name) apis[api_name] = id;
+ });
+ return apis;
+}
+
+export async function resolve_config(
+ this: Client,
+ endpoint: string
+): Promise {
+ const headers: Record = this.options.hf_token
+ ? { Authorization: `Bearer ${this.options.hf_token}` }
+ : {};
+
+ headers["Content-Type"] = "application/json";
+
+ if (
+ typeof window !== "undefined" &&
+ window.gradio_config &&
+ location.origin !== "http://localhost:9876" &&
+ !window.gradio_config.dev_mode
+ ) {
+ const path = window.gradio_config.root;
+ const config = window.gradio_config;
+ let config_root = resolve_root(endpoint, config.root, false);
+ config.root = config_root;
+ return { ...config, path } as Config;
+ } else if (endpoint) {
+ const config_url = join_urls(endpoint, CONFIG_URL);
+ const response = await this.fetch(config_url, {
+ headers,
+ credentials: "include"
+ });
+
+ if (response?.status === 401 && !this.options.auth) {
+ throw new Error(MISSING_CREDENTIALS_MSG);
+ } else if (response?.status === 401 && this.options.auth) {
+ throw new Error(INVALID_CREDENTIALS_MSG);
+ }
+ if (response?.status === 200) {
+ let config = await response.json();
+ config.path = config.path ?? "";
+ config.root = endpoint;
+ config.dependencies?.forEach((dep: any, i: number) => {
+ if (dep.id === undefined) {
+ dep.id = i;
+ }
+ });
+ return config;
+ } else if (response?.status === 401) {
+ throw new Error(UNAUTHORIZED_MSG);
+ }
+ throw new Error(CONFIG_ERROR_MSG);
+ }
+
+ throw new Error(CONFIG_ERROR_MSG);
+}
+
+export async function resolve_cookies(this: Client): Promise {
+ const { http_protocol, host } = await process_endpoint(
+ this.app_reference,
+ this.options.hf_token
+ );
+
+ try {
+ if (this.options.auth) {
+ const cookie_header = await get_cookie_header(
+ http_protocol,
+ host,
+ this.options.auth,
+ this.fetch,
+ this.options.hf_token
+ );
+
+ if (cookie_header) this.set_cookies(cookie_header);
+ }
+ } catch (e: unknown) {
+ throw Error((e as Error).message);
+ }
+}
+
+// separating this from client-bound resolve_cookies so that it can be used in duplicate
+export async function get_cookie_header(
+ http_protocol: string,
+ host: string,
+ auth: [string, string],
+ _fetch: typeof fetch,
+ hf_token?: `hf_${string}`
+): Promise {
+ const formData = new FormData();
+ formData.append("username", auth?.[0]);
+ formData.append("password", auth?.[1]);
+
+ let headers: { Authorization?: string } = {};
+
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+
+ const res = await _fetch(`${http_protocol}//${host}/${LOGIN_URL}`, {
+ headers,
+ method: "POST",
+ body: formData,
+ credentials: "include"
+ });
+
+ if (res.status === 200) {
+ return res.headers.get("set-cookie");
+ } else if (res.status === 401) {
+ throw new Error(INVALID_CREDENTIALS_MSG);
+ } else {
+ throw new Error(SPACE_METADATA_ERROR_MSG);
+ }
+}
+
+export function determine_protocol(endpoint: string): {
+ ws_protocol: "ws" | "wss";
+ http_protocol: "http:" | "https:";
+ host: string;
+} {
+ if (endpoint.startsWith("http")) {
+ const { protocol, host, pathname } = new URL(endpoint);
+
+ if (host.endsWith("hf.space")) {
+ return {
+ ws_protocol: "wss",
+ host: host,
+ http_protocol: protocol as "http:" | "https:"
+ };
+ }
+ return {
+ ws_protocol: protocol === "https:" ? "wss" : "ws",
+ http_protocol: protocol as "http:" | "https:",
+ host: host + (pathname !== "/" ? pathname : "")
+ };
+ } else if (endpoint.startsWith("file:")) {
+ // This case is only expected to be used for the Wasm mode (Gradio-lite),
+ // where users can create a local HTML file using it and open the page in a browser directly via the `file:` protocol.
+ return {
+ ws_protocol: "ws",
+ http_protocol: "http:",
+ host: "lite.local" // Special fake hostname only used for this case. This matches the hostname allowed in `is_self_host()` in `js/wasm/network/host.ts`.
+ };
+ }
+
+ // default to secure if no protocol is provided
+ return {
+ ws_protocol: "wss",
+ http_protocol: "https:",
+ host: endpoint
+ };
+}
+
+export const parse_and_set_cookies = (cookie_header: string): string[] => {
+ let cookies: string[] = [];
+ const parts = cookie_header.split(/,(?=\s*[^\s=;]+=[^\s=;]+)/);
+ parts.forEach((cookie) => {
+ const [cookie_name, cookie_value] = cookie.split(";")[0].split("=");
+ if (cookie_name && cookie_value) {
+ cookies.push(`${cookie_name.trim()}=${cookie_value.trim()}`);
+ }
+ });
+ return cookies;
+};
diff --git a/node_modules/@gradio/client/src/helpers/spaces.ts b/node_modules/@gradio/client/src/helpers/spaces.ts
new file mode 100644
index 0000000000000000000000000000000000000000..50f66281204ab0a004fae6613d0356d6007138c0
--- /dev/null
+++ b/node_modules/@gradio/client/src/helpers/spaces.ts
@@ -0,0 +1,198 @@
+import {
+ RUNTIME_URL,
+ SLEEPTIME_URL,
+ SPACE_STATUS_ERROR_MSG
+} from "../constants";
+import type { SpaceStatusCallback } from "../types";
+
+export async function check_space_status(
+ id: string,
+ type: "subdomain" | "space_name",
+ status_callback: SpaceStatusCallback
+): Promise {
+ let endpoint =
+ type === "subdomain"
+ ? `https://huggingface.co/api/spaces/by-subdomain/${id}`
+ : `https://huggingface.co/api/spaces/${id}`;
+ let response;
+ let _status;
+ try {
+ response = await fetch(endpoint);
+ _status = response.status;
+ if (_status !== 200) {
+ throw new Error();
+ }
+ response = await response.json();
+ } catch (e) {
+ status_callback({
+ status: "error",
+ load_status: "error",
+ message: SPACE_STATUS_ERROR_MSG,
+ detail: "NOT_FOUND"
+ });
+ return;
+ }
+
+ if (!response || _status !== 200) return;
+ const {
+ runtime: { stage },
+ id: space_name
+ } = response;
+
+ switch (stage) {
+ case "STOPPED":
+ case "SLEEPING":
+ status_callback({
+ status: "sleeping",
+ load_status: "pending",
+ message: "Space is asleep. Waking it up...",
+ detail: stage
+ });
+
+ setTimeout(() => {
+ check_space_status(id, type, status_callback);
+ }, 1000); // poll for status
+ break;
+ case "PAUSED":
+ status_callback({
+ status: "paused",
+ load_status: "error",
+ message:
+ "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
+ detail: stage,
+ discussions_enabled: await discussions_enabled(space_name)
+ });
+ break;
+ case "RUNNING":
+ case "RUNNING_BUILDING":
+ status_callback({
+ status: "running",
+ load_status: "complete",
+ message: "",
+ detail: stage
+ });
+ break;
+ case "BUILDING":
+ status_callback({
+ status: "building",
+ load_status: "pending",
+ message: "Space is building...",
+ detail: stage
+ });
+
+ setTimeout(() => {
+ check_space_status(id, type, status_callback);
+ }, 1000);
+ break;
+ default:
+ status_callback({
+ status: "space_error",
+ load_status: "error",
+ message: "This space is experiencing an issue.",
+ detail: stage,
+ discussions_enabled: await discussions_enabled(space_name)
+ });
+ break;
+ }
+}
+
+const RE_DISABLED_DISCUSSION =
+ /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
+export async function discussions_enabled(space_id: string): Promise {
+ try {
+ const r = await fetch(
+ `https://huggingface.co/api/spaces/${space_id}/discussions`,
+ {
+ method: "HEAD"
+ }
+ );
+
+ const error = r.headers.get("x-error-message");
+
+ if (!r.ok || (error && RE_DISABLED_DISCUSSION.test(error))) return false;
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+export async function get_space_hardware(
+ space_id: string,
+ hf_token?: `hf_${string}` | undefined
+): Promise<(typeof hardware_types)[number]> {
+ const headers: { Authorization?: string } = {};
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+
+ try {
+ const res = await fetch(
+ `https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`,
+ { headers }
+ );
+
+ if (res.status !== 200)
+ throw new Error("Space hardware could not be obtained.");
+
+ const { hardware } = await res.json();
+
+ return hardware.current;
+ } catch (e: any) {
+ throw new Error(e.message);
+ }
+}
+
+export async function set_space_timeout(
+ space_id: string,
+ timeout: number,
+ hf_token?: `hf_${string}`
+): Promise {
+ const headers: { Authorization?: string } = {};
+ if (hf_token) {
+ headers.Authorization = `Bearer ${hf_token}`;
+ }
+
+ const body: {
+ seconds?: number;
+ } = {
+ seconds: timeout
+ };
+
+ try {
+ const res = await fetch(
+ `https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`,
+ {
+ method: "POST",
+ headers: { "Content-Type": "application/json", ...headers },
+ body: JSON.stringify(body)
+ }
+ );
+
+ if (res.status !== 200) {
+ throw new Error(
+ "Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges."
+ );
+ }
+
+ const response = await res.json();
+ return response;
+ } catch (e: any) {
+ throw new Error(e.message);
+ }
+}
+
+export const hardware_types = [
+ "cpu-basic",
+ "cpu-upgrade",
+ "cpu-xl",
+ "t4-small",
+ "t4-medium",
+ "a10g-small",
+ "a10g-large",
+ "a10g-largex2",
+ "a10g-largex4",
+ "a100-large",
+ "zero-a10g",
+ "h100",
+ "h100x8"
+] as const;
diff --git a/node_modules/@gradio/client/src/index.ts b/node_modules/@gradio/client/src/index.ts
index 98e248e54cc5d72d681ff6dda03db016af70f25f..7717d94f887c3ef86b6b548757e1323ace2a6e21 100644
--- a/node_modules/@gradio/client/src/index.ts
+++ b/node_modules/@gradio/client/src/index.ts
@@ -1,15 +1,22 @@
-export {
- client,
- post_data,
- upload_files,
- duplicate,
- api_factory
-} from "./client.js";
-export type { SpaceStatus } from "./types.js";
-export {
- normalise_file,
- FileData,
- upload,
- get_fetchable_url_or_file,
- prepare_files
-} from "./upload.js";
+export { Client } from "./client";
+
+export { predict } from "./utils/predict";
+export { submit } from "./utils/submit";
+export { upload_files } from "./utils/upload_files";
+export { FileData, upload, prepare_files } from "./upload";
+export { handle_file } from "./helpers/data";
+
+export type {
+ SpaceStatus,
+ StatusMessage,
+ Status,
+ client_return,
+ UploadResponse,
+ RenderMessage,
+ LogMessage,
+ Payload
+} from "./types";
+
+// todo: remove in @gradio/client v1.0
+export { client } from "./client";
+export { duplicate_space as duplicate } from "./client";
diff --git a/node_modules/@gradio/client/src/test/api_info.test.ts b/node_modules/@gradio/client/src/test/api_info.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ad0a7538eaeefd85a816bc80a579a1017d0b3348
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/api_info.test.ts
@@ -0,0 +1,631 @@
+import {
+ INVALID_URL_MSG,
+ QUEUE_FULL_MSG,
+ SPACE_METADATA_ERROR_MSG
+} from "../constants";
+import { beforeAll, afterEach, afterAll, it, expect, describe } from "vitest";
+import {
+ handle_message,
+ get_description,
+ get_type,
+ process_endpoint,
+ join_urls,
+ map_data_to_params
+} from "../helpers/api_info";
+import { initialise_server } from "./server";
+import { transformed_api_info } from "./test_data";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("handle_message", () => {
+ it("should return type 'data' when msg is 'send_data'", () => {
+ const data = { msg: "send_data" };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({ type: "data" });
+ });
+
+ it("should return type 'hash' when msg is 'send_hash'", () => {
+ const data = { msg: "send_hash" };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({ type: "hash" });
+ });
+
+ it("should return type 'update' with queue full message when msg is 'queue_full'", () => {
+ const data = { msg: "queue_full", code: 500, success: false };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "update",
+ status: {
+ queue: true,
+ message: QUEUE_FULL_MSG,
+ stage: "error",
+ code: 500,
+ success: false
+ }
+ });
+ });
+
+ it("should return type 'heartbeat' when msg is 'heartbeat'", () => {
+ const data = { msg: "heartbeat" };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({ type: "heartbeat" });
+ });
+
+ it("should return type 'unexpected_error' with error message when msg is 'unexpected_error'", () => {
+ const data = { msg: "unexpected_error", message: "Something went wrong" };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "unexpected_error",
+ status: {
+ queue: true,
+ message: "Something went wrong",
+ stage: "error",
+ success: false
+ }
+ });
+ });
+
+ it("should return type 'update' with estimation status when msg is 'estimation'", () => {
+ const data = {
+ msg: "estimation",
+ code: 200,
+ queue_size: 10,
+ rank: 5,
+ rank_eta: 60,
+ success: true
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "update",
+ status: {
+ queue: true,
+ stage: "pending",
+ code: 200,
+ size: 10,
+ position: 5,
+ eta: 60,
+ success: true
+ }
+ });
+ });
+
+ it("should return type 'update' with progress status when msg is 'progress'", () => {
+ const data = {
+ msg: "progress",
+ code: 200,
+ progress_data: { current: 50, total: 100 },
+ success: true
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "update",
+ status: {
+ queue: true,
+ stage: "pending",
+ code: 200,
+ progress_data: { current: 50, total: 100 },
+ success: true
+ }
+ });
+ });
+
+ it("should return type 'log' with the provided data when msg is 'log'", () => {
+ const data = { msg: "log", log_data: "Some log message" };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "log",
+ data: { msg: "log", log_data: "Some log message" }
+ });
+ });
+
+ it("should return type 'generating' with generating status when msg is 'process_generating' and success is true", () => {
+ const data = {
+ msg: "process_generating",
+ success: true,
+ code: 200,
+ progress_data: { current: 50, total: 100 },
+ average_duration: 120,
+ output: { result: "Some result" }
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "generating",
+ status: {
+ queue: true,
+ message: null,
+ stage: "generating",
+ code: 200,
+ progress_data: { current: 50, total: 100 },
+ eta: 120
+ },
+ data: { result: "Some result" }
+ });
+ });
+
+ it("should return type 'update' with error status when msg is 'process_generating' and success is false", () => {
+ const data = {
+ msg: "process_generating",
+ success: false,
+ code: 500,
+ progress_data: { current: 50, total: 100 },
+ average_duration: 120,
+ output: { error: "Error" }
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+
+ expect(result).toEqual({
+ type: "generating",
+ data: null,
+ status: {
+ eta: 120,
+ queue: true,
+ message: "Error",
+ stage: "error",
+ code: 500,
+ progress_data: { current: 50, total: 100 }
+ }
+ });
+ });
+
+ it("should return type 'complete' with success status when msg is 'process_completed' and success is true", () => {
+ const data = {
+ msg: "process_completed",
+ success: true,
+ code: 200,
+ progress_data: { current: 100, total: 100 },
+ output: { result: "Some result" }
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "complete",
+ status: {
+ queue: true,
+ message: undefined,
+ stage: "complete",
+ code: 200,
+ progress_data: { current: 100, total: 100 }
+ },
+ data: { result: "Some result" }
+ });
+ });
+
+ it("should return type 'update' with error status when msg is 'process_completed' and success is false", () => {
+ const data = {
+ msg: "process_completed",
+ success: false,
+ code: 500,
+ progress_data: { current: 100, total: 100 },
+ output: { error: "Some error message" }
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "update",
+ status: {
+ queue: true,
+ message: "Some error message",
+ stage: "error",
+ code: 500,
+ success: false
+ }
+ });
+ });
+
+ it("should return type 'update' with pending status when msg is 'process_starts'", () => {
+ const data = {
+ msg: "process_starts",
+ code: 200,
+ rank: 5,
+ success: true,
+ eta: 60
+ };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "update",
+ status: {
+ queue: true,
+ stage: "pending",
+ code: 200,
+ size: 5,
+ position: 0,
+ success: true,
+ eta: 60
+ }
+ });
+ });
+
+ it("should return type 'none' with error status when msg is unknown", () => {
+ const data = { msg: "unknown" };
+ const last_status = "pending";
+ const result = handle_message(data, last_status);
+ expect(result).toEqual({
+ type: "none",
+ status: { stage: "error", queue: true }
+ });
+ });
+});
+
+describe("get_description", () => {
+ it("should return 'array of [file, label] tuples' when serializer is 'GallerySerializable'", () => {
+ const type = { type: "string", description: "param description" };
+ const serializer = "GallerySerializable";
+ const result = get_description(type, serializer);
+ expect(result).toEqual("array of [file, label] tuples");
+ });
+
+ it("should return 'array of strings' when serializer is 'ListStringSerializable'", () => {
+ const type = { type: "string", description: "param description" };
+ const serializer = "ListStringSerializable";
+ const result = get_description(type, serializer);
+ expect(result).toEqual("array of strings");
+ });
+
+ it("should return 'array of files or single file' when serializer is 'FileSerializable'", () => {
+ const type = { type: "string", description: "param description" };
+ const serializer = "FileSerializable";
+ const result = get_description(type, serializer);
+ expect(result).toEqual("array of files or single file");
+ });
+
+ it("should return the type's description when serializer is not 'GallerySerializable', 'ListStringSerializable', or 'FileSerializable'", () => {
+ const type = { type: "string", description: "param description" };
+ const serializer = "SomeOtherSerializer";
+ const result = get_description(type, serializer);
+ expect(result).toEqual(type.description);
+ });
+});
+
+describe("get_type", () => {
+ it("should return 'string' when type is 'string'", () => {
+ const type = { type: "string", description: "param description" };
+ const component = "Component";
+ const serializer = "Serializer";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("string");
+ });
+
+ it("should return 'boolean' when type is 'boolean'", () => {
+ const type = { type: "boolean", description: "param description" };
+ const component = "Component";
+ const serializer = "Serializer";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("boolean");
+ });
+
+ it("should return 'number' when type is 'number'", () => {
+ const type = { type: "number", description: "param description" };
+ const component = "Component";
+ const serializer = "Serializer";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("number");
+ });
+
+ it("should return 'any' when serializer is 'JSONSerializable'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "JSONSerializable";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("any");
+ });
+
+ it("should return 'any' when serializer is 'StringSerializable'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "StringSerializable";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("any");
+ });
+
+ it("should return 'string[]' when serializer is 'ListStringSerializable'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "ListStringSerializable";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("string[]");
+ });
+
+ it("should return 'Blob | File | Buffer' when component is 'Image' and signature_type is 'parameter'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Image";
+ const serializer = "Serializer";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("Blob | File | Buffer");
+ });
+
+ it("should return 'string' when component is 'Image' and signature_type is 'return'", () => {
+ const type = { type: "string", description: "param description" };
+ const component = "Image";
+ const serializer = "Serializer";
+ const signature_type = "return";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("string");
+ });
+
+ it("should return '(Blob | File | Buffer)[]' when serializer is 'FileSerializable' and type is an array and signature_type is 'parameter'", () => {
+ const type = { type: "array", description: "param description" };
+ const component = "Component";
+ const serializer = "FileSerializable";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("(Blob | File | Buffer)[]");
+ });
+
+ it("should return 'Blob | File | Buffer' when serializer is 'FileSerializable' and type is not an array and signature_type is 'return'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "FileSerializable";
+ const signature_type = "return";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual(
+ "{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}"
+ );
+ });
+
+ it("should return a FileData object when serializer is 'FileSerializable' and type is not an array and signature_type is 'return'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "FileSerializable";
+ const signature_type = "return";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual(
+ "{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}"
+ );
+ });
+
+ it("should return '[(Blob | File | Buffer), (string | null)][]' when serializer is 'GallerySerializable' and signature_type is 'parameter'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "GallerySerializable";
+ const signature_type = "parameter";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual("[(Blob | File | Buffer), (string | null)][]");
+ });
+
+ it("should return a FileData object when serializer is 'GallerySerializable' and signature_type is 'return'", () => {
+ const type = { type: "any", description: "param description" };
+ const component = "Component";
+ const serializer = "GallerySerializable";
+ const signature_type = "return";
+ const result = get_type(type, component, serializer, signature_type);
+ expect(result).toEqual(
+ "[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]"
+ );
+ });
+});
+
+describe("process_endpoint", () => {
+ it("should return space_id, host, ws_protocol, and http_protocol when app_reference is a valid space name", async () => {
+ const app_reference = "hmb/hello_world";
+ const host = "hmb-hello-world.hf.space";
+
+ const hf_token = "hf_token";
+ const expected = {
+ space_id: app_reference,
+ host,
+ ws_protocol: "wss",
+ http_protocol: "https:"
+ };
+
+ const result = await process_endpoint(app_reference, hf_token);
+ expect(result).toEqual(expected);
+ });
+
+ it("should throw an error when fetching space metadata fails", async () => {
+ const app_reference = "hmb/bye_world";
+ const hf_token = "hf_token";
+
+ try {
+ await process_endpoint(app_reference, hf_token);
+ } catch (error) {
+ expect(error.message).toEqual(SPACE_METADATA_ERROR_MSG);
+ }
+ });
+
+ it("should return the correct data when app_reference is a valid space domain", async () => {
+ const app_reference = "hmb/hello_world";
+ const host = "hmb-hello-world.hf.space";
+
+ const expected = {
+ space_id: app_reference,
+ host,
+ ws_protocol: "wss",
+ http_protocol: "https:"
+ };
+
+ const result = await process_endpoint("hmb/hello_world");
+ expect(result).toEqual(expected);
+ });
+
+ it("processes local server URLs correctly", async () => {
+ const local_url = "http://localhost:7860/gradio";
+ const response_local_url = await process_endpoint(local_url);
+ expect(response_local_url.space_id).toBe(false);
+ expect(response_local_url.host).toBe("localhost:7860/gradio");
+
+ const local_url_2 = "http://localhost:7860/gradio/";
+ const response_local_url_2 = await process_endpoint(local_url_2);
+ expect(response_local_url_2.space_id).toBe(false);
+ expect(response_local_url_2.host).toBe("localhost:7860/gradio");
+ });
+
+ it("handles hugging face space references", async () => {
+ const space_id = "hmb/hello_world";
+
+ const response = await process_endpoint(space_id);
+ expect(response.space_id).toBe(space_id);
+ expect(response.host).toContain("hf.space");
+ });
+
+ it("handles hugging face domain URLs", async () => {
+ const app_reference = "https://hmb-hello-world.hf.space/";
+ const response = await process_endpoint(app_reference);
+ expect(response.space_id).toBe("hmb-hello-world");
+ expect(response.host).toBe("hmb-hello-world.hf.space");
+ });
+});
+
+describe("join_urls", () => {
+ it("joins URLs correctly", () => {
+ expect(join_urls("http://localhost:7860", "/gradio")).toBe(
+ "http://localhost:7860/gradio"
+ );
+ expect(join_urls("http://localhost:7860/", "/gradio")).toBe(
+ "http://localhost:7860/gradio"
+ );
+ expect(join_urls("http://localhost:7860", "app/", "/gradio")).toBe(
+ "http://localhost:7860/app/gradio"
+ );
+ expect(join_urls("http://localhost:7860/", "/app/", "/gradio/")).toBe(
+ "http://localhost:7860/app/gradio/"
+ );
+
+ expect(join_urls("http://127.0.0.1:8000/app", "/config")).toBe(
+ "http://127.0.0.1:8000/app/config"
+ );
+
+ expect(join_urls("http://127.0.0.1:8000/app/gradio", "/config")).toBe(
+ "http://127.0.0.1:8000/app/gradio/config"
+ );
+ });
+ it("throws an error when the URLs are not valid", () => {
+ expect(() => join_urls("localhost:7860", "/gradio")).toThrowError(
+ INVALID_URL_MSG
+ );
+
+ expect(() => join_urls("localhost:7860", "/gradio", "app")).toThrowError(
+ INVALID_URL_MSG
+ );
+ });
+});
+
+describe("map_data_params", () => {
+ let test_data = transformed_api_info;
+
+ test_data.named_endpoints["/predict"].parameters = [
+ {
+ parameter_name: "param1",
+ parameter_has_default: false,
+ label: "",
+ component: "",
+ serializer: "",
+ python_type: {
+ type: "",
+ description: ""
+ },
+ type: {
+ type: "",
+ description: ""
+ }
+ },
+ {
+ parameter_name: "param2",
+ parameter_has_default: false,
+ label: "",
+ type: {
+ type: "",
+ description: ""
+ },
+ component: "",
+ serializer: "",
+ python_type: {
+ type: "",
+ description: ""
+ }
+ },
+ {
+ parameter_name: "param3",
+ parameter_has_default: true,
+ parameter_default: 3,
+ label: "",
+ type: {
+ type: "",
+ description: ""
+ },
+ component: "",
+ serializer: "",
+ python_type: {
+ type: "",
+ description: ""
+ }
+ }
+ ];
+
+ it("should return an array of data when data is an array", () => {
+ const data = [1, 2];
+
+ const result = map_data_to_params(data, transformed_api_info);
+ expect(result).toEqual(data);
+ });
+
+ it("should return the data when too many arguments are provided for the endpoint", () => {
+ const data = [1, 2, 3, 4];
+
+ const result = map_data_to_params(data, transformed_api_info);
+ expect(result).toEqual(data);
+ });
+
+ it("should return an array of resolved data when data is an object", () => {
+ const data = {
+ param1: 1,
+ param2: 2,
+ param3: 3
+ };
+
+ const result = map_data_to_params(data, transformed_api_info);
+ expect(result).toEqual([1, 2, 3]);
+ });
+
+ it("should use the default value when a keyword argument is not provided and has a default value", () => {
+ const data = {
+ param1: 1,
+ param2: 2
+ };
+
+ const result = map_data_to_params(data, transformed_api_info);
+ expect(result).toEqual([1, 2, 3]);
+ });
+
+ it("should throw an error when an invalid keyword argument is provided", () => {
+ const data = {
+ param1: 1,
+ param2: 2,
+ param3: 3,
+ param4: 4
+ };
+
+ expect(() => map_data_to_params(data, transformed_api_info)).toThrowError(
+ "Parameter `param4` is not a valid keyword argument. Please refer to the API for usage."
+ );
+ });
+
+ it("should throw an error when no value is provided for a required parameter", () => {
+ const data = {};
+
+ expect(() => map_data_to_params(data, transformed_api_info)).toThrowError(
+ "No value provided for required parameter: param1"
+ );
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/data.test.ts b/node_modules/@gradio/client/src/test/data.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3798c89679d95db601afdbb9791ffc1d2dbc440c
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/data.test.ts
@@ -0,0 +1,453 @@
+import { describe, it, expect, vi, afterEach } from "vitest";
+import {
+ update_object,
+ walk_and_store_blobs,
+ skip_queue,
+ post_message,
+ handle_file,
+ handle_payload
+} from "../helpers/data";
+import { config_response, endpoint_info } from "./test_data";
+import { BlobRef, Command } from "../types";
+import { FileData } from "../upload";
+
+const IS_NODE = process.env.TEST_MODE === "node";
+
+describe("walk_and_store_blobs", () => {
+ it("should convert a Buffer to a Blob", async () => {
+ const buffer = Buffer.from("test data");
+ const parts = await walk_and_store_blobs(buffer, "text");
+
+ expect(parts).toHaveLength(1);
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ });
+
+ it("should return a Blob when passed a Blob", async () => {
+ const blob = new Blob(["test data"]);
+ const parts = await walk_and_store_blobs(
+ blob,
+ undefined,
+ [],
+ true,
+ endpoint_info
+ );
+
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ });
+
+ it("should handle arrays", async () => {
+ const image = new Blob([]);
+ const parts = await walk_and_store_blobs([image]);
+
+ expect(parts).toHaveLength(1);
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ expect(parts[0].path).toEqual(["0"]);
+ });
+
+ it("should handle deep structures", async () => {
+ const image = new Blob([]);
+ const parts = await walk_and_store_blobs({ a: { b: { data: { image } } } });
+
+ expect(parts).toHaveLength(1);
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ expect(parts[0].path).toEqual(["a", "b", "data", "image"]);
+ });
+
+ it("should handle deep structures with arrays", async () => {
+ const image = new Blob([]);
+ const parts = await walk_and_store_blobs({
+ a: [
+ {
+ b: [
+ {
+ data: [
+ {
+ image
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ });
+
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ });
+
+ it("should handle deep structures with arrays (with equality check)", async () => {
+ const image = new Blob([]);
+
+ const obj = {
+ a: [
+ {
+ b: [
+ {
+ data: [[image], image, [image, [image]]]
+ }
+ ]
+ }
+ ]
+ };
+ const parts = await walk_and_store_blobs(obj);
+
+ async function map_path(obj: Record, parts: BlobRef[]) {
+ const { path, blob } = parts[parts.length - 1];
+ let ref = obj;
+ path.forEach((p) => (ref = ref[p]));
+
+ // since ref is a Blob and blob is a Blob, we deep equal check the two buffers instead
+ if (ref instanceof Blob && blob instanceof Blob) {
+ const refBuffer = Buffer.from(await ref.arrayBuffer());
+ const blobBuffer = Buffer.from(await blob.arrayBuffer());
+ return refBuffer.equals(blobBuffer);
+ }
+
+ return ref === blob;
+ }
+
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ expect(map_path(obj, parts)).toBeTruthy();
+ });
+
+ it("should handle buffer instances and return a BlobRef", async () => {
+ const buffer = Buffer.from("test");
+ const parts = await walk_and_store_blobs(buffer, undefined, ["blob"]);
+
+ expect(parts).toHaveLength(1);
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ expect(parts[0].path).toEqual(["blob"]);
+ });
+
+ it("should handle buffer instances with a path and return a BlobRef with the path", async () => {
+ const buffer = Buffer.from("test data");
+ const parts = await walk_and_store_blobs(buffer);
+
+ expect(parts).toHaveLength(1);
+ expect(parts[0].path).toEqual([]);
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ });
+
+ it("should convert an object with deep structures to BlobRefs", async () => {
+ const param = {
+ a: {
+ b: {
+ data: {
+ image: Buffer.from("test image")
+ }
+ }
+ }
+ };
+ const parts = await walk_and_store_blobs(param);
+
+ expect(parts).toHaveLength(1);
+ expect(parts[0].path).toEqual(["a", "b", "data", "image"]);
+ expect(parts[0].blob).toBeInstanceOf(Blob);
+ });
+});
+describe("update_object", () => {
+ it("should update the value of a nested property", () => {
+ const obj = {
+ a: {
+ b: {
+ c: "old value"
+ }
+ }
+ };
+
+ const stack = ["a", "b", "c"];
+ const new_val = "new value";
+
+ update_object(obj, new_val, stack);
+
+ expect(obj.a.b.c).toBe(new_val);
+ });
+
+ it("should throw an error for invalid key type", () => {
+ const obj = {
+ a: {
+ b: {
+ c: "value"
+ }
+ }
+ };
+
+ const stack = ["a", "b", true];
+ const newValue = "new value";
+
+ expect(() => {
+ // @ts-ignore
+ update_object(obj, newValue, stack);
+ }).toThrowError("Invalid key type");
+ });
+});
+
+describe("skip_queue", () => {
+ const id = 0;
+ const config = config_response;
+
+ it("should not skip queue when global and dependency queue is enabled", () => {
+ config.enable_queue = true;
+ config.dependencies.find((dep) => dep.id === id)!.queue = true;
+
+ const result = skip_queue(id, config_response);
+
+ expect(result).toBe(false);
+ });
+
+ it("should not skip queue when global queue is disabled and dependency queue is enabled", () => {
+ config.enable_queue = false;
+ config.dependencies.find((dep) => dep.id === id)!.queue = true;
+
+ const result = skip_queue(id, config_response);
+
+ expect(result).toBe(false);
+ });
+
+ it("should should skip queue when global queue and dependency queue is disabled", () => {
+ config.enable_queue = false;
+ config.dependencies.find((dep) => dep.id === id)!.queue = false;
+
+ const result = skip_queue(id, config_response);
+
+ expect(result).toBe(true);
+ });
+
+ it("should should skip queue when global queue is enabled and dependency queue is disabled", () => {
+ config.enable_queue = true;
+ config.dependencies.find((dep) => dep.id === id)!.queue = false;
+
+ const result = skip_queue(id, config_response);
+
+ expect(result).toBe(true);
+ });
+});
+
+describe("post_message", () => {
+ afterEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ it("should send a message to the parent window and resolve with received data", async () => {
+ const test_data = { key: "value" };
+ const test_origin = "https://huggingface.co";
+
+ const post_message_mock = vi.fn();
+
+ global.window = {
+ // @ts-ignore
+ parent: {
+ postMessage: post_message_mock
+ }
+ };
+
+ const message_channel_mock = {
+ port1: {
+ onmessage: (handler) => {
+ onmessage = handler;
+ },
+ close: vi.fn()
+ },
+ port2: {}
+ };
+
+ vi.stubGlobal("MessageChannel", function () {
+ this.port1 = message_channel_mock.port1;
+ this.port2 = message_channel_mock.port2;
+ return this;
+ });
+
+ const promise = post_message(test_data, test_origin);
+
+ if (message_channel_mock.port1.onmessage) {
+ message_channel_mock.port1.onmessage({ data: test_data });
+ }
+
+ await expect(promise).resolves.toEqual(test_data);
+ expect(post_message_mock).toHaveBeenCalledWith(test_data, test_origin, [
+ message_channel_mock.port2
+ ]);
+ });
+});
+
+describe("handle_file", () => {
+ it("should handle a Blob object and return the blob", () => {
+ const blob = new Blob(["test data"], { type: "image/png" });
+ const result = handle_file(blob) as FileData;
+
+ expect(result).toBe(blob);
+ });
+
+ it("should handle a Buffer object and return it as a blob", () => {
+ const buffer = Buffer.from("test data");
+ const result = handle_file(buffer) as FileData;
+ expect(result).toBeInstanceOf(Blob);
+ });
+ it("should handle a local file path and return a Command object", () => {
+ const file_path = "./owl.png";
+ const result = handle_file(file_path) as Command;
+ expect(result).toBeInstanceOf(Command);
+ expect(result).toEqual({
+ type: "command",
+ command: "upload_file",
+ meta: { path: "./owl.png", name: "./owl.png", orig_path: "./owl.png" },
+ fileData: undefined
+ });
+ });
+
+ it("should handle a File object and return it as FileData", () => {
+ if (IS_NODE) {
+ return;
+ }
+ const file = new File(["test image"], "test.png", { type: "image/png" });
+ const result = handle_file(file) as FileData;
+ expect(result.path).toBe("test.png");
+ expect(result.orig_name).toBe("test.png");
+ expect(result.blob).toBeInstanceOf(Blob);
+ expect(result.size).toBe(file.size);
+ expect(result.mime_type).toBe("image/png");
+ expect(result.meta).toEqual({ _type: "gradio.FileData" });
+ });
+
+ it("should throw an error for invalid input", () => {
+ const invalid_input = 123;
+
+ expect(() => {
+ // @ts-ignore
+ handle_file(invalid_input);
+ }).toThrowError(
+ "Invalid input: must be a URL, File, Blob, or Buffer object."
+ );
+ });
+});
+
+describe("handle_payload", () => {
+ it("should return an input payload with null in place of `state` when with_null_state is true", () => {
+ const resolved_payload = [2];
+ const dependency = {
+ inputs: [1, 2]
+ };
+ const components = [
+ { id: 1, type: "number" },
+ { id: 2, type: "state" }
+ ];
+ const with_null_state = true;
+ const result = handle_payload(
+ resolved_payload,
+ // @ts-ignore
+ dependency,
+ components,
+ "input",
+ with_null_state
+ );
+ expect(result).toEqual([2, null]);
+ });
+ it("should return an input payload with null in place of two `state` components when with_null_state is true", () => {
+ const resolved_payload = ["hello", "goodbye"];
+ const dependency = {
+ inputs: [1, 2, 3, 4]
+ };
+ const components = [
+ { id: 1, type: "textbox" },
+ { id: 2, type: "state" },
+ { id: 3, type: "textbox" },
+ { id: 4, type: "state" }
+ ];
+ const with_null_state = true;
+ const result = handle_payload(
+ resolved_payload,
+ // @ts-ignore
+ dependency,
+ components,
+ "input",
+ with_null_state
+ );
+ expect(result).toEqual(["hello", null, "goodbye", null]);
+ });
+
+ it("should return an output payload without the state component value when with_null_state is false", () => {
+ const resolved_payload = ["hello", null];
+ const dependency = {
+ inputs: [2, 3]
+ };
+ const components = [
+ { id: 2, type: "textbox" },
+ { id: 3, type: "state" }
+ ];
+ const with_null_state = false;
+ const result = handle_payload(
+ resolved_payload,
+ // @ts-ignore
+ dependency,
+ components,
+ "output",
+ with_null_state
+ );
+ expect(result).toEqual(["hello"]);
+ });
+
+ it("should return an ouput payload without the two state component values when with_null_state is false", () => {
+ const resolved_payload = ["hello", null, "world", null];
+ const dependency = {
+ inputs: [2, 3, 4, 5]
+ };
+ const components = [
+ { id: 2, type: "textbox" },
+ { id: 3, type: "state" },
+ { id: 4, type: "textbox" },
+ { id: 5, type: "state" }
+ ];
+ const with_null_state = false;
+ const result = handle_payload(
+ resolved_payload,
+ // @ts-ignore
+ dependency,
+ components,
+ "output",
+ with_null_state
+ );
+ expect(result).toEqual(["hello", "world"]);
+ });
+
+ it("should return an ouput payload with the two state component values when with_null_state is true", () => {
+ const resolved_payload = ["hello", null, "world", null];
+ const dependency = {
+ inputs: [2, 3, 4, 5]
+ };
+ const components = [
+ { id: 2, type: "textbox" },
+ { id: 3, type: "state" },
+ { id: 4, type: "textbox" },
+ { id: 5, type: "state" }
+ ];
+ const with_null_state = true;
+ const result = handle_payload(
+ resolved_payload,
+ // @ts-ignore
+ dependency,
+ components,
+ "output",
+ with_null_state
+ );
+ expect(result).toEqual(["hello", null, "world", null]);
+ });
+
+ it("should return the same payload where no state components are defined", () => {
+ const resolved_payload = ["hello", "world"];
+ const dependency = {
+ inputs: [2, 3]
+ };
+ const components = [
+ { id: 2, type: "textbox" },
+ { id: 3, type: "textbox" }
+ ];
+ const with_null_state = true;
+ const result = handle_payload(
+ resolved_payload,
+ // @ts-ignore
+ dependency,
+ components,
+ with_null_state
+ );
+ expect(result).toEqual(["hello", "world"]);
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/handlers.ts b/node_modules/@gradio/client/src/test/handlers.ts
new file mode 100644
index 0000000000000000000000000000000000000000..308b8846bc441714ef9bf6caa39245e6415f8458
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/handlers.ts
@@ -0,0 +1,693 @@
+import { HttpResponse, http, RequestHandler } from "msw";
+import {
+ HOST_URL,
+ API_INFO_URL,
+ CONFIG_URL,
+ RUNTIME_URL,
+ SLEEPTIME_URL,
+ UPLOAD_URL,
+ BROKEN_CONNECTION_MSG,
+ LOGIN_URL
+} from "../constants";
+import {
+ response_api_info,
+ config_response,
+ whoami_response,
+ duplicate_response,
+ hardware_sleeptime_response,
+ discussions_response,
+ runtime_response
+} from "./test_data";
+
+const root_url = "https://huggingface.co";
+
+export const direct_space_url = "https://hmb-hello-world.hf.space";
+const private_space_url = "https://hmb-secret-world.hf.space";
+const private_auth_space_url = "https://hmb-private-auth-space.hf.space";
+
+const server_error_space_url = "https://hmb-server-error.hf.space";
+const upload_server_test_space_url = "https://hmb-server-test.hf.space";
+const auth_app_space_url = "https://hmb-auth-space.hf.space";
+const unauth_app_space_url = "https://hmb-unauth-space.hf.space";
+const invalid_auth_space_url = "https://hmb-invalid-auth-space.hf.space";
+
+const server_error_reference = "hmb/server_error";
+const app_reference = "hmb/hello_world";
+const broken_app_reference = "hmb/bye_world";
+const duplicate_app_reference = "gradio/hello_world";
+const private_app_reference = "hmb/secret_world";
+const server_test_app_reference = "hmb/server_test";
+const auth_app_reference = "hmb/auth_space";
+const unauth_app_reference = "hmb/unauth_space";
+const invalid_auth_app_reference = "hmb/invalid_auth_space";
+const private_auth_app_reference = "hmb/private_auth_space";
+
+export const handlers: RequestHandler[] = [
+ // /host requests
+ http.get(`${root_url}/api/spaces/${app_reference}/${HOST_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-hello-world",
+ host: "https://hmb-hello-world.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${root_url}/api/spaces/${broken_app_reference}/${HOST_URL}`, () => {
+ return new HttpResponse(null, {
+ status: 404,
+ headers: {
+ "Content-Type": "application/json",
+ hf_token: "hf_123"
+ }
+ });
+ }),
+ http.get(
+ `${root_url}/api/spaces/${private_auth_app_reference}/${HOST_URL}`,
+ () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-private-auth-space",
+ host: "https://hmb-private-auth-space.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ http.get(
+ `${root_url}/api/spaces/${private_app_reference}/${HOST_URL}`,
+ ({ request }) => {
+ const token = request.headers.get("authorization")?.substring(7);
+
+ if (!token || token !== "hf_123") {
+ return new HttpResponse(null, {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }
+
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: private_app_reference,
+ host: private_space_url
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ http.get(
+ `${root_url}/api/spaces/${server_error_reference}/${HOST_URL}`,
+ () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-server-test",
+ host: "https://hmb-server-test.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ http.get(
+ `${root_url}/api/spaces/${server_test_app_reference}/${HOST_URL}`,
+ () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-server-test",
+ host: "https://hmb-server-test.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ http.get(`${root_url}/api/spaces/${auth_app_reference}/${HOST_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-auth-space",
+ host: "https://hmb-auth-space.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(
+ `${root_url}/api/spaces/${invalid_auth_app_reference}/${HOST_URL}`,
+ () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-invalid-auth-space",
+ host: "https://hmb-invalid-auth-space.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ http.get(
+ `${root_url}/api/spaces/${duplicate_app_reference}/${HOST_URL}`,
+ () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "gradio-hello-world",
+ host: "https://gradio-hello-world.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ http.get(`${root_url}/api/spaces/${unauth_app_reference}/${HOST_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ subdomain: "hmb-unath-space",
+ host: "https://hmb-unauth-space.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ // /info requests
+ http.get(`${direct_space_url}/${API_INFO_URL}`, () => {
+ return new HttpResponse(JSON.stringify(response_api_info), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${upload_server_test_space_url}/${API_INFO_URL}`, () => {
+ return new HttpResponse(JSON.stringify(response_api_info), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${private_space_url}/${API_INFO_URL}`, () => {
+ return new HttpResponse(JSON.stringify(response_api_info), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${server_error_space_url}/${API_INFO_URL}`, () => {
+ return new HttpResponse(JSON.stringify(response_api_info), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${auth_app_space_url}/${API_INFO_URL}`, async () => {
+ return new HttpResponse(JSON.stringify(response_api_info), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${private_auth_space_url}/${API_INFO_URL}`, async () => {
+ return new HttpResponse(JSON.stringify(response_api_info), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // /config requests
+ http.get(`${direct_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(JSON.stringify(config_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${private_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ ...config_response,
+ root: "https://hmb-secret-world.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${upload_server_test_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ ...config_response,
+ root: "https://hmb-server-test.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${private_auth_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ ...config_response,
+ root: "https://hmb-private-auth-space.hf.space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${direct_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(JSON.stringify(config_response), {
+ status: 500,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${server_error_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(JSON.stringify(config_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${invalid_auth_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(JSON.stringify({ detail: "Unauthorized" }), {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${auth_app_space_url}/${CONFIG_URL}`, ({ request }) => {
+ return new HttpResponse(
+ JSON.stringify({
+ ...config_response,
+ root: "https://hmb-auth-space.hf.space",
+ space_id: "hmb/auth_space"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${unauth_app_space_url}/${CONFIG_URL}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ detail: "Unauthorized"
+ }),
+ {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ // /whoami requests
+ http.get(`${root_url}/api/whoami-v2`, () => {
+ return new HttpResponse(JSON.stringify(whoami_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json",
+ "hf-token": "hf_123"
+ }
+ });
+ }),
+ // /duplicate requests
+ http.post(
+ `${root_url}/api/spaces/${duplicate_app_reference}/duplicate`,
+ ({ request }) => {
+ if (request.headers.get("authorization")?.substring(7) !== "hf_123") {
+ throw new HttpResponse(null, {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }
+ return new HttpResponse(JSON.stringify(duplicate_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }
+ ),
+ // /sleeptime requests
+ http.post(`${root_url}/api/spaces/${app_reference}/${SLEEPTIME_URL}`, () => {
+ return new HttpResponse(JSON.stringify(hardware_sleeptime_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.post(
+ `${root_url}/api/spaces/${server_test_app_reference}/${SLEEPTIME_URL}`,
+ () => {
+ throw new HttpResponse(null, {
+ status: 500,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }
+ ),
+ // /runtime requests
+ http.get(
+ `${root_url}/api/spaces/${broken_app_reference}/${RUNTIME_URL}`,
+ () => {
+ return new HttpResponse(null, {
+ status: 404,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }
+ ),
+ http.get(`${root_url}/api/spaces/${app_reference}/${RUNTIME_URL}`, () => {
+ return new HttpResponse(JSON.stringify(hardware_sleeptime_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // queue requests
+ http.get(`${direct_space_url}/queue/data`, () => {
+ return new HttpResponse(JSON.stringify({ event_id: "123" }), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.post(`${direct_space_url}/queue/join`, () => {
+ return new HttpResponse(JSON.stringify({ event_id: "123" }), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // upload requests
+ http.post(`${direct_space_url}/${UPLOAD_URL}`, () => {
+ return new HttpResponse(JSON.stringify(["lion.jpg"]), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.post(`${upload_server_test_space_url}/${UPLOAD_URL}`, () => {
+ throw new HttpResponse(JSON.parse("Internal Server Error"), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // discussions requests
+ http.head(`${root_url}/api/spaces/${app_reference}/discussions`, () => {
+ return new HttpResponse(JSON.stringify(discussions_response), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.head(
+ `${root_url}/api/spaces/${broken_app_reference}/discussions`,
+ () => {
+ throw new HttpResponse(
+ JSON.parse("Discussions are disabled for this repo"),
+ {
+ status: 403,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }
+ ),
+ // space requests
+ http.get(`${root_url}/api/spaces/${app_reference}`, () => {
+ return new HttpResponse(
+ JSON.stringify({ id: app_reference, runtime: runtime_response }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${root_url}/api/spaces/hmb/paused_space`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ id: app_reference,
+ runtime: { ...runtime_response, stage: "PAUSED" }
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${root_url}/api/spaces/hmb/building_space`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ id: app_reference,
+ runtime: { ...runtime_response, stage: "BUILDING" }
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${root_url}/api/spaces/hmb/stopped_space`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ id: app_reference,
+ runtime: { ...runtime_response, stage: "STOPPED" }
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${root_url}/api/spaces/hmb/failed_space`, () => {
+ throw new HttpResponse(null, {
+ status: 500,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.get(`${root_url}/api/spaces/${unauth_app_reference}`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ id: unauth_app_reference,
+ runtime: { ...runtime_response }
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ // jwt requests
+ http.get(`${root_url}/api/spaces/${app_reference}/jwt`, () => {
+ return new HttpResponse(
+ JSON.stringify({
+ token: "jwt_123"
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ );
+ }),
+ http.get(`${root_url}/api/spaces/${broken_app_reference}/jwt`, () => {
+ return new HttpResponse(null, {
+ status: 500,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // post_data requests
+ http.post(`${direct_space_url}`, () => {
+ return new HttpResponse(JSON.stringify({}), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.post(`${private_space_url}`, () => {
+ return new HttpResponse(JSON.stringify(BROKEN_CONNECTION_MSG), {
+ status: 500,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // heartbeat requests
+ http.get(`*/heartbeat/*`, () => {
+ return new HttpResponse(null, {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ // login requests
+ http.post(`${auth_app_space_url}/${LOGIN_URL}`, async ({ request }) => {
+ let username;
+ let password;
+
+ await request.formData().then((data) => {
+ username = data.get("username");
+ password = data.get("password");
+ });
+
+ if (username === "admin" && password === "pass1234") {
+ return new HttpResponse(
+ JSON.stringify({
+ success: true
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json",
+ "Set-Cookie":
+ "access-token-123=abc; HttpOnly; Path=/; SameSite=none; Secure",
+ // @ts-ignore - multiple Set-Cookie headers are returned
+ "Set-Cookie":
+ "access-token-unsecure-123=abc; HttpOnly; Path=/; SameSite=none; Secure"
+ }
+ }
+ );
+ }
+
+ return new HttpResponse(null, {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.post(`${invalid_auth_space_url}/${LOGIN_URL}`, async () => {
+ return new HttpResponse(null, {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ }),
+ http.post(`${private_auth_space_url}/${LOGIN_URL}`, async ({ request }) => {
+ let username;
+ let password;
+
+ await request.formData().then((data) => {
+ username = data.get("username");
+ password = data.get("password");
+ });
+
+ if (username === "admin" && password === "pass1234") {
+ return new HttpResponse(
+ JSON.stringify({
+ success: true
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json",
+ "Set-Cookie":
+ "access-token-123=abc; HttpOnly; Path=/; SameSite=none; Secure",
+ // @ts-ignore - multiple Set-Cookie headers are returned
+ "Set-Cookie":
+ "access-token-unsecure-123=abc; HttpOnly; Path=/; SameSite=none; Secure"
+ }
+ }
+ );
+ }
+
+ return new HttpResponse(null, {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json"
+ }
+ });
+ })
+];
diff --git a/node_modules/@gradio/client/src/test/init.test.ts b/node_modules/@gradio/client/src/test/init.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b2407009544da893bd1417548ae30166b9b183ba
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/init.test.ts
@@ -0,0 +1,139 @@
+import {
+ describe,
+ beforeAll,
+ afterEach,
+ afterAll,
+ test,
+ expect,
+ vi
+} from "vitest";
+
+import { Client, client, duplicate } from "..";
+import { transformed_api_info, config_response } from "./test_data";
+import { initialise_server } from "./server";
+import { CONFIG_ERROR_MSG, SPACE_METADATA_ERROR_MSG } from "../constants";
+
+const app_reference = "hmb/hello_world";
+const broken_app_reference = "hmb/bye_world";
+const direct_app_reference = "https://hmb-hello-world.hf.space";
+const secret_direct_app_reference = "https://hmb-secret-world.hf.space";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("Client class", () => {
+ describe("initialisation", () => {
+ test("backwards compatibility of client using deprecated syntax", async () => {
+ const app = await client(app_reference);
+ expect(app.config).toEqual(config_response);
+ });
+ test("connecting to a running app with a space reference", async () => {
+ const app = await Client.connect(app_reference);
+ expect(app.config).toEqual(config_response);
+ });
+
+ test("connecting to a running app with a direct app URL", async () => {
+ const app = await Client.connect(direct_app_reference);
+ expect(app.config).toEqual(config_response);
+ });
+
+ test("connecting successfully to a private running app with a space reference", async () => {
+ const app = await Client.connect("hmb/secret_world", {
+ hf_token: "hf_123"
+ });
+
+ expect(app.config).toEqual({
+ ...config_response,
+ root: "https://hmb-secret-world.hf.space"
+ });
+ });
+
+ test("connecting successfully to a private running app with a direct app URL ", async () => {
+ const app = await Client.connect(secret_direct_app_reference, {
+ hf_token: "hf_123"
+ });
+
+ expect(app.config).toEqual({
+ ...config_response,
+ root: "https://hmb-secret-world.hf.space"
+ });
+ });
+
+ test("unsuccessfully attempting to connect to a private running app", async () => {
+ await expect(
+ Client.connect("hmb/secret_world", {
+ hf_token: "hf_bad_token"
+ })
+ ).rejects.toThrowError(SPACE_METADATA_ERROR_MSG);
+ });
+
+ test("viewing the api info of a running app", async () => {
+ const app = await Client.connect(app_reference);
+ expect(await app.view_api()).toEqual(transformed_api_info);
+ });
+
+ test("viewing the api info of a non-existent app", async () => {
+ const app = Client.connect(broken_app_reference);
+ await expect(app).rejects.toThrowError();
+ });
+ });
+
+ describe("duplicate", () => {
+ test("backwards compatibility of duplicate using deprecated syntax", async () => {
+ const app = await duplicate("gradio/hello_world", {
+ hf_token: "hf_123",
+ private: true,
+ hardware: "cpu-basic"
+ });
+
+ expect(app.config).toEqual(config_response);
+ });
+
+ test("creating a duplicate of a running app", async () => {
+ const duplicate = await Client.duplicate("gradio/hello_world", {
+ hf_token: "hf_123",
+ private: true,
+ hardware: "cpu-basic"
+ });
+
+ expect(duplicate.config).toEqual(config_response);
+ });
+
+ test("creating a duplicate of a running app without a token", async () => {
+ const duplicate = Client.duplicate("gradio/hello_world", {
+ private: true,
+ hardware: "cpu-basic"
+ });
+
+ await expect(duplicate).rejects.toThrow("Error: Unauthorized");
+ });
+
+ test("creating a duplicate of a broken app", async () => {
+ const duplicate = Client.duplicate(broken_app_reference);
+
+ await expect(duplicate).rejects.toThrow(SPACE_METADATA_ERROR_MSG);
+ });
+ });
+
+ describe("overriding the Client class", () => {
+ test("overriding methods on the Client class", async () => {
+ const mocked_fetch = vi.fn(
+ (input: RequestInfo | URL, init?: RequestInit): Promise => {
+ return Promise.resolve(
+ new Response(JSON.stringify({ data: "test" }))
+ );
+ }
+ );
+
+ class CustomClient extends Client {
+ fetch = mocked_fetch;
+ }
+
+ await CustomClient.connect("hmb/hello_world");
+ expect(mocked_fetch).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/init_helpers.test.ts b/node_modules/@gradio/client/src/test/init_helpers.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2462dd4ea2691e59fc71e817b81839dfb4b9e672
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/init_helpers.test.ts
@@ -0,0 +1,146 @@
+import {
+ resolve_root,
+ get_jwt,
+ determine_protocol,
+ parse_and_set_cookies
+} from "../helpers/init_helpers";
+import { initialise_server } from "./server";
+import { beforeAll, afterEach, afterAll, it, expect, describe } from "vitest";
+import { Client } from "../client";
+import { INVALID_CREDENTIALS_MSG, MISSING_CREDENTIALS_MSG } from "../constants";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("resolve_root", () => {
+ it('should return the base URL if the root path starts with "http://"', () => {
+ const base_url = "https://huggingface.co";
+ const root_path = "https://hmb-hello-world.hf.space";
+ const prioritize_base = true;
+ const result = resolve_root(base_url, root_path, prioritize_base);
+ expect(result).toBe(base_url);
+ });
+
+ it('should return the base URL if the root path starts with "https://"', () => {
+ const base_url = "https://huggingface.co";
+ const root_path = "https://hmb-hello-world.hf.space";
+ const prioritize_base = true;
+ const result = resolve_root(base_url, root_path, prioritize_base);
+ expect(result).toBe(base_url);
+ });
+});
+
+describe("get_jwt", () => {
+ it("should return a valid JWT token when the API call is successful", async () => {
+ const space = "hmb/hello_world";
+ const token = "hf_123";
+ const expected_jwt = "jwt_123";
+
+ const result = await get_jwt(space, token);
+
+ expect(result).toBe(expected_jwt);
+ });
+
+ it("should return false when the API call fails", async () => {
+ const space = "hmb/bye_world";
+ const token = "hf_123";
+
+ const result = await get_jwt(space, token);
+
+ expect(result).toBe(false);
+ });
+});
+
+describe("determine_protocol", () => {
+ it('should return the correct protocols and host when the endpoint starts with "http"', () => {
+ const endpoint = "http://huggingface.co";
+ const result = determine_protocol(endpoint);
+ expect(result).toEqual({
+ ws_protocol: "ws",
+ http_protocol: "http:",
+ host: "huggingface.co"
+ });
+ });
+
+ it('should return the correct protocols and host when the endpoint starts with "https"', () => {
+ const endpoint = "https://huggingface.co";
+ const result = determine_protocol(endpoint);
+ expect(result).toEqual({
+ ws_protocol: "wss",
+ http_protocol: "https:",
+ host: "huggingface.co"
+ });
+ });
+
+ it('should return the correct protocols and host when the endpoint starts with "file"', () => {
+ const endpoint = "file:///path/to/app.html";
+ const result = determine_protocol(endpoint);
+ expect(result).toEqual({
+ ws_protocol: "ws",
+ http_protocol: "http:",
+ host: "lite.local"
+ });
+ });
+
+ it('should return the default protocols and host when the endpoint does not start with "http" or "file"', () => {
+ const endpoint = "huggingface.co";
+ const result = determine_protocol(endpoint);
+ expect(result).toEqual({
+ ws_protocol: "wss",
+ http_protocol: "https:",
+ host: "huggingface.co"
+ });
+ });
+});
+
+describe("parse_and_set_cookies", () => {
+ it("should return an empty array when the cookie header is empty", () => {
+ const cookie_header = "";
+ const result = parse_and_set_cookies(cookie_header);
+ expect(result).toEqual([]);
+ });
+
+ it("should parse the cookie header and return an array of cookies", () => {
+ const cookie_header = "access-token-123=abc;access-token-unsecured-456=def";
+ const result = parse_and_set_cookies(cookie_header);
+ expect(result).toEqual(["access-token-123=abc"]);
+ });
+});
+
+describe("resolve_cookies", () => {
+ it("should set the cookies when correct auth credentials are provided", async () => {
+ const client = await Client.connect("hmb/auth_space", {
+ auth: ["admin", "pass1234"]
+ });
+
+ const api = client.view_api();
+ expect((await api).named_endpoints["/predict"]).toBeDefined();
+ });
+
+ it("should connect to a private and authenticated space", async () => {
+ const client = await Client.connect("hmb/private_auth_space", {
+ hf_token: "hf_123",
+ auth: ["admin", "pass1234"]
+ });
+
+ const api = client.view_api();
+ expect((await api).named_endpoints["/predict"]).toBeDefined();
+ });
+
+ it("should not set the cookies when auth credentials are invalid", async () => {
+ await expect(
+ Client.connect("hmb/invalid_auth_space", {
+ auth: ["admin", "wrong_password"]
+ })
+ ).rejects.toThrowError(INVALID_CREDENTIALS_MSG);
+ });
+
+ it("should not set the cookies when auth option is not provided in an auth space", async () => {
+ await expect(Client.connect("hmb/unauth_space")).rejects.toThrowError(
+ MISSING_CREDENTIALS_MSG
+ );
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/mock_eventsource.ts b/node_modules/@gradio/client/src/test/mock_eventsource.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1f47258cd3b90b03fa1dc97991806bc4fad54dfc
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/mock_eventsource.ts
@@ -0,0 +1,13 @@
+import { vi } from "vitest";
+
+if (process.env.TEST_MODE !== "node") {
+ Object.defineProperty(window, "EventSource", {
+ writable: true,
+ value: vi.fn().mockImplementation(() => ({
+ close: vi.fn(() => {}),
+ addEventListener: vi.fn(),
+ onmessage: vi.fn((_event: MessageEvent) => {}),
+ onerror: vi.fn((_event: Event) => {})
+ }))
+ });
+}
diff --git a/node_modules/@gradio/client/src/test/post_data.test.ts b/node_modules/@gradio/client/src/test/post_data.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6ae96fed346ce8d2171ef1621ef394ca45d53684
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/post_data.test.ts
@@ -0,0 +1,45 @@
+import { Client } from "../client";
+
+import { initialise_server } from "./server";
+import { BROKEN_CONNECTION_MSG } from "../constants";
+const server = initialise_server();
+import { beforeAll, afterEach, afterAll, it, expect, describe } from "vitest";
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("post_data", () => {
+ it("should send a POST request with the correct headers and body", async () => {
+ const app = await Client.connect("hmb/hello_world");
+ const config = app.config;
+ const url = config?.root;
+ const body = { data: "test" };
+
+ if (!url) {
+ throw new Error("No URL provided");
+ }
+
+ const [response, status] = await app.post_data(url, body);
+
+ expect(response).toEqual({});
+ expect(status).toBe(200);
+ });
+
+ it("should handle network errors", async () => {
+ const app = await Client.connect("hmb/secret_world", {
+ hf_token: "hf_123"
+ });
+
+ const url = "https://hmb-secret-world.hf.space";
+
+ if (!url) {
+ throw new Error("No URL provided");
+ }
+
+ const [response, status] = await app.post_data(url, {});
+
+ expect(response).toEqual(BROKEN_CONNECTION_MSG);
+ expect(status).toBe(500);
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/server.ts b/node_modules/@gradio/client/src/test/server.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8eb91f6b278e6abb51965a1bf45561082c527bb6
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/server.ts
@@ -0,0 +1,6 @@
+import { setupServer } from "msw/node";
+import { handlers } from "./handlers";
+
+export function initialise_server(): any {
+ return setupServer(...handlers);
+}
diff --git a/node_modules/@gradio/client/src/test/spaces.test.ts b/node_modules/@gradio/client/src/test/spaces.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60271ff37a57af9770e88c3b76011e7c98f3e2fc
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/spaces.test.ts
@@ -0,0 +1,145 @@
+import { SPACE_STATUS_ERROR_MSG } from "../constants";
+import {
+ discussions_enabled,
+ get_space_hardware,
+ set_space_timeout,
+ check_space_status
+} from "../helpers/spaces";
+import { beforeAll, afterEach, afterAll, it, expect, describe } from "vitest";
+
+import { initialise_server } from "./server";
+import { hardware_sleeptime_response } from "./test_data";
+import { vi } from "vitest";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("set_space_timeout", () => {
+ it("should set the sleep timeout for a space", async () => {
+ const space_id = "hmb/hello_world";
+ const timeout = 60;
+ const hf_token = "hf_123";
+
+ const response = await set_space_timeout(space_id, timeout, hf_token);
+
+ expect(response).toEqual(hardware_sleeptime_response);
+ });
+
+ it("should throw an error if the fetch call fails", async () => {
+ const space_id = "hmb/server_test";
+ const timeout = 60;
+ const hf_token = "hf_123";
+
+ await expect(
+ set_space_timeout(space_id, timeout, hf_token)
+ ).rejects.toThrow(
+ "Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges."
+ );
+ });
+});
+
+describe("get_space_hardware", () => {
+ it("should return the current hardware for a space", async () => {
+ const space_id = "hmb/hello_world";
+ const hf_token = "hf_123";
+
+ const hardware = await get_space_hardware(space_id, hf_token);
+ expect(hardware).toEqual(hardware_sleeptime_response.hardware.current);
+ });
+
+ it("should throw an error if the fetch call fails", async () => {
+ const space_id = "hmb/bye_world";
+
+ await expect(get_space_hardware(space_id)).rejects.toThrow(
+ "Space hardware could not be obtained."
+ );
+ });
+});
+
+describe("discussions_enabled", () => {
+ it("should return true if discussions are enabled for the space", async () => {
+ const space_id = "hmb/hello_world";
+ const result = await discussions_enabled(space_id);
+ expect(result).toBe(true);
+ });
+
+ it("should return false if discussions are disabled for the space", async () => {
+ const space_id = "hmb/bye_world";
+ const result = await discussions_enabled(space_id);
+ expect(result).toBe(false);
+ });
+});
+
+describe("check_space_status", () => {
+ const status_callback = vi.fn();
+
+ it("should handle a successful response with RUNNING stage", async () => {
+ const id = "hmb/hello_world";
+ const type = "space_name";
+
+ await check_space_status(id, type, status_callback);
+ expect(status_callback).toHaveBeenCalledWith({
+ status: "running",
+ load_status: "complete",
+ message: "",
+ detail: "RUNNING"
+ });
+ });
+
+ it("should handle a successful response with PAUSED stage", async () => {
+ const id = "hmb/paused_space";
+ const type = "space_name";
+
+ await check_space_status(id, type, status_callback);
+ expect(status_callback).toHaveBeenCalledWith({
+ status: "paused",
+ load_status: "error",
+ message:
+ "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
+ detail: "PAUSED",
+ discussions_enabled: true
+ });
+ });
+
+ it("should handle a successful response with BUILDING stage", async () => {
+ const id = "hmb/building_space";
+ const type = "space_name";
+
+ await check_space_status(id, type, status_callback);
+ expect(status_callback).toHaveBeenCalledWith({
+ status: "building",
+ load_status: "pending",
+ message: "Space is building...",
+ detail: "BUILDING"
+ });
+ });
+
+ it("should handle a successful response with STOPPED stage", async () => {
+ const id = "hmb/stopped_space";
+ const type = "space_name";
+
+ await check_space_status(id, type, status_callback);
+ expect(status_callback).toHaveBeenCalledWith({
+ status: "sleeping",
+ load_status: "pending",
+ message: "Space is asleep. Waking it up...",
+ detail: "STOPPED"
+ });
+ });
+
+ it("should handle a failed response", async () => {
+ const id = "hmb/failed_space";
+ const type = "space_name";
+
+ await check_space_status(id, type, status_callback);
+ expect(status_callback).toHaveBeenCalledWith({
+ status: "error",
+ load_status: "error",
+ message: SPACE_STATUS_ERROR_MSG,
+ detail: "NOT_FOUND"
+ });
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/stream.test.ts b/node_modules/@gradio/client/src/test/stream.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9ac4b6c6a05b70f4fe07b7801eac9821fec62b8b
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/stream.test.ts
@@ -0,0 +1,81 @@
+import { vi, type Mock } from "vitest";
+import { Client } from "../client";
+import { readable_stream } from "../utils/stream";
+import { initialise_server } from "./server";
+import { direct_space_url } from "./handlers.ts";
+
+import {
+ describe,
+ it,
+ expect,
+ afterEach,
+ beforeAll,
+ afterAll,
+ beforeEach
+} from "vitest";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("open_stream", () => {
+ let app: Client;
+
+ beforeEach(async () => {
+ app = await Client.connect("hmb/hello_world");
+ app.stream = vi.fn().mockImplementation(() => {
+ app.stream_instance = readable_stream(
+ new URL(`${direct_space_url}/queue/data`)
+ );
+ return app.stream_instance;
+ });
+ });
+
+ afterEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("should throw an error if config is not defined", () => {
+ app.config = undefined;
+
+ expect(async () => {
+ await app.open_stream();
+ }).rejects.toThrow("Could not resolve app config");
+ });
+
+ it("should connect to the SSE endpoint and handle messages", async () => {
+ await app.open_stream();
+
+ const eventsource_mock_call = (app.stream as Mock).mock.calls[0][0];
+
+ expect(eventsource_mock_call.href).toMatch(
+ /https:\/\/hmb-hello-world\.hf\.space\/queue\/data\?session_hash/
+ );
+
+ expect(app.stream).toHaveBeenCalledWith(eventsource_mock_call);
+
+ if (!app.stream_instance?.onmessage || !app.stream_instance?.onerror) {
+ throw new Error("stream instance is not defined");
+ }
+
+ const onMessageCallback = app.stream_instance.onmessage.bind(app);
+ const onErrorCallback = app.stream_instance.onerror.bind(app);
+
+ const message = { msg: "hello jerry" };
+
+ onMessageCallback({ data: JSON.stringify(message) });
+ expect(app.stream_status.open).toBe(true);
+
+ expect(app.event_callbacks).toEqual({});
+ expect(app.pending_stream_messages).toEqual({});
+
+ const close_stream_message = { msg: "close_stream" };
+ onMessageCallback({ data: JSON.stringify(close_stream_message) });
+ expect(app.stream_status.open).toBe(false);
+
+ onErrorCallback({ data: JSON.stringify("404") });
+ expect(app.stream_status.open).toBe(false);
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/test_data.ts b/node_modules/@gradio/client/src/test/test_data.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0d7aa5c3a135754c78072a140a55bd99c550735
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/test_data.ts
@@ -0,0 +1,563 @@
+// @ts-nocheck
+import { ApiData, ApiInfo, Config, EndpointInfo } from "../types";
+
+export const runtime_response = {
+ stage: "RUNNING",
+ hardware: {
+ current: "cpu-basic",
+ requested: "cpu-basic"
+ },
+ storage: {
+ current: null,
+ requested: null
+ },
+ gcTimeout: 86400,
+ replicas: {
+ current: 1,
+ requested: 1
+ },
+ devMode: false,
+ domains: [
+ {
+ domain: "hmb-hello-world.hf.space",
+ isCustom: false,
+ stage: "READY"
+ }
+ ]
+};
+
+export const transformed_api_info: ApiInfo = {
+ named_endpoints: {
+ "/predict": {
+ parameters: [
+ {
+ label: "name",
+ type: "string",
+ python_type: { type: "str", description: "" },
+ component: "Textbox",
+ example_input: "Hello!!"
+ }
+ ],
+ returns: [
+ {
+ label: "output",
+ type: "string",
+ python_type: { type: "str", description: "" },
+ component: "Textbox"
+ }
+ ],
+ type: { continuous: false, generator: false, cancel: false }
+ }
+ },
+ unnamed_endpoints: {
+ "0": {
+ parameters: [
+ {
+ label: "name",
+ type: "string",
+ python_type: { type: "str", description: "" },
+ component: "Textbox",
+ example_input: "Hello!!"
+ }
+ ],
+ returns: [
+ {
+ label: "output",
+ type: "string",
+ python_type: { type: "str", description: "" },
+ component: "Textbox"
+ }
+ ],
+ type: { continuous: false, generator: false, cancel: false }
+ }
+ }
+};
+
+export const response_api_info: ApiInfo = {
+ named_endpoints: {
+ "/predict": {
+ parameters: [
+ {
+ label: "name",
+ type: {
+ type: "string"
+ },
+ python_type: {
+ type: "str",
+ description: ""
+ },
+ component: "Textbox",
+ example_input: "Hello!!"
+ }
+ ],
+ returns: [
+ {
+ label: "output",
+ type: {
+ type: "string"
+ },
+ python_type: {
+ type: "str",
+ description: ""
+ },
+ component: "Textbox"
+ }
+ ]
+ }
+ },
+ unnamed_endpoints: {}
+};
+
+export const config_response: Config = {
+ version: "4.27.0",
+ mode: "interface",
+ app_id: 123,
+ dev_mode: false,
+ analytics_enabled: true,
+ components: [
+ {
+ id: 3,
+ type: "row",
+ props: {
+ variant: "default",
+ visible: true,
+ equal_height: false,
+ name: "row"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 4,
+ type: "column",
+ props: {
+ scale: 1,
+ min_width: 320,
+ variant: "panel",
+ visible: true,
+ name: "column"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 5,
+ type: "column",
+ props: {
+ scale: 1,
+ min_width: 320,
+ variant: "default",
+ visible: true,
+ name: "column"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 1,
+ type: "textbox",
+ props: {
+ lines: 1,
+ max_lines: 20,
+ label: "name",
+ show_label: true,
+ container: true,
+ min_width: 160,
+ visible: true,
+ autofocus: false,
+ autoscroll: true,
+ elem_classes: [],
+ type: "text",
+ rtl: false,
+ show_copy_button: false,
+ name: "textbox",
+ _selectable: false
+ },
+ skip_api: false,
+ component_class_id: "",
+ api_info: {
+ type: "string"
+ },
+ example_inputs: "Hello!!"
+ },
+ {
+ id: 6,
+ type: "form",
+ props: {
+ scale: 0,
+ min_width: 0,
+ name: "form"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 7,
+ type: "row",
+ props: {
+ variant: "default",
+ visible: true,
+ equal_height: true,
+ name: "row"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 8,
+ type: "button",
+ props: {
+ value: "Clear",
+ variant: "secondary",
+ visible: true,
+ interactive: true,
+ elem_classes: [],
+ show_api: false,
+ name: "button",
+ _selectable: false
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 9,
+ type: "button",
+ props: {
+ value: "Submit",
+ variant: "primary",
+ visible: true,
+ interactive: true,
+ elem_classes: [],
+ name: "button",
+ _selectable: false
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 10,
+ type: "column",
+ props: {
+ scale: 1,
+ min_width: 320,
+ variant: "panel",
+ visible: true,
+ name: "column"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 2,
+ type: "textbox",
+ props: {
+ lines: 1,
+ max_lines: 20,
+ label: "output",
+ show_label: true,
+ container: true,
+ min_width: 160,
+ interactive: false,
+ visible: true,
+ autofocus: false,
+ autoscroll: true,
+ elem_classes: [],
+ type: "text",
+ rtl: false,
+ show_copy_button: false,
+ name: "textbox",
+ _selectable: false
+ },
+ skip_api: false,
+ component_class_id: "",
+ api_info: {
+ type: "string"
+ },
+ example_inputs: "Hello!!"
+ },
+ {
+ id: 11,
+ type: "row",
+ props: {
+ variant: "default",
+ visible: true,
+ equal_height: true,
+ name: "row"
+ },
+ skip_api: true,
+ component_class_id: ""
+ },
+ {
+ id: 12,
+ type: "form",
+ props: {
+ scale: 0,
+ min_width: 0,
+ name: "form"
+ },
+ skip_api: true,
+ component_class_id: ""
+ }
+ ],
+ css: null,
+ js: null,
+ head: null,
+ title: "Gradio",
+ space_id: "hmb/hello_world",
+ enable_queue: true,
+ show_error: false,
+ show_api: true,
+ is_colab: false,
+ stylesheets: [],
+ theme: "default",
+ protocol: "sse_v3",
+ body_css: {
+ body_background_fill: "white",
+ body_text_color: "#1f2937",
+ body_background_fill_dark: "#0b0f19",
+ body_text_color_dark: "#f3f4f6"
+ },
+ fill_height: false,
+ layout: {
+ id: 0,
+ children: [
+ {
+ id: 3,
+ children: [
+ {
+ id: 4,
+ children: [
+ {
+ id: 5,
+ children: [
+ {
+ id: 6,
+ children: [
+ {
+ id: 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ id: 7,
+ children: [
+ {
+ id: 8
+ },
+ {
+ id: 9
+ }
+ ]
+ }
+ ]
+ },
+ {
+ id: 10,
+ children: [
+ {
+ id: 12,
+ children: [
+ {
+ id: 2
+ }
+ ]
+ },
+ {
+ id: 11,
+ children: []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ dependencies: [
+ {
+ id: 0,
+ targets: [
+ [9, "click"],
+ [1, "submit"]
+ ],
+ inputs: [1],
+ outputs: [2],
+ backend_fn: true,
+ js: null,
+ queue: null,
+ api_name: "predict",
+ scroll_to_output: false,
+ show_progress: "full",
+ every: null,
+ batch: false,
+ max_batch_size: 4,
+ cancels: [],
+ types: {
+ continuous: false,
+ generator: false,
+ cancel: false
+ },
+ collects_event_data: false,
+ trigger_after: null,
+ trigger_only_on_success: false,
+ trigger_mode: "once",
+ show_api: true,
+ zerogpu: false
+ },
+ {
+ id: 1,
+ targets: [[8, "click"]],
+ inputs: [],
+ outputs: [1, 2],
+ backend_fn: false,
+ js: "() => [null, null]",
+ queue: false,
+ api_name: "js_fn",
+ scroll_to_output: false,
+ show_progress: "full",
+ every: null,
+ batch: false,
+ max_batch_size: 4,
+ cancels: [],
+ types: {
+ continuous: false,
+ generator: false,
+ cancel: false
+ },
+ collects_event_data: false,
+ trigger_after: null,
+ trigger_only_on_success: false,
+ trigger_mode: "once",
+ show_api: false,
+ zerogpu: false
+ },
+ {
+ id: 2,
+ targets: [[8, "click"]],
+ inputs: [],
+ outputs: [5],
+ backend_fn: false,
+ js: '() => [{"variant": null, "visible": true, "__type__": "update"}]\n ',
+ queue: false,
+ api_name: "js_fn_1",
+ scroll_to_output: false,
+ show_progress: "full",
+ every: null,
+ batch: false,
+ max_batch_size: 4,
+ cancels: [],
+ types: {
+ continuous: false,
+ generator: false,
+ cancel: false
+ },
+ collects_event_data: false,
+ trigger_after: null,
+ trigger_only_on_success: false,
+ trigger_mode: "once",
+ show_api: false,
+ zerogpu: false
+ }
+ ],
+ root: "https://hmb-hello-world.hf.space",
+ path: ""
+};
+
+export const whoami_response = {
+ type: "user",
+ id: "123",
+ name: "hmb",
+ fullname: "jerry",
+ email: "jerry@gradio.com",
+ emailVerified: true,
+ canPay: true,
+ periodEnd: 123,
+ isPro: false,
+ avatarUrl: "",
+ orgs: [],
+ auth: {
+ type: "access_token",
+ accessToken: {
+ displayName: "Gradio Client",
+ role: "write"
+ }
+ }
+};
+
+export const duplicate_response = {
+ url: "https://huggingface.co/spaces/hmb/hello_world"
+};
+
+export const hardware_sleeptime_response = {
+ stage: "RUNNING",
+ hardware: {
+ current: "cpu-basic",
+ requested: "cpu-upgrade"
+ },
+ storage: null,
+ gcTimeout: 300,
+ replicas: {
+ current: 1,
+ requested: 1
+ },
+ devMode: false,
+ domains: [
+ {
+ domain: "hmb-hello-world.hf.space",
+ isCustom: false,
+ stage: "READY"
+ }
+ ]
+};
+
+export const endpoint_info: EndpointInfo = {
+ parameters: [
+ {
+ label: "parameter_2",
+ parameter_name: "im",
+ parameter_has_default: false,
+ parameter_default: null,
+ type: "",
+ python_type: {
+ type: "Dict(background: filepath | None, layers: List[filepath], composite: filepath | None, id: str | None)",
+ description: ""
+ },
+ component: "Imageeditor",
+ example_input: {
+ background: {
+ path: "",
+ meta: {
+ _type: "gradio.FileData"
+ },
+ orig_name: "bus.png",
+ url: ""
+ },
+ layers: [],
+ composite: null
+ }
+ }
+ ],
+ returns: [
+ {
+ label: "value_3",
+ type: "string",
+ python_type: {
+ type: "filepath",
+ description: ""
+ },
+ component: "Image"
+ }
+ ],
+ type: {
+ continuous: false,
+ generator: false
+ }
+};
+
+export const discussions_response = {
+ discussions: [],
+ count: 0,
+ start: 0,
+ numClosedDiscussions: 0
+};
diff --git a/node_modules/@gradio/client/src/test/upload_files.test.ts b/node_modules/@gradio/client/src/test/upload_files.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2f50a0984a305d741833eac824b5e112ab6feb00
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/upload_files.test.ts
@@ -0,0 +1,42 @@
+import { describe, it, expect, afterEach, beforeAll, afterAll } from "vitest";
+
+import { Client } from "..";
+import { initialise_server } from "./server";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("upload_files", () => {
+ it("should upload files successfully", async () => {
+ const root_url = "https://hmb-hello-world.hf.space";
+
+ const client = await Client.connect("hmb/hello_world", {
+ hf_token: "hf_token"
+ });
+
+ const files = [new Blob([], { type: "image/jpeg" })];
+
+ const response = await client.upload_files(root_url, files);
+
+ if (!response.files) {
+ throw new Error("No files returned");
+ }
+
+ expect(response.files).toHaveLength(1);
+ expect(response.files[0]).toBe("lion.jpg");
+ });
+
+ it.skip("should handle a server error when connected to a running app and uploading files", async () => {
+ const client = await Client.connect("hmb/server_test");
+
+ const root_url = "https://hmb-server-test.hf.space";
+ const files = [new Blob([""], { type: "text/plain" })];
+
+ await expect(client.upload_files(root_url, files)).rejects.toThrow(
+ "Connection errored out. Failed to fetch"
+ );
+ });
+});
diff --git a/node_modules/@gradio/client/src/test/view_api.test.ts b/node_modules/@gradio/client/src/test/view_api.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c137be6e2d553f17f72ed41f5e85e6985f060226
--- /dev/null
+++ b/node_modules/@gradio/client/src/test/view_api.test.ts
@@ -0,0 +1,53 @@
+import { describe, beforeAll, afterEach, afterAll, test, expect } from "vitest";
+
+import { Client, client, duplicate } from "..";
+import { transformed_api_info, config_response } from "./test_data";
+import { initialise_server } from "./server";
+
+const app_reference = "hmb/hello_world";
+const secret_app_reference = "hmb/secret_world";
+const secret_direct_app_reference = "https://hmb-secret-world.hf.space";
+
+const server = initialise_server();
+
+beforeAll(() => server.listen());
+afterEach(() => server.resetHandlers());
+afterAll(() => server.close());
+
+describe("view_api", () => {
+ test("viewing the api of a running, public app", async () => {
+ const app = await Client.connect(app_reference);
+
+ expect(await app.view_api()).toEqual(transformed_api_info);
+ });
+
+ test("viewing the api of a running, private app", async () => {
+ const app = await Client.connect(secret_app_reference, {
+ hf_token: "hf_123"
+ });
+
+ expect(app.config).toEqual({
+ ...config_response,
+ root: secret_direct_app_reference
+ });
+
+ expect(await app.view_api()).toEqual({
+ ...transformed_api_info
+ });
+ });
+
+ test("viewing the api of a running, private app with a direct app URL", async () => {
+ const app = await Client.connect(secret_direct_app_reference, {
+ hf_token: "hf_123"
+ });
+
+ expect(app.config).toEqual({
+ ...config_response,
+ root: secret_direct_app_reference
+ });
+
+ expect(await app.view_api()).toEqual({
+ ...transformed_api_info
+ });
+ });
+});
diff --git a/node_modules/@gradio/client/src/types.ts b/node_modules/@gradio/client/src/types.ts
index 2b1869855ef0a7d40d9fcda86bfc98197e733478..8e2d33c27fb388d3ba078bfb7aec421675bfd802 100644
--- a/node_modules/@gradio/client/src/types.ts
+++ b/node_modules/@gradio/client/src/types.ts
@@ -1,13 +1,163 @@
+// API Data Types
+
+import { hardware_types } from "./helpers/spaces";
+import type { SvelteComponent } from "svelte";
+import type { ComponentType } from "svelte";
+
+export interface ApiData {
+ label: string;
+ parameter_name: string;
+ parameter_default?: any;
+ parameter_has_default?: boolean;
+ type: {
+ type: any;
+ description: string;
+ };
+ component: string;
+ example_input?: any;
+ python_type: { type: string; description: string };
+ serializer: string;
+}
+
+export interface JsApiData {
+ label: string;
+ parameter_name: string;
+ parameter_default?: any;
+ parameter_has_default?: boolean;
+ type: string;
+ description: string;
+ component: string;
+ example_input?: any;
+ serializer: string;
+ python_type: { type: string; description: string };
+}
+
+export interface EndpointInfo {
+ parameters: T[];
+ returns: T[];
+ type?: DependencyTypes;
+}
+
+export interface ApiInfo {
+ named_endpoints: Record>;
+ unnamed_endpoints: Record>;
+}
+
+export interface BlobRef {
+ path: string[];
+ type: string | undefined;
+ blob: Blob | File | false;
+}
+
+export type DataType = string | Buffer | Record | any[];
+
+// custom class used for uploading local files
+export class Command {
+ type: string;
+ command: string;
+ meta: {
+ path: string;
+ name: string;
+ orig_path: string;
+ };
+ fileData?: FileData;
+
+ constructor(
+ command: string,
+ meta: { path: string; name: string; orig_path: string }
+ ) {
+ this.type = "command";
+ this.command = command;
+ this.meta = meta;
+ }
+}
+
+// Function Signature Types
+
+export type SubmitFunction = (
+ endpoint: string | number,
+ data: unknown[] | Record,
+ event_data?: unknown,
+ trigger_id?: number | null
+) => SubmitIterable;
+
+export type PredictFunction = (
+ endpoint: string | number,
+ data: unknown[] | Record,
+ event_data?: unknown
+) => Promise;
+
+export type client_return = {
+ config: Config | undefined;
+ predict: PredictFunction;
+ submit: SubmitFunction;
+ component_server: (
+ component_id: number,
+ fn_name: string,
+ data: unknown[]
+ ) => any;
+ view_api: (_fetch: typeof fetch) => Promise>;
+};
+
+export interface SubmitIterable extends AsyncIterable {
+ [Symbol.asyncIterator](): AsyncIterator;
+ cancel: () => Promise;
+}
+
+export type PredictReturn = {
+ type: EventType;
+ time: Date;
+ data: unknown;
+ endpoint: string;
+ fn_index: number;
+};
+
+// Space Status Types
+
+export type SpaceStatus = SpaceStatusNormal | SpaceStatusError;
+
+export interface SpaceStatusNormal {
+ status: "sleeping" | "running" | "building" | "error" | "stopped";
+ detail:
+ | "SLEEPING"
+ | "RUNNING"
+ | "RUNNING_BUILDING"
+ | "BUILDING"
+ | "NOT_FOUND";
+ load_status: "pending" | "error" | "complete" | "generating";
+ message: string;
+}
+
+export interface SpaceStatusError {
+ status: "space_error" | "paused";
+ detail:
+ | "NO_APP_FILE"
+ | "CONFIG_ERROR"
+ | "BUILD_ERROR"
+ | "RUNTIME_ERROR"
+ | "PAUSED";
+ load_status: "error";
+ message: string;
+ discussions_enabled: boolean;
+}
+
+export type SpaceStatusCallback = (a: SpaceStatus) => void;
+
+// Configuration and Response Types
+// --------------------------------
export interface Config {
- auth_required: boolean | undefined;
+ auth_required: boolean;
+ analytics_enabled: boolean;
+ connect_heartbeat: boolean;
auth_message: string;
- components: any[];
+ components: ComponentMeta[];
css: string | null;
js: string | null;
head: string | null;
- dependencies: any[];
+ dependencies: Dependency[];
dev_mode: boolean;
enable_queue: boolean;
+ show_error: boolean;
layout: any;
mode: "blocks" | "interface";
root: string;
@@ -16,29 +166,164 @@ export interface Config {
title: string;
version: string;
space_id: string | null;
+ is_space: boolean;
is_colab: boolean;
show_api: boolean;
stylesheets: string[];
path: string;
- protocol?: "sse_v1" | "sse" | "ws";
+ protocol: "sse_v3" | "sse_v2.1" | "sse_v2" | "sse_v1" | "sse" | "ws";
+ max_file_size?: number;
+ theme_hash?: number;
+}
+
+// todo: DRY up types
+export interface ComponentMeta {
+ type: string;
+ id: number;
+ has_modes: boolean;
+ props: SharedProps;
+ instance: SvelteComponent;
+ component: ComponentType;
+ documentation?: Documentation;
+ children?: ComponentMeta[];
+ parent?: ComponentMeta;
+ value?: any;
+ component_class_id: string;
+ key: string | number | null;
+ rendered_in?: number;
+}
+
+interface SharedProps {
+ elem_id?: string;
+ elem_classes?: string[];
+ components?: string[];
+ server_fns?: string[];
+ interactive: boolean;
+ [key: string]: unknown;
+ root_url?: string;
+}
+
+export interface Documentation {
+ type?: TypeDescription;
+ description?: TypeDescription;
+ example_data?: string;
+}
+
+interface TypeDescription {
+ input_payload?: string;
+ response_object?: string;
+ payload?: string;
+}
+
+export interface Dependency {
+ id: number;
+ targets: [number, string][];
+ inputs: number[];
+ outputs: number[];
+ backend_fn: boolean;
+ js: string | null;
+ scroll_to_output: boolean;
+ trigger: "click" | "load" | string;
+ max_batch_size: number;
+ show_progress: "full" | "minimal" | "hidden";
+ frontend_fn: ((...args: unknown[]) => Promise) | null;
+ status?: string;
+ queue: boolean | null;
+ every: number | null;
+ batch: boolean;
+ api_name: string | null;
+ cancels: number[];
+ types: DependencyTypes;
+ collects_event_data: boolean;
+ pending_request?: boolean;
+ trigger_after?: number;
+ trigger_only_on_success?: boolean;
+ trigger_mode: "once" | "multiple" | "always_last";
+ final_event: Payload | null;
+ show_api: boolean;
+ zerogpu?: boolean;
+ rendered_in: number | null;
+}
+
+export interface DependencyTypes {
+ continuous: boolean;
+ generator: boolean;
+ cancel: boolean;
}
export interface Payload {
+ fn_index: number;
data: unknown[];
- fn_index?: number;
- event_data?: unknown;
time?: Date;
+ event_data?: unknown;
+ trigger_id?: number | null;
}
export interface PostResponse {
error?: string;
[x: string]: any;
}
+
export interface UploadResponse {
error?: string;
files?: string[];
}
+// Client and File Handling Types
+
+export interface DuplicateOptions extends ClientOptions {
+ private?: boolean;
+ hardware?: (typeof hardware_types)[number];
+ timeout?: number;
+}
+
+export interface ClientOptions {
+ hf_token?: `hf_${string}`;
+ status_callback?: SpaceStatusCallback | null;
+ auth?: [string, string] | null;
+ with_null_state?: boolean;
+ events?: EventType[];
+}
+
+export interface FileData {
+ name: string;
+ orig_name?: string;
+ size?: number;
+ data: string;
+ blob?: File;
+ is_file?: boolean;
+ mime_type?: string;
+ alt_text?: string;
+}
+
+// Event and Listener Types
+
+export type EventType = "data" | "status" | "log" | "render";
+
+export interface EventMap {
+ data: PayloadMessage;
+ status: StatusMessage;
+ log: LogMessage;
+ render: RenderMessage;
+}
+
+export type GradioEvent = {
+ [P in EventType]: EventMap[P];
+}[EventType];
+
+export interface Log {
+ log: string;
+ level: "warning" | "info";
+}
+export interface Render {
+ data: {
+ components: any[];
+ layout: any;
+ dependencies: Dependency[];
+ render_id: number;
+ };
+}
+
export interface Status {
queue: boolean;
code?: string;
@@ -57,63 +342,29 @@ export interface Status {
desc: string | null;
}[];
time?: Date;
+ changed_state_ids?: number[];
}
-export interface LogMessage {
- log: string;
- level: "warning" | "info";
+export interface StatusMessage extends Status {
+ type: "status";
+ endpoint: string;
+ fn_index: number;
}
-export interface SpaceStatusNormal {
- status: "sleeping" | "running" | "building" | "error" | "stopped";
- detail:
- | "SLEEPING"
- | "RUNNING"
- | "RUNNING_BUILDING"
- | "BUILDING"
- | "NOT_FOUND";
- load_status: "pending" | "error" | "complete" | "generating";
- message: string;
+export interface PayloadMessage extends Payload {
+ type: "data";
+ endpoint: string;
+ fn_index: number;
}
-export interface SpaceStatusError {
- status: "space_error" | "paused";
- detail:
- | "NO_APP_FILE"
- | "CONFIG_ERROR"
- | "BUILD_ERROR"
- | "RUNTIME_ERROR"
- | "PAUSED";
- load_status: "error";
- message: string;
- discussions_enabled: boolean;
-}
-export type SpaceStatus = SpaceStatusNormal | SpaceStatusError;
-
-export type status_callback_function = (a: Status) => void;
-export type SpaceStatusCallback = (a: SpaceStatus) => void;
-
-export type EventType = "data" | "status" | "log";
-export interface EventMap {
- data: Payload;
- status: Status;
- log: LogMessage;
+export interface LogMessage extends Log {
+ type: "log";
+ endpoint: string;
+ fn_index: number;
}
-export type Event = {
- [P in K]: EventMap[P] & { type: P; endpoint: string; fn_index: number };
-}[K];
-export type EventListener = (event: Event) => void;
-export type ListenerMap = {
- [P in K]?: EventListener[];
-};
-export interface FileData {
- name: string;
- orig_name?: string;
- size?: number;
- data: string;
- blob?: File;
- is_file?: boolean;
- mime_type?: string;
- alt_text?: string;
+export interface RenderMessage extends Render {
+ type: "render";
+ endpoint: string;
+ fn_index: number;
}
diff --git a/node_modules/@gradio/client/src/upload.ts b/node_modules/@gradio/client/src/upload.ts
index f5011710ae69b994c3dedd6f43402e6f630a15c8..0dfe714f7da6ad8e2743ecd895cbd3e1d937c25a 100644
--- a/node_modules/@gradio/client/src/upload.ts
+++ b/node_modules/@gradio/client/src/upload.ts
@@ -1,111 +1,42 @@
-import { upload_files } from "./client";
-
-export function normalise_file(
- file: FileData | null,
- server_url: string,
- proxy_url: string | null
-): FileData | null;
-
-export function normalise_file(
- file: FileData[] | null,
- server_url: string,
- proxy_url: string | null
-): FileData[] | null;
-
-export function normalise_file(
- file: FileData[] | FileData | null,
- server_url: string, // root: string,
- proxy_url: string | null // root_url: string | null
-): FileData[] | FileData | null;
-
-export function normalise_file(
- file: FileData[] | FileData | null,
- server_url: string, // root: string,
- proxy_url: string | null // root_url: string | null
-): FileData[] | FileData | null {
- if (file == null) {
- return null;
- }
-
- if (Array.isArray(file)) {
- const normalized_file: (FileData | null)[] = [];
-
- for (const x of file) {
- if (x == null) {
- normalized_file.push(null);
- } else {
- normalized_file.push(normalise_file(x, server_url, proxy_url));
- }
- }
-
- return normalized_file as FileData[];
- }
-
- if (file.is_stream) {
- if (proxy_url == null) {
- return new FileData({
- ...file,
- url: server_url + "/stream/" + file.path
- });
- }
- return new FileData({
- ...file,
- url: "/proxy=" + proxy_url + "stream/" + file.path
- });
- }
-
- return new FileData({
- ...file,
- url: get_fetchable_url_or_file(file.path, server_url, proxy_url)
- });
-}
-
-function is_url(str: string): boolean {
- try {
- const url = new URL(str);
- return url.protocol === "http:" || url.protocol === "https:";
- } catch {
- return false;
- }
-}
-
-export function get_fetchable_url_or_file(
- path: string | null,
- server_url: string,
- proxy_url: string | null
-): string {
- if (path == null) {
- return proxy_url ? `/proxy=${proxy_url}file=` : `${server_url}/file=`;
- }
- if (is_url(path)) {
- return path;
- }
- return proxy_url
- ? `/proxy=${proxy_url}file=${path}`
- : `${server_url}/file=${path}`;
-}
+import type { UploadResponse } from "./types";
+import type { Client } from "./client";
export async function upload(
+ this: Client,
file_data: FileData[],
- root: string,
+ root_url: string,
upload_id?: string,
- upload_fn: typeof upload_files = upload_files
+ max_file_size?: number
): Promise<(FileData | null)[] | null> {
let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
(file_data) => file_data.blob!
);
+ const oversized_files = files.filter(
+ (f) => f.size > (max_file_size ?? Infinity)
+ );
+ if (oversized_files.length) {
+ throw new Error(
+ `File size exceeds the maximum allowed size of ${max_file_size} bytes: ${oversized_files
+ .map((f) => f.name)
+ .join(", ")}`
+ );
+ }
+
return await Promise.all(
- await upload_fn(root, files, undefined, upload_id).then(
+ await this.upload_files(root_url, files, upload_id).then(
async (response: { files?: string[]; error?: string }) => {
if (response.error) {
throw new Error(response.error);
} else {
if (response.files) {
return response.files.map((f, i) => {
- const file = new FileData({ ...file_data[i], path: f });
-
- return normalise_file(file, root, null);
+ const file = new FileData({
+ ...file_data[i],
+ path: f,
+ url: root_url + "/file=" + f
+ });
+ return file;
});
}
@@ -121,7 +52,7 @@ export async function prepare_files(
is_stream?: boolean
): Promise {
return files.map(
- (f, i) =>
+ (f) =>
new FileData({
path: f.name,
orig_name: f.name,
@@ -142,6 +73,7 @@ export class FileData {
is_stream?: boolean;
mime_type?: string;
alt_text?: string;
+ readonly meta = { _type: "gradio.FileData" };
constructor({
path,
diff --git a/node_modules/@gradio/client/src/utils.ts b/node_modules/@gradio/client/src/utils.ts
deleted file mode 100644
index 5883cfe0b16c9cc0920c25efabe232ad5529a70c..0000000000000000000000000000000000000000
--- a/node_modules/@gradio/client/src/utils.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-import type { Config } from "./types.js";
-
-/**
- * This function is used to resolve the URL for making requests when the app has a root path.
- * The root path could be a path suffix like "/app" which is appended to the end of the base URL. Or
- * it could be a full URL like "https://abidlabs-test-client-replica--gqf2x.hf.space" which is used when hosting
- * Gradio apps on Hugging Face Spaces.
- * @param {string} base_url The base URL at which the Gradio server is hosted
- * @param {string} root_path The root path, which could be a path suffix (e.g. mounted in FastAPI app) or a full URL (e.g. hosted on Hugging Face Spaces)
- * @param {boolean} prioritize_base Whether to prioritize the base URL over the root path. This is used when both the base path and root paths are full URLs. For example, for fetching files the root path should be prioritized, but for making requests, the base URL should be prioritized.
- * @returns {string} the resolved URL
- */
-export function resolve_root(
- base_url: string,
- root_path: string,
- prioritize_base: boolean
-): string {
- if (root_path.startsWith("http://") || root_path.startsWith("https://")) {
- return prioritize_base ? base_url : root_path;
- }
- return base_url + root_path;
-}
-
-export function determine_protocol(endpoint: string): {
- ws_protocol: "ws" | "wss";
- http_protocol: "http:" | "https:";
- host: string;
-} {
- if (endpoint.startsWith("http")) {
- const { protocol, host } = new URL(endpoint);
-
- if (host.endsWith("hf.space")) {
- return {
- ws_protocol: "wss",
- host: host,
- http_protocol: protocol as "http:" | "https:"
- };
- }
- return {
- ws_protocol: protocol === "https:" ? "wss" : "ws",
- http_protocol: protocol as "http:" | "https:",
- host
- };
- } else if (endpoint.startsWith("file:")) {
- // This case is only expected to be used for the Wasm mode (Gradio-lite),
- // where users can create a local HTML file using it and open the page in a browser directly via the `file:` protocol.
- return {
- ws_protocol: "ws",
- http_protocol: "http:",
- host: "lite.local" // Special fake hostname only used for this case. This matches the hostname allowed in `is_self_host()` in `js/wasm/network/host.ts`.
- };
- }
-
- // default to secure if no protocol is provided
- return {
- ws_protocol: "wss",
- http_protocol: "https:",
- host: endpoint
- };
-}
-
-export const RE_SPACE_NAME = /^[^\/]*\/[^\/]*$/;
-export const RE_SPACE_DOMAIN = /.*hf\.space\/{0,1}$/;
-export async function process_endpoint(
- app_reference: string,
- token?: `hf_${string}`
-): Promise<{
- space_id: string | false;
- host: string;
- ws_protocol: "ws" | "wss";
- http_protocol: "http:" | "https:";
-}> {
- const headers: { Authorization?: string } = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
-
- const _app_reference = app_reference.trim();
-
- if (RE_SPACE_NAME.test(_app_reference)) {
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${_app_reference}/host`,
- { headers }
- );
-
- if (res.status !== 200)
- throw new Error("Space metadata could not be loaded.");
- const _host = (await res.json()).host;
-
- return {
- space_id: app_reference,
- ...determine_protocol(_host)
- };
- } catch (e: any) {
- throw new Error("Space metadata could not be loaded." + e.message);
- }
- }
-
- if (RE_SPACE_DOMAIN.test(_app_reference)) {
- const { ws_protocol, http_protocol, host } =
- determine_protocol(_app_reference);
-
- return {
- space_id: host.replace(".hf.space", ""),
- ws_protocol,
- http_protocol,
- host
- };
- }
-
- return {
- space_id: false,
- ...determine_protocol(_app_reference)
- };
-}
-
-export function map_names_to_ids(
- fns: Config["dependencies"]
-): Record {
- let apis: Record = {};
-
- fns.forEach(({ api_name }, i) => {
- if (api_name) apis[api_name] = i;
- });
-
- return apis;
-}
-
-const RE_DISABLED_DISCUSSION =
- /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
-export async function discussions_enabled(space_id: string): Promise {
- try {
- const r = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/discussions`,
- {
- method: "HEAD"
- }
- );
- const error = r.headers.get("x-error-message");
-
- if (error && RE_DISABLED_DISCUSSION.test(error)) return false;
- return true;
- } catch (e) {
- return false;
- }
-}
-
-export async function get_space_hardware(
- space_id: string,
- token: `hf_${string}`
-): Promise<(typeof hardware_types)[number]> {
- const headers: { Authorization?: string } = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
-
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/runtime`,
- { headers }
- );
-
- if (res.status !== 200)
- throw new Error("Space hardware could not be obtained.");
-
- const { hardware } = await res.json();
-
- return hardware;
- } catch (e: any) {
- throw new Error(e.message);
- }
-}
-
-export async function set_space_hardware(
- space_id: string,
- new_hardware: (typeof hardware_types)[number],
- token: `hf_${string}`
-): Promise<(typeof hardware_types)[number]> {
- const headers: { Authorization?: string } = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
-
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/hardware`,
- { headers, body: JSON.stringify(new_hardware) }
- );
-
- if (res.status !== 200)
- throw new Error(
- "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in."
- );
-
- const { hardware } = await res.json();
-
- return hardware;
- } catch (e: any) {
- throw new Error(e.message);
- }
-}
-
-export async function set_space_timeout(
- space_id: string,
- timeout: number,
- token: `hf_${string}`
-): Promise {
- const headers: { Authorization?: string } = {};
- if (token) {
- headers.Authorization = `Bearer ${token}`;
- }
-
- try {
- const res = await fetch(
- `https://huggingface.co/api/spaces/${space_id}/hardware`,
- { headers, body: JSON.stringify({ seconds: timeout }) }
- );
-
- if (res.status !== 200)
- throw new Error(
- "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in."
- );
-
- const { hardware } = await res.json();
-
- return hardware;
- } catch (e: any) {
- throw new Error(e.message);
- }
-}
-
-export const hardware_types = [
- "cpu-basic",
- "cpu-upgrade",
- "t4-small",
- "t4-medium",
- "a10g-small",
- "a10g-large",
- "a100-large"
-] as const;
diff --git a/node_modules/@gradio/client/src/utils/duplicate.ts b/node_modules/@gradio/client/src/utils/duplicate.ts
new file mode 100644
index 0000000000000000000000000000000000000000..27cecd3ffbce98b52a9f04b744012fb5ea291ba5
--- /dev/null
+++ b/node_modules/@gradio/client/src/utils/duplicate.ts
@@ -0,0 +1,129 @@
+import {
+ get_space_hardware,
+ hardware_types,
+ set_space_timeout
+} from "../helpers/spaces";
+import type { DuplicateOptions } from "../types";
+import { Client } from "../client";
+import { SPACE_METADATA_ERROR_MSG } from "../constants";
+import {
+ get_cookie_header,
+ parse_and_set_cookies
+} from "../helpers/init_helpers";
+import { process_endpoint } from "../helpers/api_info";
+
+export async function duplicate(
+ app_reference: string,
+ options: DuplicateOptions
+): Promise {
+ const { hf_token, private: _private, hardware, timeout, auth } = options;
+
+ if (hardware && !hardware_types.includes(hardware)) {
+ throw new Error(
+ `Invalid hardware type provided. Valid types are: ${hardware_types
+ .map((v) => `"${v}"`)
+ .join(",")}.`
+ );
+ }
+
+ const { http_protocol, host } = await process_endpoint(
+ app_reference,
+ hf_token
+ );
+
+ let cookies: string[] | null = null;
+
+ if (auth) {
+ const cookie_header = await get_cookie_header(
+ http_protocol,
+ host,
+ auth,
+ fetch
+ );
+
+ if (cookie_header) cookies = parse_and_set_cookies(cookie_header);
+ }
+
+ const headers = {
+ Authorization: `Bearer ${hf_token}`,
+ "Content-Type": "application/json",
+ ...(cookies ? { Cookie: cookies.join("; ") } : {})
+ };
+
+ const user = (
+ await (
+ await fetch(`https://huggingface.co/api/whoami-v2`, {
+ headers
+ })
+ ).json()
+ ).name;
+
+ const space_name = app_reference.split("/")[1];
+ const body: {
+ repository: string;
+ private?: boolean;
+ hardware?: string;
+ } = {
+ repository: `${user}/${space_name}`
+ };
+
+ if (_private) {
+ body.private = true;
+ }
+
+ let original_hardware;
+
+ try {
+ if (!hardware) {
+ original_hardware = await get_space_hardware(app_reference, hf_token);
+ }
+ } catch (e) {
+ throw Error(SPACE_METADATA_ERROR_MSG + (e as Error).message);
+ }
+
+ const requested_hardware = hardware || original_hardware || "cpu-basic";
+
+ body.hardware = requested_hardware;
+
+ try {
+ const response = await fetch(
+ `https://huggingface.co/api/spaces/${app_reference}/duplicate`,
+ {
+ method: "POST",
+ headers,
+ body: JSON.stringify(body)
+ }
+ );
+
+ if (response.status === 409) {
+ try {
+ const client = await Client.connect(`${user}/${space_name}`, options);
+ return client;
+ } catch (error) {
+ console.error("Failed to connect Client instance:", error);
+ throw error;
+ }
+ } else if (response.status !== 200) {
+ throw new Error(response.statusText);
+ }
+
+ const duplicated_space = await response.json();
+
+ await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
+
+ return await Client.connect(
+ get_space_reference(duplicated_space.url),
+ options
+ );
+ } catch (e: any) {
+ throw new Error(e);
+ }
+}
+
+function get_space_reference(url: string): any {
+ const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
+ const match = url.match(regex);
+ if (match) {
+ return match[1];
+ }
+}
diff --git a/node_modules/@gradio/client/src/utils/handle_blob.ts b/node_modules/@gradio/client/src/utils/handle_blob.ts
new file mode 100644
index 0000000000000000000000000000000000000000..54c164887b84c492c47aca30d4d2733254e10c37
--- /dev/null
+++ b/node_modules/@gradio/client/src/utils/handle_blob.ts
@@ -0,0 +1,137 @@
+import { update_object, walk_and_store_blobs } from "../helpers/data";
+import {
+ Command,
+ type ApiData,
+ type EndpointInfo,
+ type JsApiData
+} from "../types";
+import { FileData } from "../upload";
+import type { Client } from "..";
+import {
+ FILE_PROCESSING_ERROR_MSG,
+ NODEJS_FS_ERROR_MSG,
+ ROOT_URL_ERROR_MSG
+} from "../constants";
+
+export async function handle_blob(
+ this: Client,
+ endpoint: string,
+ data: unknown[],
+ api_info: EndpointInfo
+): Promise {
+ const self = this;
+
+ await process_local_file_commands(self, data);
+
+ const blobRefs = await walk_and_store_blobs(
+ data,
+ undefined,
+ [],
+ true,
+ api_info
+ );
+
+ const results = await Promise.all(
+ blobRefs.map(async ({ path, blob, type }) => {
+ if (!blob) return { path, type };
+
+ const response = await self.upload_files(endpoint, [blob]);
+ const file_url = response.files && response.files[0];
+ return {
+ path,
+ file_url,
+ type,
+ name: blob instanceof File ? blob?.name : undefined
+ };
+ })
+ );
+
+ results.forEach(({ path, file_url, type, name }) => {
+ if (type === "Gallery") {
+ update_object(data, file_url, path);
+ } else if (file_url) {
+ const file = new FileData({ path: file_url, orig_name: name });
+ update_object(data, file, path);
+ }
+ });
+
+ return data;
+}
+
+export async function process_local_file_commands(
+ client: Client,
+ data: unknown[]
+): Promise {
+ const root = client.config?.root || client.config?.root_url;
+
+ if (!root) {
+ throw new Error(ROOT_URL_ERROR_MSG);
+ }
+
+ await recursively_process_commands(client, data);
+}
+
+async function recursively_process_commands(
+ client: Client,
+ data: any,
+ path: string[] = []
+): Promise {
+ for (const key in data) {
+ if (data[key] instanceof Command) {
+ await process_single_command(client, data, key);
+ } else if (typeof data[key] === "object" && data[key] !== null) {
+ await recursively_process_commands(client, data[key], [...path, key]);
+ }
+ }
+}
+
+async function process_single_command(
+ client: Client,
+ data: any,
+ key: string
+): Promise {
+ let cmd_item = data[key] as Command;
+ const root = client.config?.root || client.config?.root_url;
+
+ if (!root) {
+ throw new Error(ROOT_URL_ERROR_MSG);
+ }
+
+ try {
+ let fileBuffer: Buffer;
+ let fullPath: string;
+
+ // check if running in a Node.js environment
+ if (
+ typeof process !== "undefined" &&
+ process.versions &&
+ process.versions.node
+ ) {
+ const fs = await import("fs/promises");
+ const path = await import("path");
+
+ fullPath = path.resolve(process.cwd(), cmd_item.meta.path);
+ fileBuffer = await fs.readFile(fullPath); // Read file from disk
+ } else {
+ throw new Error(NODEJS_FS_ERROR_MSG);
+ }
+
+ const file = new Blob([fileBuffer], { type: "application/octet-stream" });
+
+ const response = await client.upload_files(root, [file]);
+
+ const file_url = response.files && response.files[0];
+
+ if (file_url) {
+ const fileData = new FileData({
+ path: file_url,
+ orig_name: cmd_item.meta.name || ""
+ });
+
+ // replace the command object with the fileData object
+ data[key] = fileData;
+ }
+ } catch (error) {
+ console.error(FILE_PROCESSING_ERROR_MSG, error);
+ }
+}
diff --git a/node_modules/@gradio/client/src/utils/post_data.ts b/node_modules/@gradio/client/src/utils/post_data.ts
new file mode 100644
index 0000000000000000000000000000000000000000..53264a3c86f3083df3ff336c867b697e20a3f69e
--- /dev/null
+++ b/node_modules/@gradio/client/src/utils/post_data.ts
@@ -0,0 +1,38 @@
+import { BROKEN_CONNECTION_MSG } from "../constants";
+import type { PostResponse } from "../types";
+import { Client } from "..";
+
+export async function post_data(
+ this: Client,
+ url: string,
+ body: unknown,
+ additional_headers?: any
+): Promise<[PostResponse, number]> {
+ const headers: {
+ Authorization?: string;
+ "Content-Type": "application/json";
+ } = { "Content-Type": "application/json" };
+ if (this.options.hf_token) {
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
+ }
+ try {
+ var response = await this.fetch(url, {
+ method: "POST",
+ body: JSON.stringify(body),
+ headers: { ...headers, ...additional_headers },
+ credentials: "include"
+ });
+ } catch (e) {
+ return [{ error: BROKEN_CONNECTION_MSG }, 500];
+ }
+ let output: PostResponse;
+ let status: number;
+ try {
+ output = await response.json();
+ status = response.status;
+ } catch (e) {
+ output = { error: `Could not parse server response: ${e}` };
+ status = 500;
+ }
+ return [output, status];
+}
diff --git a/node_modules/@gradio/client/src/utils/predict.ts b/node_modules/@gradio/client/src/utils/predict.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0d5121123cc3e08b4008ae9099321e7ba81b2cc0
--- /dev/null
+++ b/node_modules/@gradio/client/src/utils/predict.ts
@@ -0,0 +1,57 @@
+import { Client } from "../client";
+import type { Dependency, PredictReturn } from "../types";
+
+export async function predict(
+ this: Client,
+ endpoint: string | number,
+ data: unknown[] | Record
+): Promise {
+ let data_returned = false;
+ let status_complete = false;
+ let dependency: Dependency;
+
+ if (!this.config) {
+ throw new Error("Could not resolve app config");
+ }
+
+ if (typeof endpoint === "number") {
+ dependency = this.config.dependencies.find((dep) => dep.id == endpoint)!;
+ } else {
+ const trimmed_endpoint = endpoint.replace(/^\//, "");
+ dependency = this.config.dependencies.find(
+ (dep) => dep.id == this.api_map[trimmed_endpoint]
+ )!;
+ }
+
+ if (dependency?.types.continuous) {
+ throw new Error(
+ "Cannot call predict on this function as it may run forever. Use submit instead"
+ );
+ }
+
+ return new Promise(async (resolve, reject) => {
+ const app = this.submit(endpoint, data, null, null, true);
+ let result: unknown;
+
+ for await (const message of app) {
+ if (message.type === "data") {
+ if (status_complete) {
+ resolve(result as PredictReturn);
+ }
+ data_returned = true;
+ result = message;
+ }
+
+ if (message.type === "status") {
+ if (message.stage === "error") reject(message);
+ if (message.stage === "complete") {
+ status_complete = true;
+ // if complete message comes after data, resolve here
+ if (data_returned) {
+ resolve(result as PredictReturn);
+ }
+ }
+ }
+ }
+ });
+}
diff --git a/node_modules/@gradio/client/src/utils/stream.ts b/node_modules/@gradio/client/src/utils/stream.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e47bb6fad5268270d6e52e601213d304b9701d77
--- /dev/null
+++ b/node_modules/@gradio/client/src/utils/stream.ts
@@ -0,0 +1,228 @@
+import { BROKEN_CONNECTION_MSG } from "../constants";
+import type { Client } from "../client";
+import { stream } from "fetch-event-stream";
+
+export async function open_stream(this: Client): Promise {
+ let {
+ event_callbacks,
+ unclosed_events,
+ pending_stream_messages,
+ stream_status,
+ config,
+ jwt
+ } = this;
+
+ const that = this;
+
+ if (!config) {
+ throw new Error("Could not resolve app config");
+ }
+
+ stream_status.open = true;
+
+ let stream: EventSource | null = null;
+ let params = new URLSearchParams({
+ session_hash: this.session_hash
+ }).toString();
+
+ let url = new URL(`${config.root}/queue/data?${params}`);
+
+ if (jwt) {
+ url.searchParams.set("__sign", jwt);
+ }
+
+ stream = this.stream(url);
+
+ if (!stream) {
+ console.warn("Cannot connect to SSE endpoint: " + url.toString());
+ return;
+ }
+
+ stream.onmessage = async function (event: MessageEvent) {
+ let _data = JSON.parse(event.data);
+ if (_data.msg === "close_stream") {
+ close_stream(stream_status, that.abort_controller);
+ return;
+ }
+ const event_id = _data.event_id;
+ if (!event_id) {
+ await Promise.all(
+ Object.keys(event_callbacks).map((event_id) =>
+ event_callbacks[event_id](_data)
+ )
+ );
+ } else if (event_callbacks[event_id] && config) {
+ if (
+ _data.msg === "process_completed" &&
+ ["sse", "sse_v1", "sse_v2", "sse_v2.1", "sse_v3"].includes(
+ config.protocol
+ )
+ ) {
+ unclosed_events.delete(event_id);
+ }
+ let fn: (data: any) => void = event_callbacks[event_id];
+
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
+ // fn(_data); // need to do this to put the event on the end of the event loop, so the browser can refresh between callbacks and not freeze in case of quick generations. See
+ setTimeout(fn, 0, _data); // need to do this to put the event on the end of the event loop, so the browser can refresh between callbacks and not freeze in case of quick generations. See https://github.com/gradio-app/gradio/pull/7055
+ } else {
+ fn(_data);
+ }
+ } else {
+ if (!pending_stream_messages[event_id]) {
+ pending_stream_messages[event_id] = [];
+ }
+ pending_stream_messages[event_id].push(_data);
+ }
+ };
+ stream.onerror = async function () {
+ await Promise.all(
+ Object.keys(event_callbacks).map((event_id) =>
+ event_callbacks[event_id]({
+ msg: "unexpected_error",
+ message: BROKEN_CONNECTION_MSG
+ })
+ )
+ );
+ };
+}
+
+export function close_stream(
+ stream_status: { open: boolean },
+ abort_controller: AbortController | null
+): void {
+ if (stream_status) {
+ stream_status.open = false;
+ abort_controller?.abort();
+ }
+}
+
+export function apply_diff_stream(
+ pending_diff_streams: Record,
+ event_id: string,
+ data: any
+): void {
+ let is_first_generation = !pending_diff_streams[event_id];
+ if (is_first_generation) {
+ pending_diff_streams[event_id] = [];
+ data.data.forEach((value: any, i: number) => {
+ pending_diff_streams[event_id][i] = value;
+ });
+ } else {
+ data.data.forEach((value: any, i: number) => {
+ let new_data = apply_diff(pending_diff_streams[event_id][i], value);
+ pending_diff_streams[event_id][i] = new_data;
+ data.data[i] = new_data;
+ });
+ }
+}
+
+export function apply_diff(
+ obj: any,
+ diff: [string, (number | string)[], any][]
+): any {
+ diff.forEach(([action, path, value]) => {
+ obj = apply_edit(obj, path, action, value);
+ });
+
+ return obj;
+}
+
+function apply_edit(
+ target: any,
+ path: (number | string)[],
+ action: string,
+ value: any
+): any {
+ if (path.length === 0) {
+ if (action === "replace") {
+ return value;
+ } else if (action === "append") {
+ return target + value;
+ }
+ throw new Error(`Unsupported action: ${action}`);
+ }
+
+ let current = target;
+ for (let i = 0; i < path.length - 1; i++) {
+ current = current[path[i]];
+ }
+
+ const last_path = path[path.length - 1];
+ switch (action) {
+ case "replace":
+ current[last_path] = value;
+ break;
+ case "append":
+ current[last_path] += value;
+ break;
+ case "add":
+ if (Array.isArray(current)) {
+ current.splice(Number(last_path), 0, value);
+ } else {
+ current[last_path] = value;
+ }
+ break;
+ case "delete":
+ if (Array.isArray(current)) {
+ current.splice(Number(last_path), 1);
+ } else {
+ delete current[last_path];
+ }
+ break;
+ default:
+ throw new Error(`Unknown action: ${action}`);
+ }
+ return target;
+}
+
+export function readable_stream(
+ input: RequestInfo | URL,
+ init: RequestInit = {}
+): EventSource {
+ const instance: EventSource & { readyState: number } = {
+ close: () => {
+ throw new Error("Method not implemented.");
+ },
+ onerror: null,
+ onmessage: null,
+ onopen: null,
+ readyState: 0,
+ url: input.toString(),
+ withCredentials: false,
+ CONNECTING: 0,
+ OPEN: 1,
+ CLOSED: 2,
+ addEventListener: () => {
+ throw new Error("Method not implemented.");
+ },
+ dispatchEvent: () => {
+ throw new Error("Method not implemented.");
+ },
+ removeEventListener: () => {
+ throw new Error("Method not implemented.");
+ }
+ };
+
+ stream(input, init)
+ .then(async (res) => {
+ instance.readyState = instance.OPEN;
+ try {
+ for await (const chunk of res) {
+ //@ts-ignore
+ instance.onmessage && instance.onmessage(chunk);
+ }
+ instance.readyState = instance.CLOSED;
+ } catch (e) {
+ instance.onerror && instance.onerror(e as Event);
+ instance.readyState = instance.CLOSED;
+ }
+ })
+ .catch((e) => {
+ console.error(e);
+ instance.onerror && instance.onerror(e as Event);
+ instance.readyState = instance.CLOSED;
+ });
+
+ return instance as EventSource;
+}
diff --git a/node_modules/@gradio/client/src/utils/submit.ts b/node_modules/@gradio/client/src/utils/submit.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b2c02b314932abba420d965708a2e87cf79245ff
--- /dev/null
+++ b/node_modules/@gradio/client/src/utils/submit.ts
@@ -0,0 +1,838 @@
+/* eslint-disable complexity */
+import type {
+ Status,
+ Payload,
+ GradioEvent,
+ JsApiData,
+ EndpointInfo,
+ ApiInfo,
+ Config,
+ Dependency,
+ SubmitIterable
+} from "../types";
+
+import { skip_queue, post_message, handle_payload } from "../helpers/data";
+import { resolve_root } from "../helpers/init_helpers";
+import {
+ handle_message,
+ map_data_to_params,
+ process_endpoint
+} from "../helpers/api_info";
+import semiver from "semiver";
+import { BROKEN_CONNECTION_MSG, QUEUE_FULL_MSG } from "../constants";
+import { apply_diff_stream, close_stream } from "./stream";
+import { Client } from "../client";
+
+export function submit(
+ this: Client,
+ endpoint: string | number,
+ data: unknown[] | Record