Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tetras MARS Demo in TetrasLab
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Tetras MARS
Tetras MARS Demo in TetrasLab
Commits
8950fd60
Commit
8950fd60
authored
2 years ago
by
David Rouquet
Browse files
Options
Downloads
Patches
Plain Diff
Better control of width in svg graphs
parent
fafe0e26
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
selfContainedDemo.ipynb
+10
-2
10 additions, 2 deletions
selfContainedDemo.ipynb
with
10 additions
and
2 deletions
selfContainedDemo.ipynb
+
10
−
2
View file @
8950fd60
...
...
@@ -27,6 +27,7 @@
"from jupyter_dash import JupyterDash as Dash\n",
"from dash.dependencies import Input, Output, State\n",
"import base64\n",
"import xml.etree.ElementTree as ET\n",
"\n",
"AMR_BATCH_PATH = \"/opt/lib/TetrasMARS/amrbatch/\"\n",
"sys.path.insert(0, os.path.abspath(AMR_BATCH_PATH))\n",
...
...
@@ -111,11 +112,18 @@
" \n",
"def localImage2htmlImg(imgPath):\n",
" with open(imgPath, \"rb\") as image_file:\n",
" img_data = base64.b64encode(image_file.read())\n",
" imageStr = image_file.read()\n",
" root = ET.fromstring(imageStr)\n",
" widthInt = int(root.attrib['width'].replace(\"pt\",\"\"))\n",
" if widthInt > 1700 :\n",
" widthStr = \"100%\"\n",
" else:\n",
" widthStr = str(widthInt)+\"pt\"\n",
" img_data = base64.b64encode(imageStr)\n",
" img_data = img_data.decode()\n",
" img_data = \"data:image/svg+xml;base64,{}\".format(img_data)\n",
" # ...\n",
" return html.Img(id=\"tag_id\", src=img_data, width=
\"100%\"
, height=\"100%\", className=\"img_class\")#, alt=\"my image\""
" return html.Img(id=\"tag_id\", src=img_data, width=
widthStr
, height=\"100%\", className=\"img_class\")#, alt=\"my image\""
]
},
{
...
...
%% Cell type:code id:0d91640d-23ea-4079-b765-2eea030926c5 tags:
```
python
import
importlib.util
import
re
import
amrlib
from
amrlib.graph_processing.amr_plot
import
AMRPlot
import
uuid
from
IPython.display
import
SVG
,
display
import
os
import
shutil
import
subprocess
from
subprocess
import
Popen
,
PIPE
,
STDOUT
from
glob
import
glob
import
sys
import
os
from
IPython.display
import
HTML
,
IFrame
import
ipywidgets
import
dash_bootstrap_components
as
dbc
from
dash
import
dcc
,
html
,
Input
,
Output
from
jupyter_dash
import
JupyterDash
as
Dash
from
dash.dependencies
import
Input
,
Output
,
State
import
base64
import
xml.etree.ElementTree
as
ET
AMR_BATCH_PATH
=
"
/opt/lib/TetrasMARS/amrbatch/
"
sys
.
path
.
insert
(
0
,
os
.
path
.
abspath
(
AMR_BATCH_PATH
))
import
amrbatch
TENET_PATH
=
"
/opt/lib/TetrasMARS/tenet/
"
sys
.
path
.
insert
(
0
,
os
.
path
.
abspath
(
TENET_PATH
))
import
tenet
AMR_MODEL_PATH
=
"
/opt/lib/TetrasMARS/corpus/cm-tool/amrModel/model_parse_xfm_bart_large-v0_1_0
"
MEDIA_PATH
=
"
/opt/dashboards/media/17/
"
MEDIA_URL
=
"
https://unsel.tetras-lab.io/dashboard/17/media/
"
ROOT_PATH
=
"
/opt/dashboards/TetrasMARS/tetras-mars-demo-prod/
"
AMRLD_PATH
=
"
/opt/lib/TetrasMARS/amrld/
"
owl2vowlPath
=
'
/opt/dashboards/tools/owl2vowl_0.3.7/owl2vowl.jar
'
WEBVOWL_PATH
=
'
/opt/webvowl/
'
onto_prefix
=
"
ontologyTarget
"
# The following is basically `import tenet`
#spec=importlib.util.spec_from_file_location("tenet",TENET_PATH+'tenet/__init__.py')
#tenet = importlib.util.module_from_spec(spec)
#spec.loader.exec_module(tenet)
```
%% Cell type:code id:295e4aef-bbd8-40f0-8d84-0b8032b7b039 tags:
```
python
#stog = amrlib.load_stog_model(model_dir="/opt/dashboards/TetrasMARS/corpus/cm-tool/amrModel/model_parse_xfm_bart_large-v0_1_0")
#prefixPath = uuidDirPath+"file"
#penmanPath = prefixPath+".amr.penman"
#svgPath = prefixPath+".amr.svg"
#ttlFilePath = uuidDirPath+onto_prefix+"-0/"+onto_prefix+"_factoid.ttl"
```
%% Cell type:code id:a410a6b3-865d-441f-9b83-90a1badae291 tags:
```
python
def
clean_sting
(
string
):
"""
Sentence cleanup as needed
"""
return
re
.
sub
(
"
(\.)*
\\
n
"
,
""
,
string
)
def
string2amr
(
string
,
stog
):
stog_result
=
stog
.
parse_sents
([
clean_sting
(
string
)],
add_metadata
=
True
)
return
stog_result
[
0
]
def
show_svg
(
path
):
display
(
SVG
(
filename
=
path
))
def
add_id_in_penman_if_needed
(
penmanStr
,
uuidStr
):
if
not
(
penmanStr
.
startswith
(
'
# ::id
'
)):
penmanStr
=
'
# ::id
'
+
uuidStr
+
'
\n
'
+
penmanStr
return
penmanStr
def
owl2vowl
(
ttlFilePath
,
webvowlFileName
,
webvowlFilePath
,
uuid
=
''
,
importList
=
[]):
# Run java parser
if
importList
==
[]:
cmd
=
[
'
java
'
,
'
-jar
'
,
owl2vowlPath
,
'
-file
'
,
ttlFilePath
]
else
:
cmd
=
[
'
java
'
,
'
-jar
'
,
owl2vowlPath
,
'
-file
'
,
ttlFilePath
,
'
-dependencies
'
]
+
importList
with
Popen
(
cmd
,
stdout
=
PIPE
,
stderr
=
STDOUT
)
as
p
:
p
.
wait
()
p
.
stdout
.
flush
()
if
p
.
returncode
!=
0
:
print
(
"
Error in owl2vowl:
\n\n
"
+
p
.
stdout
.
read
().
decode
())
os
.
rename
(
webvowlFileName
,
webvowlFilePath
)
def
localImage2htmlImg
(
imgPath
):
with
open
(
imgPath
,
"
rb
"
)
as
image_file
:
img_data
=
base64
.
b64encode
(
image_file
.
read
())
imageStr
=
image_file
.
read
()
root
=
ET
.
fromstring
(
imageStr
)
widthInt
=
int
(
root
.
attrib
[
'
width
'
].
replace
(
"
pt
"
,
""
))
if
widthInt
>
1700
:
widthStr
=
"
100%
"
else
:
widthStr
=
str
(
widthInt
)
+
"
pt
"
img_data
=
base64
.
b64encode
(
imageStr
)
img_data
=
img_data
.
decode
()
img_data
=
"
data:image/svg+xml;base64,{}
"
.
format
(
img_data
)
# ...
return
html
.
Img
(
id
=
"
tag_id
"
,
src
=
img_data
,
width
=
"
100%
"
,
height
=
"
100%
"
,
className
=
"
img_class
"
)
#, alt="my image"
return
html
.
Img
(
id
=
"
tag_id
"
,
src
=
img_data
,
width
=
widthStr
,
height
=
"
100%
"
,
className
=
"
img_class
"
)
#, alt="my image"
```
%% Cell type:code id:5fd9cf0c-990a-4776-b206-8cc94f87c7be tags:
```
python
def
processStr
(
input
):
# Define usefull variable and paths based on a uuid
uuidStr
=
str
(
uuid
.
uuid4
())
uuidDirPath
=
"
/opt/data/tmp/demo-tetras-mars/
"
+
uuidStr
+
'
/
'
os
.
mkdir
(
uuidDirPath
)
fullOntoPath
=
uuidDirPath
+
'
full-ontology.ttl
'
ontoBySentencePath
=
uuidDirPath
+
'
onto-by-sentence/
'
webvowlFileName
=
fullOntoPath
.
split
(
'
/
'
)[
-
1
].
replace
(
'
ttl
'
,
'
json
'
)
webvowlFilePath
=
WEBVOWL_PATH
+
uuidStr
+
'
_
'
+
webvowlFileName
uuidZipPath
=
MEDIA_PATH
+
uuidStr
# without the .zip extention
uuidZipUrl
=
MEDIA_URL
+
uuidStr
+
"
.zip
"
# Generate an AMR graph by sentence in a subfolder (with companion files such as images of the graphs)
amr_graph_list
=
amrbatch
.
parse_document_string_to_produce_amr_graph
(
input
,
None
,
amr_model_path
=
AMR_MODEL_PATH
,
output_dirpath
=
uuidDirPath
,
amrld_serialization
=
True
)
# Construct ontologies from each AMR graph plus a "full" one that is the union
factoids
=
tenet
.
create_ontology_from_amrld_dir
(
uuidDirPath
,
onto_prefix
=
"
http://ontologies
"
,
out_file_path
=
fullOntoPath
,
technical_dir_path
=
ontoBySentencePath
)
# Create a zip file so the user can download all generated files
owl2vowl
(
fullOntoPath
,
webvowlFileName
,
webvowlFilePath
,
uuid
=
uuidStr
)
shutil
.
make_archive
(
uuidZipPath
,
'
zip
'
,
uuidDirPath
)
return
uuidDirPath
,
uuidZipUrl
,
webvowlFilePath
```
%% Cell type:code id:0cd10e8b-cf7a-4fd4-b8ac-540fcb943325 tags:
```
python
##################################################################################################
# THE FOLLOWING PART IS SPECIFIC TO TÉTRAS LAB
#
# The _get_tl_config function gets configuration parameters for your
# Tétras Lab instance.
# Those parameters are passed when initialising the Dash app.
##################################################################################################
def
_get_tl_config
():
import
socket
,
errno
,
os
# Find a free port
host
=
"
0.0.0.0
"
port
=
8050
end
=
9999
found
=
False
while
not
found
:
with
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
as
s
:
try
:
s
.
bind
((
host
,
port
))
found
=
True
except
socket
.
error
as
e
:
if
e
.
errno
==
errno
.
EADDRINUSE
:
port
=
port
+
1
if
(
port
>
end
):
raise
"
No available APP port
"
else
:
raise
e
if
(
os
.
getenv
(
"
HOST
"
,
None
)
is
not
None
):
proto
=
os
.
getenv
(
"
PROTO
"
)
actualhost
=
os
.
getenv
(
"
JUPYTER_HOST
"
,
os
.
getenv
(
"
VOILA_HOST
"
,
""
))
localport
=
os
.
getenv
(
"
PORT
"
,
80
)
intermediatehost
=
os
.
getenv
(
"
HOST
"
,
"
localhost
"
)
base_path
=
f
"
/
{
actualhost
}
/app_proxy/
{
port
}
/
"
proxified
=
f
"
{
proto
}
://
{
intermediatehost
}
:
{
localport
}{
base_path
}
"
localurl
=
f
"
http://
{
host
}
:
{
port
}
"
proxy
=
f
"
{
localurl
}
::
{
proxified
}
"
return
((
proxified
,
host
,
port
,
proxy
,
base_path
))
return
((
f
"
http://localhost:
{
port
}
"
,
host
,
port
,
None
,
"
/
"
))
server_url
,
host
,
port
,
proxy
,
base_path
=
_get_tl_config
()
app
=
Dash
(
server_url
=
server_url
,
requests_pathname_prefix
=
base_path
,
external_stylesheets
=
[
dbc
.
themes
.
BOOTSTRAP
]
)
##################################################################################################
##################################################################################################
# THE FOLLOWING PART IS GENERIC (JUPYTER)-DASH CODE FROM https://dash.plotly.com/basic-callbacks
#
# The _get_tl_config function gets configuration parameters for your
# Tétras Lab instance.
# Those parameters are passed when initialising the Dash app.
##################################################################################################
app
.
layout
=
html
.
Div
([
html
.
H4
(
"
Enter an english text and click on the button bellow to construct an ontology.
"
,
style
=
{
'
text-align
'
:
'
center
'
}),
html
.
Br
(),
html
.
P
(
"
It should take about 10 sec/sentence. You can then browse the results online or download them as a zip file.
"
,
style
=
{
'
text-align
'
:
'
center
'
}),
html
.
P
(
"
The text must be a simple succession of sentences. Fancy formating is not supported at the moment.
"
,
style
=
{
'
text-align
'
:
'
center
'
}),
html
.
Br
(),
html
.
Br
(),
html
.
Div
(
dbc
.
Textarea
(
id
=
'
textarea-state
'
,
value
=
'
Jupiter is a gas giant. Earth is a rock planet.
'
,
style
=
{
'
width
'
:
'
100%
'
,
'
height
'
:
130
}),
style
=
{
'
width
'
:
'
60%
'
,
'
height
'
:
130
,
'
margin-left
'
:
'
auto
'
,
'
margin-right
'
:
'
auto
'
},
),
html
.
Br
(),
html
.
Br
(),
html
.
Div
(
dbc
.
Button
(
'
Construct AMR graphs and ontology
'
,
id
=
'
textarea-state-button
'
,
n_clicks
=
0
,
outline
=
True
,
color
=
"
primary
"
),
className
=
"
text-center
"
),
html
.
Br
(),
dcc
.
Loading
(
html
.
Div
(
html
.
A
(
children
=
""
,
href
=
''
,
target
=
"
_blank
"
,
id
=
"
download-link
"
),
className
=
"
text-center
"
)),
html
.
Br
(),
html
.
Br
(),
dcc
.
Loading
(
html
.
Div
(
id
=
'
my-output
'
),
type
=
'
circle
'
),
])
@app.callback
(
#Output('textarea-state-output', 'children'),
Output
(
component_id
=
'
my-output
'
,
component_property
=
'
children
'
),
Output
(
component_id
=
'
download-link
'
,
component_property
=
'
children
'
),
Output
(
component_id
=
'
download-link
'
,
component_property
=
'
href
'
),
Input
(
'
textarea-state-button
'
,
'
n_clicks
'
),
State
(
'
textarea-state
'
,
'
value
'
),
prevent_initial_call
=
True
,
)
def
update_output
(
n_clicks
,
value
):
if
n_clicks
>
0
:
uuidDirPath
,
uuidZipUrl
,
webvowlFilePath
=
processStr
(
value
)
#show_svg(svgPath)
#display(IFrame('''https://unsel.tetras-lab.io/webvowl/#{}">'''.format(webvowlFilePath.replace("/opt/webvowl/","").replace(".json","")),800,1200))
return
[
dbc
.
Row
([
dbc
.
Col
(),
dbc
.
Col
(
dbc
.
Accordion
(
[
dbc
.
AccordionItem
(
[
localImage2htmlImg
(
svgPath
)
],
title
=
"
AMR Graph for sentence
"
+
re
.
sub
(
r
'
.document.*
'
,
''
,
svgPath
.
replace
(
uuidDirPath
+
"
document-
"
,
""
)),
)
for
svgPath
in
sorted
(
glob
(
uuidDirPath
+
"
document-*/*.svg
"
))
]
+
[
dbc
.
AccordionItem
(
[
"
You can click a class to see its instances in the right panel, they are not shown in the graph.
"
,
html
.
Br
(),
'''
https://unsel.tetras-lab.io/webvowl/#{}
'''
.
format
(
webvowlFilePath
.
replace
(
"
/opt/webvowl/
"
,
""
).
replace
(
"
.json
"
,
""
)),
html
.
Br
(),
html
.
Iframe
(
src
=
'''
https://unsel.tetras-lab.io/webvowl/#{}
'''
.
format
(
webvowlFilePath
.
replace
(
"
/opt/webvowl/
"
,
""
).
replace
(
"
.json
"
,
""
)),
style
=
{
"
height
"
:
"
800px
"
,
"
width
"
:
"
100%
"
}),
],
title
=
"
Browse ontology
"
,
item_id
=
'
onto
'
)
]
,
active_item
=
'
onto
'
),
width
=
10
),
dbc
.
Col
()
]),
"
Download Zip File
"
,
uuidZipUrl
]
#@app.callback(
# Output("download-zip", "data"),
# Input("download-zip-button", "n_clicks"),
# prevent_initial_call=True,
#)
#def func(n_clicks):
# if n_clicks > 0:
# return dcc.send_file('https://unsel.tetras-lab.io/dashboard/17/media/9f7287d0-e7b2-4328-9137-7a7c44225b68.zip')
app
.
run_server
(
mode
=
"
inline
"
,
#mode="external",
host
=
host
,
port
=
port
,
proxy
=
proxy
,
height
=
2000
)
##################################################################################################
```
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment