|
|
from esgen.functions import *
|
|
|
|
|
|
|
|
|
js = """
|
|
|
function createGradioAnimation() {
|
|
|
var container = document.createElement('div');
|
|
|
container.id = 'gradio-animation';
|
|
|
container.style.fontSize = '2em';
|
|
|
container.style.fontWeight = 'bold';
|
|
|
container.style.textAlign = 'center';
|
|
|
container.style.marginBottom = '20px';
|
|
|
|
|
|
var text = 'EntitySchema Generator';
|
|
|
for (var i = 0; i < text.length; i++) {
|
|
|
(function(i){
|
|
|
setTimeout(function(){
|
|
|
var letter = document.createElement('span');
|
|
|
letter.style.opacity = '0';
|
|
|
letter.style.transition = 'opacity 0.5s';
|
|
|
letter.innerText = text[i];
|
|
|
|
|
|
container.appendChild(letter);
|
|
|
|
|
|
setTimeout(function() {
|
|
|
letter.style.opacity = '1';
|
|
|
}, 50);
|
|
|
}, i * 250);
|
|
|
})(i);
|
|
|
}
|
|
|
|
|
|
var gradioContainer = document.querySelector('.gradio-container');
|
|
|
gradioContainer.insertBefore(container, gradioContainer.firstChild);
|
|
|
|
|
|
return 'Animation created';
|
|
|
}
|
|
|
"""
|
|
|
|
|
|
|
|
|
with gr.Blocks() as introduction_tab:
|
|
|
gr.Markdown(
|
|
|
"""
|
|
|
This is a [Wikidata EntitySchema](https://www.wikidata.org/wiki/Wikidata:Schemas) Generator that consists of
|
|
|
two components:
|
|
|
- The **Generate** tab is used to generate an EntitySchema from scratch by analyzing existing items and
|
|
|
refining the results with the help of a chatbot.
|
|
|
- The **Modify** tab is used to add, change, or remove constraints from an existing EntitySchema.
|
|
|
|
|
|
## Resources
|
|
|
- [Wikidata Schemas](https://www.wikidata.org/wiki/Wikidata:Schemas)
|
|
|
- [Shape Expressions (ShEx) 2.1 Primer](https://shex.io/shex-primer/)
|
|
|
- [EntitySchema directory](https://www.wikidata.org/wiki/Wikidata:Database_reports/EntitySchema_directory)
|
|
|
- [WikiShape](https://wikishape.weso.es)
|
|
|
- [RDFShape](https://rdfshape.weso.es)
|
|
|
- [ShExStatements](https://shexstatements.toolforge.org)
|
|
|
- A similar toolkit can be found [here on Toolforge](https://tools-static.wmflabs.org/entityschema-generator/).
|
|
|
- [ShEx2 Simple Online Validator](https://shex-simple.toolforge.org/wikidata/packages/shex-webapp/doc/shex-simple.html?data=Endpoint:%20https://query.wikidata.org/sparql&hideData&manifest=[]&textMapIsSparqlQuery)
|
|
|
|
|
|
## Report an issue
|
|
|
Hugging Face provides a [Community](https://huggingface.co/spaces/b289zhan/ESGen/discussions) panel for discussions.
|
|
|
If you encounter any bugs or issues with this tool, please feel free to start a new discussion there.
|
|
|
You can also post any new feature requests.
|
|
|
|
|
|
## Acknowledgements
|
|
|
This tool is a collaborative effort by King's College London, London, and Wikimedia Deutschland, Berlin.
|
|
|
The project is funded by the NMES Enterprise & Engagement Partnerships Fund from King's College London.
|
|
|
"""
|
|
|
)
|
|
|
|
|
|
|
|
|
with gr.Blocks() as generate_tab:
|
|
|
gr.Markdown(
|
|
|
"""
|
|
|
On this page, you can generate an EntitySchema from scratch. The tool will analyze existing items to draft an
|
|
|
EntitySchema for you. Afterwards, you can refine it by answering a few questions from a chatbot.
|
|
|
|
|
|
## Step 1: Generate an EntitySchema from scratch
|
|
|
"""
|
|
|
)
|
|
|
with gr.Row():
|
|
|
with gr.Column():
|
|
|
es_name = gr.Textbox(
|
|
|
label="Name of the new EntitySchema",
|
|
|
placeholder="e.g., algorithm"
|
|
|
)
|
|
|
es_class = gr.Textbox(
|
|
|
label="Item ID for class",
|
|
|
placeholder="e.g., Q8366",
|
|
|
info="Specify which class the new EntitySchema will cover. The tool will look at all items that "
|
|
|
"are an 'instance of' (P31) the class."
|
|
|
)
|
|
|
class_choices = gr.Radio(visible=False)
|
|
|
threshold_slider = gr.Slider(
|
|
|
minimum=10, maximum=100, value=50, step=10, label="Cutoff",
|
|
|
info="Ignore all properties that are used on less than X% of items in the class for the initial "
|
|
|
"EntitySchema generation."
|
|
|
)
|
|
|
property_type_checkboxes = gr.CheckboxGroup(
|
|
|
choices=[("WikibaseItem", "wikibase:WikibaseItem"), ("ExternalId", "wikibase:ExternalId")],
|
|
|
value=["wikibase:WikibaseItem"],
|
|
|
label="Property types",
|
|
|
info="Select the Wikidata datatypes of properties you want to encompass. Default: 'WikibaseItem'."
|
|
|
)
|
|
|
generate_btn = gr.Button(value="Generate EntitySchema")
|
|
|
gr.Markdown(
|
|
|
"""
|
|
|
## Step 2: Refine the generated EntitySchema
|
|
|
The chatbot will ask you a series of questions to refine the EntitySchema. Click the following buttons
|
|
|
to answer the questions.
|
|
|
- If you think the property is required for all items in the class, click "Yes".
|
|
|
- If you think the property is only used on some items in the class, click "Optional".
|
|
|
- If you think the property should not be used on any items in the class, click "No".
|
|
|
- If you can't decide, feel free to click "Skip".
|
|
|
"""
|
|
|
)
|
|
|
|
|
|
|
|
|
refine_chatbot = gr.Chatbot(
|
|
|
label="Chatbot",
|
|
|
value=[[None, None]],
|
|
|
height=420,
|
|
|
render_markdown=True,
|
|
|
)
|
|
|
|
|
|
with gr.Row():
|
|
|
yes_btn = gr.Button(
|
|
|
value="✅ Yes"
|
|
|
)
|
|
|
optional_btn = gr.Button(
|
|
|
value="🉑 Optional"
|
|
|
)
|
|
|
no_btn = gr.Button(
|
|
|
value="⛔️ No"
|
|
|
)
|
|
|
skip_btn = gr.Button(
|
|
|
value="⏩ Skip"
|
|
|
)
|
|
|
|
|
|
with gr.Column():
|
|
|
|
|
|
es_output = gr.Code(
|
|
|
lines=70,
|
|
|
label="EntitySchema",
|
|
|
interactive=True,
|
|
|
)
|
|
|
|
|
|
es_json = gr.JSON(
|
|
|
label="JSON",
|
|
|
visible=False,
|
|
|
)
|
|
|
|
|
|
es_class.input(
|
|
|
fn=update_class_choices,
|
|
|
inputs=es_class,
|
|
|
outputs=class_choices
|
|
|
)
|
|
|
|
|
|
class_choices.select(
|
|
|
fn=select_class,
|
|
|
inputs=[class_choices],
|
|
|
outputs=[es_class, class_choices]
|
|
|
)
|
|
|
|
|
|
generate_btn.click(
|
|
|
fn=entity_schema_generation,
|
|
|
inputs=[es_name, es_class, threshold_slider, property_type_checkboxes],
|
|
|
outputs=[es_output, es_json, refine_chatbot]
|
|
|
)
|
|
|
|
|
|
yes_btn.click(
|
|
|
fn=input_yes,
|
|
|
inputs=[es_output, es_json, refine_chatbot],
|
|
|
outputs=[es_output, es_json, refine_chatbot]
|
|
|
)
|
|
|
optional_btn.click(
|
|
|
fn=input_optional,
|
|
|
inputs=[es_output, es_json, refine_chatbot],
|
|
|
outputs=[es_output, es_json, refine_chatbot]
|
|
|
)
|
|
|
no_btn.click(
|
|
|
fn=input_no,
|
|
|
inputs=[es_output, es_json, refine_chatbot],
|
|
|
outputs=[es_output, es_json, refine_chatbot]
|
|
|
)
|
|
|
skip_btn.click(
|
|
|
fn=input_skip,
|
|
|
inputs=[es_output, es_json, refine_chatbot],
|
|
|
outputs=[es_output, es_json, refine_chatbot]
|
|
|
)
|
|
|
|
|
|
|
|
|
with gr.Blocks() as modify_single_tab:
|
|
|
gr.Markdown(
|
|
|
"""
|
|
|
On this page, you can modify an existing EntitySchema. You can load an example or paste your own EntitySchema
|
|
|
into the EntitySchema box on the right. Afterwards, you can specify the changes you would like to make to your
|
|
|
EntitySchema.
|
|
|
|
|
|
## Step 1: Load an EntitySchema
|
|
|
"""
|
|
|
)
|
|
|
with gr.Row():
|
|
|
with gr.Column():
|
|
|
|
|
|
example_dropdown = gr.Dropdown(
|
|
|
choices=["algorithm"],
|
|
|
label="EntitySchema Examples",
|
|
|
info="Either select an example from the dropdown list or "
|
|
|
"paste your own EntitySchema into the EntitySchema box on the right and "
|
|
|
"click the 'load example' button."
|
|
|
)
|
|
|
example_btn = gr.Button("Load example")
|
|
|
|
|
|
gr.Markdown(
|
|
|
"""
|
|
|
## Step 2: Modify the EntitySchema
|
|
|
|
|
|
You can add a new constraint to the EntitySchema by specifying it below. If the EntitySchema already
|
|
|
contains a constraint for the property, it will be overwritten by the new constraint. If you would like
|
|
|
to delete constraints, simply delete them in the EntitySchema box.
|
|
|
"""
|
|
|
)
|
|
|
shape_name = gr.Dropdown(
|
|
|
choices=[],
|
|
|
label="Shape Name"
|
|
|
)
|
|
|
property_name = gr.Textbox(
|
|
|
label="Property ID"
|
|
|
)
|
|
|
property_choices = gr.Radio(
|
|
|
visible=False
|
|
|
)
|
|
|
with gr.Column():
|
|
|
with gr.Group():
|
|
|
allowed_values = gr.Dropdown(
|
|
|
choices=[
|
|
|
"with any value",
|
|
|
"with one of a set of specific entities",
|
|
|
"with an instance of",
|
|
|
"with a subclass of",
|
|
|
"datatypes"
|
|
|
],
|
|
|
label="Allowed Values"
|
|
|
)
|
|
|
class_names = gr.Textbox(label="Class Name", interactive=True, visible=False)
|
|
|
class_choices = gr.Radio(visible=False)
|
|
|
datatypes = gr.Dropdown(visible=False)
|
|
|
|
|
|
cardinality = gr.Dropdown(
|
|
|
choices=[
|
|
|
"has 1 matching statement",
|
|
|
"has 0 or 1 matching statements",
|
|
|
"has 0 or more matching statements",
|
|
|
"has 1 or more matching statements",
|
|
|
"has no matching statements"
|
|
|
],
|
|
|
label="Cardinality",
|
|
|
interactive=True
|
|
|
)
|
|
|
with gr.Column():
|
|
|
comment = gr.Textbox(
|
|
|
label="Comment"
|
|
|
)
|
|
|
insert_btn = gr.Button(value="Insert")
|
|
|
|
|
|
with gr.Column():
|
|
|
es_output = gr.Code(
|
|
|
lines=46,
|
|
|
label="EntitySchema",
|
|
|
interactive=True,
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
property_name.input(
|
|
|
fn=update_property_choices,
|
|
|
inputs=property_name,
|
|
|
outputs=property_choices
|
|
|
)
|
|
|
property_choices.select(
|
|
|
fn=select_property,
|
|
|
inputs=property_choices,
|
|
|
outputs=[property_name, property_choices]
|
|
|
)
|
|
|
allowed_values.change(
|
|
|
fn=select_allowed_values,
|
|
|
inputs=allowed_values,
|
|
|
outputs=[class_names, class_choices, datatypes]
|
|
|
)
|
|
|
class_names.input(
|
|
|
fn=update_class_choices,
|
|
|
inputs=class_names,
|
|
|
outputs=class_choices
|
|
|
)
|
|
|
class_choices.select(
|
|
|
fn=add_class,
|
|
|
inputs=[class_names, class_choices],
|
|
|
outputs=[class_names, class_choices]
|
|
|
)
|
|
|
insert_btn.click(
|
|
|
fn=insert_constraint,
|
|
|
inputs=[es_output, shape_name, property_name, allowed_values, class_names, datatypes, cardinality, comment],
|
|
|
outputs=es_output
|
|
|
)
|
|
|
|
|
|
|
|
|
example_btn.click(
|
|
|
fn=load_examples,
|
|
|
inputs=[example_dropdown, es_output],
|
|
|
outputs=[es_output, shape_name]
|
|
|
)
|
|
|
|
|
|
|
|
|
demo = gr.TabbedInterface(
|
|
|
interface_list=[introduction_tab, generate_tab, modify_single_tab],
|
|
|
tab_names=["Introduction", "Generate", "Modify"],
|
|
|
css="footer {visibility: hidden}",
|
|
|
js=js
|
|
|
)
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
demo.launch()
|
|
|
|