gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
31.98k stars 2.38k forks source link

gradio_pdf component in private space not usable from public space #8674

Open ploncker opened 2 months ago

ploncker commented 2 months ago

Describe the bug

I think this is source of the problem:

Traceback (most recent call last): File "/home/user/app/app.py", line 17, in demo = gr.load("ploncker/emma", hf_token=key, src="spaces") File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 60, in load return load_blocks_from_repo( File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 99, in load_blocks_from_repo blocks: gradio.Blocks = factory_methods[src](name, hf_token, alias, **kwargs) File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 436, in from_spaces return from_spaces_blocks(space=space_name, hf_token=hf_token) File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 467, in from_spaces_blocks return gradio.Blocks.from_config(client.config, predict_fns, client.src) File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1186, in from_config iterate_over_children(config["layout"]["children"]) File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1178, in iterate_over_children iterate_over_children(children) File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1178, in iterate_over_children iterate_over_children(children) File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1167, in iterate_over_children block = get_block_instance(id) File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1140, in get_block_instance cls = component_or_layout_class(block_config["props"]["name"]) File "/usr/local/lib/python3.10/site-packages/gradio/utils.py", line 595, in component_or_layout_class raise ValueError( ValueError: No such component or layout: pdf. It is possible it is a custom component, in which case make sure it is installed and imported in your python session.

The only way to get rid of this error is to import PDF in the public space like so:

import os import gradio as gr from gradio_pdf import PDF key = os.environ['MY_TOKEN'] demo = gr.load("ploncker/emma", hf_token=key, src="spaces") demo.launch() But doing this means the PDF of the public space is used rather than the private space (guessing) So how does one fix the error in the public space:

ValueError: No such component or layout: pdf. It is possible it is a custom component, in which case make sure it is installed and imported in your python session. for the gradio_pdf component??

Have you searched existing issues? πŸ”Ž

Reproduction

private space

import os
import gradio as gr
from gradio_pdf import PDF
with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=2, min_width=600):
            pdf = PDF(label="Upload a PDF", scale = 1, min_width=800, interactive=True)
            name = gr.Textbox(type='text', visible=True)
            pdf.upload(lambda f: f, pdf, name)

public space

import os
import gradio as gr
from gradio_pdf import PDF
key = os.environ['MY_TOKEN']
demo = gr.load("ploncker/emma", hf_token=key, src="spaces")
demo.launch()

Screenshot

No response

Logs

===== Application Startup at 2024-07-01 06:13:28 =====

Fetching Space from: https://huggingface.co/spaces/ploncker/emma
Loaded as API: https://ploncker-emma.hf.space βœ”
Traceback (most recent call last):
  File "/home/user/app/app.py", line 17, in <module>
    demo = gr.load("ploncker/emma", hf_token=key, src="spaces")
  File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 60, in load
    return load_blocks_from_repo(
  File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 99, in load_blocks_from_repo
    blocks: gradio.Blocks = factory_methods[src](name, hf_token, alias, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 436, in from_spaces
    return from_spaces_blocks(space=space_name, hf_token=hf_token)
  File "/usr/local/lib/python3.10/site-packages/gradio/external.py", line 467, in from_spaces_blocks
    return gradio.Blocks.from_config(client.config, predict_fns, client.src)
  File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1186, in from_config
    iterate_over_children(config["layout"]["children"])
  File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1178, in iterate_over_children
    iterate_over_children(children)
  File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1178, in iterate_over_children
    iterate_over_children(children)
  File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1167, in iterate_over_children
    block = get_block_instance(id)
  File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 1140, in get_block_instance
    cls = component_or_layout_class(block_config["props"]["name"])
  File "/usr/local/lib/python3.10/site-packages/gradio/utils.py", line 595, in component_or_layout_class
    raise ValueError(
ValueError: No such component or layout: pdf. It is possible it is a custom component, in which case make sure it is installed and imported in your python session.

System Info

hosted in spaces

Severity

I can work around it

abidlabs commented 2 months ago

Hi @ploncker this is the intended behavior. When you do gr.load(), Gradio reconstructs the demo for you locally using the UI components, styling, and version of the gradio library that you have installed locally. However, the function calls are made to the remote Space. So if you are gr.load-ing a Space that has custom components, you'll need to install them locally as well.

ploncker commented 2 months ago

Hi @abidlabs thanks for replying. I'm not hosting the demo locally. I'm trying to gr.load() a private space from a public one. Are you suggesting in this instance can I think of the public space as being equivalent to a local host? If I import the gradio_pdf into my public space

''' import os import gradio as gr from gradio_pdf import PDF key = os.environ['MY_TOKEN'] demo = gr.load("ploncker/emma", hf_token=key, src="spaces") demo.launch() ''' then I end up with the following error when uploading a pdf file:

gradio_client.exceptions.AppError: The upstream Gradio app has raised an exception: [Errno 2] No such file or directory: '/tmp/gradio/b9c4e005bcfc18c805f30186061b14d3b0de3ed1/splunk-guide-to-operational-intelligence.pdf'

My guess is this happens because the the public space is using the public PDF component and uploading to somewhere in the public instance, the private app is expecting a file but never sees it, so throws the error. If thats correct how does one pass the file object to the private space with a custom component?

abidlabs commented 2 months ago

Hi @abidlabs thanks for replying. I'm not hosting the demo locally. I'm trying to gr.load() a private space from a public one. Are you suggesting in this instance can I think of the public space as being equivalent to a local host?

Correct

abidlabs commented 2 months ago

Regarding the error that you're seeing, can you confirm that both Spaces are using the latest versions of gradio?

ploncker commented 2 months ago

Public space logs: RUN pip install --no-cache-dir gradio[oauth]==4.37.2 "uvicorn>=0.14.0" spaces Private space logs: RUN pip install --no-cache-dir gradio[oauth]==4.37.2 "uvicorn>=0.14.0" spaces

abidlabs commented 2 months ago

Hmm interesting, let me reopen and see if we can reproduce this on our end

ploncker commented 2 months ago

Ok. Thanks for having a look.

Also just for clarity when the error says: gradio_client.exceptions.AppError: The upstream Gradio app has raised an exception: [Errno 2] No such file or directory Is the private space upstream or is the public space upstream?

I'm a bit confused in which takes precedence. Is it: Private(equivalent to remote)-> Public(equivalent to local), ie Private upstream from Public, or is it the other way around?

abidlabs commented 2 months ago

The private / remote app is the one raising the exception here

zhangweikun69 commented 2 months ago

I have kind of same issue here. I used gr.load() to load one of my private space into my public space, the whole UI is good, instead of the images and the svgs generated by the private space are not accessible inside the public space. I can see from the browser internet that the public space was trying to access images from one tmp file of the private one, which I think it had been deleted. I guess this is what happens:

  1. public-space:copied_functionA inside the gr.load() blocks has been called
  2. private-space:functionA runs and generate imageA remotely
  3. imageA has been preprocessed by gradio so it can be rendered in the browser, imageA becomes tmpImageA
  4. tmpImageA deleted since it is a tmp file?
  5. public-space try to fetch that tmp file which has been already deleted? Are those steps correct? I feel like something wrong, and how to fix this?

Code in private-space For example: with gr.Row(variant="panel"): regenerate_btn.click(fn=generateImageA, inputs=[], outputs=[imageA])

zhangweikun69 commented 2 months ago

I have kind of same issue here. I used gr.load() to load one of my private space into my public space, the whole UI is good, instead of the images and the svgs generated by the private space are not accessible inside the public space. I can see from the browser internet that the public space was trying to access images from one tmp file of the private one, which I think it had been deleted. I guess this is what happens:

  1. public-space:copied_functionA inside the gr.load() blocks has been called
  2. private-space:functionA runs and generate imageA remotely
  3. imageA has been preprocessed by gradio so it can be rendered in the browser, imageA becomes tmpImageA
  4. tmpImageA deleted since it is a tmp file?
  5. public-space try to fetch that tmp file which has been already deleted? Are those steps correct? I feel like something wrong, and how to fix this?

Code in private-space For example: with gr.Row(variant="panel"): regenerate_btn.click(fn=generateImageA, inputs=[], outputs=[imageA])

I'm sorry this is not what exactly happened. It's just the tmp file path is 404 not found, I still have no clue about it