mirror of
https://github.com/gradio-app/gradio.git
synced 2025-03-07 11:46:51 +08:00
merge changes
This commit is contained in:
commit
55eb120704
@ -1,5 +1,5 @@
|
||||
# Contributing to Gradio
|
||||
You can start by forking or cloning the repo (https://github.com/gradio-app/gradio.git) and creating your own branch to work from.
|
||||
More than 30 awesome developers have contributed to the `gradio` library, and we'd be thrilled if you would like be the next `gradio` contributor! You can start by forking or cloning the repo (https://github.com/gradio-app/gradio.git) and creating your own branch to work from.
|
||||
|
||||
Next, to install the local development version of Gradio:
|
||||
* Navigate to the `/gradio` subfolder and run `pip install -e .`.
|
||||
@ -7,23 +7,24 @@ Next, to install the local development version of Gradio:
|
||||
When installing locally, you may also need to build the front end:
|
||||
* Navigate to the `/frontend` subfolder and run `npm install`.
|
||||
* Then run `npm run build`.
|
||||
* Then you can run `npm run start` to start a local development server (on port 3000) that responds to any changes in the frontend
|
||||
|
||||
### Structure of the Repository
|
||||
|
||||
It's helpful to know the overall structure of the repository so that you can focus on the part of the source code you'd like to contribute to
|
||||
|
||||
* `/gradio`: contains the source code for the actual Python library
|
||||
* `/gradio/interface.py`: contains the source code for the core `Interface` class
|
||||
* `/test`: contains unit tests for the Python library
|
||||
|
||||
* `/gradio`: contains the Python source code for the library
|
||||
* `/gradio/interface.py`: contains the Python source code for the core `Interface` class (**start HERE!**)
|
||||
* `/frontend`: contains the HTML/JS/CSS source code for the library
|
||||
* `/test`: contains Python unit tests for the library
|
||||
* `/demo`: contains demos that are used in the documentation as well as for integration tests
|
||||
* `/website`: contains the code for the Gradio website (www.gradio.app). See the README in the `/website` folder for more details
|
||||
|
||||
|
||||
### Continuous Integration and Testing
|
||||
All PRs must pass the continuous integration tests before merging. To test locally, you can run `python -m unittest` from the `/gradio` subfolder.
|
||||
|
||||
### Submitting PRs
|
||||
All PRs must pass the continuous integration tests before merging. To test locally, you can run `python -m unittest` from `/` (the directory where you cloned this repo).
|
||||
|
||||
## Submitting PRs
|
||||
All PRs should be against `master`. Direct commits to master are blocked, and PRs require an approving review
|
||||
to merge into master. By convention, the Gradio maintainers will review PRs when:
|
||||
* An initial review has been requested, and
|
||||
@ -31,3 +32,5 @@ to merge into master. By convention, the Gradio maintainers will review PRs when
|
||||
|
||||
We ask that you make sure initial CI checks are passing before requesting a review.
|
||||
One of the Gradio maintainers will merge the PR when all the checks are passing.
|
||||
|
||||
*Could these guidelines be clearer? Feel free to open a PR to help us faciltiate open-source contributions!*
|
||||
|
@ -37,6 +37,7 @@
|
||||
"start": "cross-env REACT_APP_BACKEND_URL='http://localhost:7860/' craco start",
|
||||
"format": "prettier-eslint --write '**/*.js*'",
|
||||
"build": "cross-env REACT_APP_BACKEND_URL='' REACT_APP_VERSION=$(cat ../gradio/version.txt) GENERATE_SOURCEMAP=false craco build",
|
||||
"build:win": "cross-env REACT_APP_BACKEND_URL='' GENERATE_SOURCEMAP=false craco build",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
@ -464,7 +464,7 @@ export class GradioInterface extends React.Component {
|
||||
) : (
|
||||
false
|
||||
)}
|
||||
{this.props.allow_flagging ? (
|
||||
{this.props.allow_flagging === "manual" ? (
|
||||
this.props.flagging_options === null ? (
|
||||
<button
|
||||
className={classNames("panel_button", "flag", {
|
||||
|
@ -64,11 +64,9 @@ class Interface:
|
||||
(gradio.Interface): a Gradio Interface object for the given model
|
||||
"""
|
||||
interface_info = load_interface(name, src, api_key, alias)
|
||||
# create a dictionary of kwargs without overwriting the original interface_info dict because it is mutable
|
||||
# and that can cause some issues since the internal prediction function may rely on the original interface_info dict
|
||||
kwargs = dict(interface_info, **kwargs)
|
||||
interface = cls(**kwargs)
|
||||
interface.api_mode = True # set api mode to true so that the interface will not preprocess/postprocess
|
||||
interface.api_mode = True # So interface doesn't run pre/postprocess.
|
||||
return interface
|
||||
|
||||
@classmethod
|
||||
@ -77,7 +75,8 @@ class Interface:
|
||||
pipeline: transformers.Pipeline,
|
||||
**kwargs) -> Interface:
|
||||
"""
|
||||
Class method to construct an Interface from a Hugging Face transformers.Pipeline.
|
||||
Construct an Interface from a Hugging Face transformers.Pipeline.
|
||||
Parameters:
|
||||
pipeline (transformers.Pipeline):
|
||||
Returns:
|
||||
(gradio.Interface): a Gradio Interface object from the given Pipeline
|
||||
@ -112,7 +111,7 @@ class Interface:
|
||||
height=None,
|
||||
width=None,
|
||||
allow_screenshot: bool = True,
|
||||
allow_flagging: bool = None,
|
||||
allow_flagging: Optional[str] = None,
|
||||
flagging_options: List[str]=None,
|
||||
encrypt=None,
|
||||
show_tips=None,
|
||||
@ -120,8 +119,7 @@ class Interface:
|
||||
analytics_enabled: Optional[bool] = None,
|
||||
enable_queue=None,
|
||||
api_mode=None,
|
||||
flagging_callback: FlaggingCallback = CSVLogger()
|
||||
):
|
||||
flagging_callback: FlaggingCallback = CSVLogger()):
|
||||
"""
|
||||
Parameters:
|
||||
fn (Union[Callable, List[Callable]]): the function to wrap an interface around.
|
||||
@ -142,8 +140,8 @@ class Interface:
|
||||
theme (str): Theme to use - one of "default", "huggingface", "grass", "peach". Add "dark" prefix, e.g. "darkpeach" or "darkdefault" for darktheme.
|
||||
css (str): custom css or path to custom css file to use with interface.
|
||||
allow_screenshot (bool): if False, users will not see a button to take a screenshot of the interface.
|
||||
allow_flagging (bool): if False, users will not see a button to flag an input and output.
|
||||
flagging_options (List[str]): if not None, provides options a user must select when flagging.
|
||||
allow_flagging (str): one of "never", "auto", or "manual". If "never" or "auto", users will not see a button to flag an input and output. If "manual", users will see a button to flag. If "auto", every prediction will be automatically flagged. If "manual", samples are flagged when the user clicks flag button. Can be set with environmental variable GRADIO_ALLOW_FLAGGING.
|
||||
flagging_options (List[str]): if provided, allows user to select from the list of options when flagging. Only applies if allow_flagging is "manual".
|
||||
encrypt (bool): DEPRECATED. If True, flagged data will be encrypted by key provided by creator at launch
|
||||
flagging_dir (str): what to name the dir where flagged data is stored.
|
||||
show_tips (bool): DEPRECATED. if True, will occasionally show tips about new Gradio features
|
||||
@ -204,6 +202,10 @@ class Interface:
|
||||
self.theme = theme
|
||||
self.height = height
|
||||
self.width = width
|
||||
if self.height is not None or self.width is not None:
|
||||
warnings.warn("The `height` and `width` parameters in `Interface` "
|
||||
"are deprecated and should be passed into launch().")
|
||||
|
||||
if css is not None and os.path.exists(css):
|
||||
with open(css) as css_file:
|
||||
self.css = css_file.read()
|
||||
@ -222,11 +224,33 @@ class Interface:
|
||||
self.simple_server = None
|
||||
self.allow_screenshot = allow_screenshot
|
||||
|
||||
# For allow_flagging and analytics_enabled: (1) first check for parameter, (2) check for environment variable, (3) default to True
|
||||
# For analytics_enabled and allow_flagging: (1) first check for
|
||||
# parameter, (2) check for env variable, (3) default to True/"manual"
|
||||
self.analytics_enabled = analytics_enabled if analytics_enabled is not None else os.getenv("GRADIO_ANALYTICS_ENABLED", "True")=="True"
|
||||
self.allow_flagging = allow_flagging if allow_flagging is not None else os.getenv("GRADIO_ALLOW_FLAGGING", "True")=="True"
|
||||
if allow_flagging is None:
|
||||
allow_flagging = os.getenv("GRADIO_ALLOW_FLAGGING", "manual")
|
||||
if allow_flagging==True:
|
||||
warnings.warn("The `allow_flagging` parameter in `Interface` now"
|
||||
"takes a string value ('auto', 'manual', or 'never')"
|
||||
", not a boolean. Setting parameter to: 'manual'.")
|
||||
self.allow_flagging = "manual"
|
||||
elif allow_flagging=="manual":
|
||||
self.allow_flagging = "manual"
|
||||
elif allow_flagging==False:
|
||||
warnings.warn("The `allow_flagging` parameter in `Interface` now"
|
||||
"takes a string value ('auto', 'manual', or 'never')"
|
||||
", not a boolean. Setting parameter to: 'never'.")
|
||||
self.allow_flagging = "never"
|
||||
elif allow_flagging=="never":
|
||||
self.allow_flagging = "never"
|
||||
elif allow_flagging=="auto":
|
||||
self.allow_flagging = "auto"
|
||||
else:
|
||||
raise ValueError("Invalid value for `allow_flagging` parameter."
|
||||
"Must be: 'auto', 'manual', or 'never'.")
|
||||
|
||||
self.flagging_options = flagging_options
|
||||
self.flagging_callback: FlaggingCallback = flagging_callback
|
||||
self.flagging_callback = flagging_callback
|
||||
self.flagging_dir = flagging_dir
|
||||
|
||||
self.save_to = None
|
||||
@ -319,14 +343,16 @@ class Interface:
|
||||
called_directly: bool = False
|
||||
) -> List[Any] | Tuple[List[Any], List[float]]:
|
||||
"""
|
||||
This is the method that actually runs the prediction function with the given (processed) inputs.
|
||||
Runs the prediction function with the given (already processed) inputs.
|
||||
Parameters:
|
||||
processed_input (list): A list of processed inputs.
|
||||
return_duration (bool): Whether to return the duration of the prediction.
|
||||
called_directly (bool): Whether the prediction is being called directly (i.e. as a function, not through the GUI).
|
||||
called_directly (bool): Whether the prediction is being called
|
||||
directly (i.e. as a function, not through the GUI).
|
||||
Returns:
|
||||
predictions (list): A list of predictions (not post-processed).
|
||||
durations (list): A list of durations for each prediction (only if `return_duration` is True).
|
||||
durations (list): A list of durations for each prediction
|
||||
(only returned if `return_duration` is True).
|
||||
"""
|
||||
if self.api_mode: # Serialize the input
|
||||
processed_input = [input_component.serialize(processed_input[i], called_directly)
|
||||
@ -363,6 +389,8 @@ class Interface:
|
||||
raw_input: List[Any]
|
||||
) -> Tuple[List[Any], List[float]]:
|
||||
"""
|
||||
First preprocesses the input, then runs prediction using
|
||||
self.run_prediction(), then postprocesses the output.
|
||||
Parameters:
|
||||
raw_input: a list of raw inputs to process and apply the prediction(s) on.
|
||||
Returns:
|
||||
@ -370,7 +398,8 @@ class Interface:
|
||||
duration: a list of time deltas measuring inference time for each prediction fn.
|
||||
"""
|
||||
processed_input = [input_component.preprocess(raw_input[i])
|
||||
for i, input_component in enumerate(self.input_components)]
|
||||
for i, input_component in enumerate(
|
||||
self.input_components)]
|
||||
predictions, durations = self.run_prediction(
|
||||
processed_input, return_duration=True)
|
||||
processed_output = [output_component.postprocess(predictions[i]) if predictions[i] is not None else None
|
||||
@ -411,13 +440,12 @@ class Interface:
|
||||
def test_launch(self) -> None:
|
||||
for predict_fn in self.predict:
|
||||
print("Test launch: {}()...".format(predict_fn.__name__), end=' ')
|
||||
|
||||
raw_input = []
|
||||
for input_component in self.input_components:
|
||||
if input_component.test_input is None: # If no test input is defined for that input interface
|
||||
if input_component.test_input is None:
|
||||
print("SKIPPED")
|
||||
break
|
||||
else: # If a test input is defined for each interface object
|
||||
else:
|
||||
raw_input.append(input_component.test_input)
|
||||
else:
|
||||
self.process(raw_input)
|
||||
@ -456,8 +484,8 @@ class Interface:
|
||||
private_endpoint (str): If provided, the public URL of the interface will be this endpoint (should generally be unchanged).
|
||||
prevent_thread_lock (bool): If True, the interface will block the main thread while the server is running.
|
||||
show_error (bool): If True, any errors in the interface will be printed in the browser console log
|
||||
server_port (int): will start gradio app on this port (if available)
|
||||
server_name (str): to make app accessible on local network, set this to "0.0.0.0".
|
||||
server_port (int): will start gradio app on this port (if available). Can be set by environment variable GRADIO_SERVER_PORT.
|
||||
server_name (str): to make app accessible on local network, set this to "0.0.0.0". Can be set by environment variable GRADIO_SERVER_NAME.
|
||||
show_tips (bool): if True, will occasionally show tips about new Gradio features
|
||||
enable_queue (bool): if True, inference requests will be served through a queue instead of with parallel threads. Required for longer inference times (> 1min) to prevent timeout.
|
||||
width (int): The width in pixels of the <iframe> element containing the interface (used if inline=True)
|
||||
@ -469,7 +497,6 @@ class Interface:
|
||||
path_to_local_server (str): Locally accessible link
|
||||
share_url (str): Publicly accessible link (if share=True)
|
||||
"""
|
||||
# Set up local flask server
|
||||
self.cache_examples = cache_examples
|
||||
if auth and not callable(auth) and not isinstance(auth[0], tuple) and not isinstance(auth[0], list):
|
||||
auth = [auth]
|
||||
@ -477,13 +504,15 @@ class Interface:
|
||||
self.auth_message = auth_message
|
||||
self.show_tips = show_tips
|
||||
self.show_error = show_error
|
||||
self.height = self.height or height # if height is not set in constructor, use the one provided here
|
||||
self.width = self.width or width # if width is not set in constructor, use the one provided here
|
||||
self.height = self.height or height
|
||||
self.width = self.width or width
|
||||
|
||||
if self.encrypt is None:
|
||||
self.encrypt = encrypt # if encrypt is not set in constructor, use the one provided here
|
||||
self.encrypt = encrypt
|
||||
if self.encrypt:
|
||||
self.encryption_key = encryptor.get_key(
|
||||
getpass.getpass("Enter key for encryption: "))
|
||||
|
||||
if self.enable_queue is None:
|
||||
self.enable_queue = enable_queue
|
||||
if self.allow_flagging:
|
||||
@ -495,7 +524,6 @@ class Interface:
|
||||
if self.cache_examples:
|
||||
cache_interface_examples(self)
|
||||
|
||||
# Launch local flask server
|
||||
server_port, path_to_local_server, app, thread, server = networking.start_server(
|
||||
self, server_name, server_port, self.auth)
|
||||
self.local_url = path_to_local_server
|
||||
@ -505,10 +533,10 @@ class Interface:
|
||||
self.server_app = app
|
||||
self.server_thread = thread
|
||||
|
||||
# Count number of launches
|
||||
utils.launch_counter()
|
||||
|
||||
# If running in a colab or not able to access localhost, automatically create a shareable link
|
||||
# If running in a colab or not able to access localhost,
|
||||
# automatically create a shareable link.
|
||||
is_colab = utils.colab_check()
|
||||
if is_colab or not (networking.url_ok(path_to_local_server)):
|
||||
share = True
|
||||
@ -524,7 +552,6 @@ class Interface:
|
||||
|
||||
if private_endpoint is not None:
|
||||
share = True
|
||||
# Set up shareable link
|
||||
self.share = share
|
||||
|
||||
if share:
|
||||
@ -545,7 +572,6 @@ class Interface:
|
||||
print(strings.en["PUBLIC_SHARE_TRUE"])
|
||||
share_url = None
|
||||
|
||||
# Open a browser tab with the interface.
|
||||
if inbrowser:
|
||||
link = share_url if share else path_to_local_server
|
||||
webbrowser.open(link)
|
||||
@ -556,7 +582,6 @@ class Interface:
|
||||
if inline:
|
||||
try:
|
||||
from IPython.display import IFrame, display # type: ignore
|
||||
# Embed the remote interface page if on google colab; otherwise, embed the local page.
|
||||
if share:
|
||||
while not networking.url_ok(share_url):
|
||||
time.sleep(1)
|
||||
@ -565,7 +590,7 @@ class Interface:
|
||||
display(IFrame(path_to_local_server,
|
||||
width=self.width, height=self.height))
|
||||
except ImportError:
|
||||
pass # IPython is not available so does not print inline.
|
||||
pass
|
||||
|
||||
data = {
|
||||
'launch_method': 'browser' if inbrowser else 'inline',
|
||||
@ -608,9 +633,7 @@ class Interface:
|
||||
self.server_thread.join()
|
||||
if verbose:
|
||||
print("Closing server running on port: {}".format(self.server_port))
|
||||
except AttributeError: # can't close if not running
|
||||
pass
|
||||
except OSError: # sometimes OSError is thrown when shutting down
|
||||
except (AttributeError, OSError): # can't close if not running
|
||||
pass
|
||||
|
||||
def integrate(
|
||||
@ -658,7 +681,6 @@ class Interface:
|
||||
|
||||
|
||||
def close_all(verbose: bool = True) -> None:
|
||||
# Tries to close all running interfaces, but method is a little flaky.
|
||||
for io in Interface.get_instances():
|
||||
io.close(verbose)
|
||||
|
||||
|
@ -159,6 +159,39 @@ def login():
|
||||
return abort(401)
|
||||
|
||||
|
||||
@app.route("/api/", methods=["GET"])
|
||||
def api_docs():
|
||||
inputs = [type(inp) for inp in app.interface.input_components]
|
||||
outputs = [type(out) for out in app.interface.output_components]
|
||||
input_types_doc, input_types = get_types(inputs, "input")
|
||||
output_types_doc, output_types = get_types(outputs, "output")
|
||||
input_names = [type(inp).__name__ for inp in app.interface.input_components]
|
||||
output_names = [type(out).__name__ for out in app.interface.output_components]
|
||||
if app.interface.examples is not None:
|
||||
sample_inputs = app.interface.examples[0]
|
||||
else:
|
||||
sample_inputs = [inp.generate_sample() for inp in app.interface.input_components]
|
||||
docs = {
|
||||
"inputs": input_names,
|
||||
"outputs": output_names,
|
||||
"len_inputs": len(inputs),
|
||||
"len_outputs": len(outputs),
|
||||
"inputs_lower": [name.lower() for name in input_names],
|
||||
"outputs_lower": [name.lower() for name in output_names],
|
||||
"input_types": input_types,
|
||||
"output_types": output_types,
|
||||
"input_types_doc": input_types_doc,
|
||||
"output_types_doc": output_types_doc,
|
||||
"sample_inputs": sample_inputs,
|
||||
"auth": app.interface.auth,
|
||||
"local_login_url": urllib.parse.urljoin(
|
||||
app.interface.local_url, "login"),
|
||||
"local_api_url": urllib.parse.urljoin(
|
||||
app.interface.local_url, "api/predict")
|
||||
}
|
||||
return render_template("api_docs.html", **docs)
|
||||
|
||||
|
||||
@app.route("/config/", methods=["GET"])
|
||||
def get_config():
|
||||
if app.interface.auth is None or current_user.is_authenticated:
|
||||
@ -210,8 +243,7 @@ def predict():
|
||||
if app.interface.allow_flagging == "auto":
|
||||
flag_index = app.interface.flagging_callback.flag(app.interface, raw_input, prediction,
|
||||
flag_option=(None if app.interface.flagging_options is None else ""),
|
||||
username=current_user.id if current_user.is_authenticated else None,
|
||||
flag_path=os.path.join(app.cwd, app.interface.flagging_dir))
|
||||
username=current_user.id if current_user.is_authenticated else None)
|
||||
output = {
|
||||
"data": prediction,
|
||||
"durations": durations,
|
||||
@ -221,74 +253,14 @@ def predict():
|
||||
return output
|
||||
|
||||
|
||||
def get_types(cls_set, component):
|
||||
docset = []
|
||||
types = []
|
||||
if component == "input":
|
||||
for cls in cls_set:
|
||||
doc = inspect.getdoc(cls.preprocess)
|
||||
doc_lines = doc.split("\n")
|
||||
docset.append(doc_lines[1].split(":")[-1])
|
||||
types.append(doc_lines[1].split(")")[0].split("(")[-1])
|
||||
else:
|
||||
for cls in cls_set:
|
||||
doc = inspect.getdoc(cls.postprocess)
|
||||
doc_lines = doc.split("\n")
|
||||
docset.append(doc_lines[-1].split(":")[-1])
|
||||
types.append(doc_lines[-1].split(")")[0].split("(")[-1])
|
||||
return docset, types
|
||||
|
||||
|
||||
@app.route("/api/", methods=["GET"])
|
||||
def api_docs():
|
||||
inputs = [type(inp) for inp in app.interface.input_components]
|
||||
outputs = [type(out) for out in app.interface.output_components]
|
||||
input_types_doc, input_types = get_types(inputs, "input")
|
||||
output_types_doc, output_types = get_types(outputs, "output")
|
||||
input_names = [type(inp).__name__ for inp in app.interface.input_components]
|
||||
output_names = [type(out).__name__ for out in app.interface.output_components]
|
||||
if app.interface.examples is not None:
|
||||
sample_inputs = app.interface.examples[0]
|
||||
else:
|
||||
sample_inputs = [inp.generate_sample() for inp in app.interface.input_components]
|
||||
docs = {
|
||||
"inputs": input_names,
|
||||
"outputs": output_names,
|
||||
"len_inputs": len(inputs),
|
||||
"len_outputs": len(outputs),
|
||||
"inputs_lower": [name.lower() for name in input_names],
|
||||
"outputs_lower": [name.lower() for name in output_names],
|
||||
"input_types": input_types,
|
||||
"output_types": output_types,
|
||||
"input_types_doc": input_types_doc,
|
||||
"output_types_doc": output_types_doc,
|
||||
"sample_inputs": sample_inputs,
|
||||
"auth": app.interface.auth,
|
||||
"local_login_url": urllib.parse.urljoin(
|
||||
app.interface.local_url, "login"),
|
||||
"local_api_url": urllib.parse.urljoin(
|
||||
app.interface.local_url, "api/predict")
|
||||
}
|
||||
return render_template("api_docs.html", **docs)
|
||||
|
||||
|
||||
def log_feature_analytics(feature):
|
||||
if app.interface.analytics_enabled:
|
||||
try:
|
||||
requests.post(GRADIO_FEATURE_ANALYTICS_URL,
|
||||
data={
|
||||
'ip_address': IP_ADDRESS,
|
||||
'feature': feature}, timeout=3)
|
||||
except (requests.ConnectionError, requests.exceptions.ReadTimeout):
|
||||
pass # do not push analytics if no network
|
||||
|
||||
|
||||
@app.route("/api/flag/", methods=["POST"])
|
||||
@login_check
|
||||
def flag():
|
||||
log_feature_analytics('flag')
|
||||
data = request.json['data']
|
||||
app.interface.flagging_callback.flag(app.interface, data['input_data'], data['output_data'], data.get("flag_option"), data.get("flag_index"),
|
||||
app.interface.flagging_callback.flag(
|
||||
app.interface, data['input_data'], data['output_data'],
|
||||
data.get("flag_option"), data.get("flag_index"),
|
||||
current_user.id if current_user.is_authenticated else None)
|
||||
return jsonify(success=True)
|
||||
|
||||
@ -446,3 +418,35 @@ def url_ok(url):
|
||||
return True
|
||||
except (ConnectionError, requests.exceptions.ConnectionError):
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def get_types(cls_set, component):
|
||||
docset = []
|
||||
types = []
|
||||
if component == "input":
|
||||
for cls in cls_set:
|
||||
doc = inspect.getdoc(cls.preprocess)
|
||||
doc_lines = doc.split("\n")
|
||||
docset.append(doc_lines[1].split(":")[-1])
|
||||
types.append(doc_lines[1].split(")")[0].split("(")[-1])
|
||||
else:
|
||||
for cls in cls_set:
|
||||
doc = inspect.getdoc(cls.postprocess)
|
||||
doc_lines = doc.split("\n")
|
||||
docset.append(doc_lines[-1].split(":")[-1])
|
||||
types.append(doc_lines[-1].split(")")[0].split("(")[-1])
|
||||
return docset, types
|
||||
|
||||
|
||||
def log_feature_analytics(feature):
|
||||
if app.interface.analytics_enabled:
|
||||
try:
|
||||
requests.post(GRADIO_FEATURE_ANALYTICS_URL,
|
||||
data={
|
||||
'ip_address': IP_ADDRESS,
|
||||
'feature': feature}, timeout=3)
|
||||
except (requests.ConnectionError, requests.exceptions.ReadTimeout):
|
||||
pass # do not push analytics if no network
|
||||
|
||||
|
||||
|
@ -1,19 +1,27 @@
|
||||
{
|
||||
"files": {
|
||||
<<<<<<< HEAD
|
||||
"main.css": "/static/css/main.8fe32992.css",
|
||||
=======
|
||||
"main.css": "/static/css/main.9666dfea.css",
|
||||
>>>>>>> fdf679c4fa34c778bfda8977be6d4860d082322f
|
||||
"main.js": "/static/bundle.js",
|
||||
"index.html": "/index.html",
|
||||
"static/media/api-logo.b3893a52.svg": "/static/media/api-logo.b3893a52.svg",
|
||||
"static/media/arrow-left.e497f657.svg": "/static/media/arrow-left.e497f657.svg",
|
||||
"static/media/arrow-right.ea6059fd.svg": "/static/media/arrow-right.ea6059fd.svg",
|
||||
"static/media/clear.33f9b5f3.svg": "/static/media/clear.33f9b5f3.svg",
|
||||
"static/media/edit.44bd4fe1.svg": "/static/media/edit.44bd4fe1.svg",
|
||||
"static/media/logo.411acfd1.svg": "/static/media/logo.411acfd1.svg",
|
||||
"static/media/logo_error.0d6fa515.svg": "/static/media/logo_error.0d6fa515.svg"
|
||||
"static/media/api-logo.93f17adb.svg": "/static/media/api-logo.93f17adb.svg",
|
||||
"static/media/arrow-left.794a4706.svg": "/static/media/arrow-left.794a4706.svg",
|
||||
"static/media/arrow-right.5a7d4ada.svg": "/static/media/arrow-right.5a7d4ada.svg",
|
||||
"static/media/clear.85cf6de8.svg": "/static/media/clear.85cf6de8.svg",
|
||||
"static/media/edit.c6b7d6f7.svg": "/static/media/edit.c6b7d6f7.svg",
|
||||
"static/media/logo.36a8f455.svg": "/static/media/logo.36a8f455.svg",
|
||||
"static/media/logo_error.52ef12b4.svg": "/static/media/logo_error.52ef12b4.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/bundle.css",
|
||||
<<<<<<< HEAD
|
||||
"static/css/main.8fe32992.css",
|
||||
=======
|
||||
"static/css/main.9666dfea.css",
|
||||
>>>>>>> fdf679c4fa34c778bfda8977be6d4860d082322f
|
||||
"static/bundle.js"
|
||||
]
|
||||
}
|
@ -1 +1,5 @@
|
||||
<!doctype html><html lang="en" style="height:100%;margin:0;padding:0"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>{{ config['title'] or 'Gradio' }}</title><meta property="og:url" content="https://gradio.app/"/><meta property="og:type" content="website"/><meta property="og:image" content="{{ config['thumbnail'] or '' }}"/><meta property="og:title" content="{{ config['title'] or '' }}"/><meta property="og:description" content="{{ config['description'] or '' }}"/><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@teamGradio"><meta name="twitter:title" content="{{ config['title'] or '' }}"><meta name="twitter:description" content="{{ config['description'] or '' }}"><meta name="twitter:image" content="{{ config['thumbnail'] or '' }}"><script async src="https://www.googletagmanager.com/gtag/js?id=UA-156449732-1"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-156449732-1"),window.gradio_mode="app"</script><script>window.gradio_config = {{ config|tojson }};</script><script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script><title>Gradio</title><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.8fe32992.css" rel="stylesheet"></head><body style="height:100%;margin:0;padding:0"><div id="root" style="height:100%"></div><script src="static/bundle.js"></script></body></html>
|
||||
<<<<<<< HEAD
|
||||
<!doctype html><html lang="en" style="height:100%;margin:0;padding:0"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>{{ config['title'] or 'Gradio' }}</title><meta property="og:url" content="https://gradio.app/"/><meta property="og:type" content="website"/><meta property="og:image" content="{{ config['thumbnail'] or '' }}"/><meta property="og:title" content="{{ config['title'] or '' }}"/><meta property="og:description" content="{{ config['description'] or '' }}"/><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@teamGradio"><meta name="twitter:title" content="{{ config['title'] or '' }}"><meta name="twitter:description" content="{{ config['description'] or '' }}"><meta name="twitter:image" content="{{ config['thumbnail'] or '' }}"><script async src="https://www.googletagmanager.com/gtag/js?id=UA-156449732-1"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-156449732-1"),window.gradio_mode="app"</script><script>window.gradio_config = {{ config|tojson }};</script><script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script><title>Gradio</title><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.8fe32992.css" rel="stylesheet"></head><body style="height:100%;margin:0;padding:0"><div id="root" style="height:100%"></div><script src="static/bundle.js"></script></body></html>
|
||||
=======
|
||||
<!doctype html><html lang="en" style="height:100%;margin:0;padding:0"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>{{ config['title'] or 'Gradio' }}</title><meta property="og:url" content="https://gradio.app/"/><meta property="og:type" content="website"/><meta property="og:image" content="{{ config['thumbnail'] or '' }}"/><meta property="og:title" content="{{ config['title'] or '' }}"/><meta property="og:description" content="{{ config['description'] or '' }}"/><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@teamGradio"><meta name="twitter:title" content="{{ config['title'] or '' }}"><meta name="twitter:description" content="{{ config['description'] or '' }}"><meta name="twitter:image" content="{{ config['thumbnail'] or '' }}"><script async src="https://www.googletagmanager.com/gtag/js?id=UA-156449732-1"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-156449732-1"),window.gradio_mode="app";try{let a="";window.gradio_config=JSON.parse("{{ config|tojson }}"+a)}catch(a){}</script><script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script><title>Gradio</title><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.9666dfea.css" rel="stylesheet"></head><body style="height:100%;margin:0;padding:0"><div id="root" style="height:100%"></div><script src="static/bundle.js"></script></body></html>
|
||||
>>>>>>> fdf679c4fa34c778bfda8977be6d4860d082322f
|
||||
|
Loading…
Reference in New Issue
Block a user