-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor JS Client #7646
Refactor JS Client #7646
Conversation
🪼 branch checks and previews
Install Gradio from this PR pip install https://gradio-builds.s3.amazonaws.com/c094ed7ef4f2f58c516d6fdd2182ed48141de17a/gradio-4.27.0-py3-none-any.whl Install Gradio Python Client from this PR pip install "gradio-client @ git+https://github.com/gradio-app/gradio@c094ed7ef4f2f58c516d6fdd2182ed48141de17a#subdirectory=client/python" |
🦄 change detectedThis Pull Request includes changes to the following packages.
With the following changelog entry.
Maintainers or the PR author can modify the PR title to modify this entry.
|
…into refactor-client
@hannahblair We chatted about this in retro and we agreed that option 3 was probably preferable: const app = await Client.create(); The reasoning was as follows:
I think we are good to finish this off in that direction. |
@hannahblair could we update the docs here: https://www.gradio.app/guides/getting-started-with-the-js-client as well? |
I've got a separate PR with docs changes in #8003. It's actually branching off this PR so if that's approved (and I've fixed those conflicts) I can merge it into this one. |
Awesome PR @hannahblair. I tested a lot of Gradio, only 2 things I noticed: (1) The ![]() Locally, I see this error printed in the console:
Seems like maybe there's a conflict between recent changes to the ImageEditor and this client refactor PR. (2) This is not super urgent, but if you look at the view API page for any endpoint that involves uploading a file, the file dictionary in the payload is very complex, e.g.: ![]() This is the dict for a single file: {"path":"https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf","meta":{"_type":"gradio.FileData"},"orig_name":"sample_file.pdf","url":"https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf"} This is technically correct, but it would be nice to wrap this in a helper function so users don't have to think about all of the fields. For the Python Client, we have a I'm about to test some Gradio-Lite demos, will let you know if I see anything else. But so far, everything else works perfectly! |
Tested a few Gradio/Lite demos and they are working well from what I can tell! |
…into refactor-client
* update client examples * remove test data * fix types * remove types changes * client -> Client.create * Update client/js/README.md Co-authored-by: Abubakar Abid <abubakar@huggingface.co> * Update client/js/README.md Co-authored-by: Abubakar Abid <abubakar@huggingface.co> * update duplicate docs * attempt to update cn docs * format --------- Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
thanks for testing @abidlabs! fixed the image editor issue. good catch. agree with your point about the view api docs - i'll fix this in a separate PR if that's all good |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM @hannahblair! This PR's good stuff
agree with your point about the view api docs - i'll fix this in a separate PR if that's all good
👍 I'll create an issue so we catch it before the 1.0 release
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome stuff! Good to merge imo. Thanks for taking this one on @hannahblair!
Refactoring our Client from a giant function to a cleaner, more readable, fully typed Class constructor has meant that we need to change the way we initialise an instance of the client.
To create an instance of the client, we write the following:
const app = await Client.create("hmb/whisper")
Description
@ts-nocheck
sclient/js/README
and website docs with new usage pattern (UpdateClient
usage examples #8003)sse_v2.1
andsse_v3
to protocol listTesting
view_api
,predict
(with files and primitive types) (with and without endpoint param)submit
, (on
,off
,cancel
,destroy
), `duplicate
Closes:
🎯 PRs Should Target Issues
Before your create a PR, please check to see if there is an existing issue for this change. If not, please create an issue before you create this PR, unless the fix is very small.
Not adhering to this guideline will result in the PR being closed.
Tests
PRs will only be merged if tests pass on CI. To run the tests locally, please set up your Gradio environment locally and run the tests:
bash scripts/run_all_tests.sh
You may need to run the linters:
bash scripts/format_backend.sh
andbash scripts/format_frontend.sh
🗑️ Outdated Description 🗑️
The reason why we can't simply initialise an app via a Class Constructor is because we need to fetch certain values (
config
,api
,api_map
etc) via asynchronous functions when an instance of the client is created, and a TS constructor cannot be async (perhaps without a janky workaround). So we need to decide on a new usage pattern.We've got a few options:
Add
ready
to the client; aPromise
that resolves when the client is fully initialised. Implement an event listener for aready
event on the client. When theready
event is emitted by the client instance, the callback function provided will be executedNice article here
init()
functionAdd an
init()
function (with the async initialisation logic) which the user manually calls andawait
sEssentially uses a function like init() in option 2 but encapsulates this in a create() function so it can be used in one line
Initial thoughts:
@pngwn
app.on('ready', () => {...})
is a common pattern, technically most "correct", it also echoes other parts of the API, event driven, with the caveat of the api syntax@hannahblair
await new Client()
->await new Client.create()
Note: We already have the initialisation logic in place in the Client, and going ahead with any of the other two options won't mean too much work; just moving some code around a bit. This is just a matter of what pattern is most ideal.