main
Steve Nyemba 3 months ago
parent ee7cddf32f
commit 773a7faa6f

@ -1,55 +0,0 @@
{
"system":{
"id":"data-transport",
"logo":"www/data-transport/_images/database.png","context":"", "theme":"oss.css",
"app":{
"debug":true,"port":8000},
"version":0.6,"mode":"portal",
"source":{
"id":"cloud",
"auth":"nextcloud-auth.json"
}
},
"layout":{
"header":{"title":"data-transport","logo":true,"subtitle":"Simple Data Access Layer - Pandas Support"},
"icons":[],
"root":"www/data-transport",
"index":"index.html",
"on":{
"load":{
"left-pane":["www/data-transport/more.md"]
}
},
"order":{
"menu":["resources","about"]
},
"overwrite":{
"license":{
"title":"MIT License",
"text":"license",
"type":"dialog",
"uri":"www/data-transport/resources/license.md"
},
"source-code":{
"text":"Source Code",
"type":"redirect",
"url":"https://hiplab.mc.vanderbilt.edu/git/hiplab/data-transport"
},
"the-story":{
"title":"History",
"text":"History","type":"dialog","uri":"www/data-transport/about/the-story.md"
},
"about-etl":{
"title":"data-transport - ETL",
"text":"Run ETL", "type":"dialog",
"uri":"www/data-transport/tutorials/about-etl.md"
}
},
"footer":[{"text":"Health Information Privacy Laboratory"},{"text":"Powered By - QCMS"}]
}
}

@ -0,0 +1,95 @@
{
"system": {
"logo": "www/html/_assets/images/logo.png",
"context": "",
"theme": "oss",
"app": {
"debug": true,
"port": 8000
},
"version": 0.1,
"source": {
"id": "_cloud",
"auth": "nextcloud-auth.json",
"key": "/home/steve/dev/data/qcms/dev-qcms.key"
},
"data": {
"logger": {
"provider": "console"
}
}
},
"plugins": {
"info": [
"_data",
"about",
"product","registry"
]
},
"layout": {
"header": {
"title": "data-transport",
"logo": true,
"subtitle": "Simple/Seamless Read, Write & Streaming - Powered by Pandas"
},
"icons": [],
"root": "www/html",
"index": "index.html",
"on": {
"load": {
}
},
"order": {
"menu": [
"docs",
"wizard",
"setup",
"about"
]
},
"overwrite": {
"design and credit": {
"title": "Design & Credit",
"text": "Design/Credit",
"type": "dialog",
"uri": "www/html/about/design-and-credit.md"
},
"tutorials": {
"text": "notebooks",
"type": "redirect",
"url": "https://github.com/lnyemba/data-transport/src/branch/v2.0/notebooks"
},
"wizard": {
"title": "auth-file Generator",
"text": "auth-file Generator",
"type": "dialog",
"uri": "www/html/wizard/wizard.html"
},
"transport": {
"text": "ETL - CLI",
"type": "redirect"
},
"source code": {
"title": "Source Code",
"text": "Source Code",
"type": "redirect",
"url": "https://hiplab.mc.vanderbilt.edu/git/hiplab/data-transport"
},
"feedback": {
"title": "Feedback",
"text": "Feedback",
"type": "redirect",
"url": "https://dev.the-phi.com/cloud/apps/forms/s/CXqXgBaSk7qkgammbqALWfPM"
}
},
"footer": [
{
"text": "Health Information Privacy Laboratory"
},
{
"text": "Powered By - QCMS"
}
]
}
}

@ -0,0 +1,10 @@
,community edition,enterprise edition
NoSQL <div class="small">mongodb; couchdb ...</div>,yes,yes
RDBMS/SQL <div class="small">PostgreSQL; SQL Server; MySQL ...</div></div>,yes,yes
Cloud <div class="small">s3; redshift; bigquery; databricks ...</div>,yes,yes
Warehouse <div class="small">Iceberg; Drill ...</div>,yes,yes
Other <div class="small">http; MQTT; Files ...</div>,yes,yes
Plugins <div class="small">native python</div>,yes,yes
Command Line (CLI) <div class="small">ETL & setting up registry</div>,yes,yes
Logging/Monitoring,no,yes
Streaming,no,yes
Can't render this file because it contains an unexpected character in line 2 and column 18.

@ -0,0 +1,62 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.17 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.17">
<diagram name="Page-1" id="ontOpGGeyPPU7iH7FkDo">
<mxGraphModel dx="1434" dy="844" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-3" target="rpdVHkOTuV7LQ5_BBYuJ-11" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="650" y="235" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-3" value="«plugin»&lt;br&gt;&lt;b&gt;Plug02&lt;/b&gt;" style="html=1;dropTarget=0;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="550" y="330" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-4" value="" style="shape=module;jettyWidth=8;jettyHeight=4;" parent="rpdVHkOTuV7LQ5_BBYuJ-3" vertex="1">
<mxGeometry x="1" width="20" height="20" relative="1" as="geometry">
<mxPoint x="-27" y="7" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-5" target="rpdVHkOTuV7LQ5_BBYuJ-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-5" value="«plugin»&lt;br&gt;&lt;b&gt;Plug01&lt;/b&gt;" style="html=1;dropTarget=0;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="75" y="330" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-6" value="" style="shape=module;jettyWidth=8;jettyHeight=4;" parent="rpdVHkOTuV7LQ5_BBYuJ-5" vertex="1">
<mxGeometry x="1" width="20" height="20" relative="1" as="geometry">
<mxPoint x="-27" y="7" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-11" target="rpdVHkOTuV7LQ5_BBYuJ-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-11" value="&lt;p style=&quot;margin:0px;margin-top:6px;text-align:center;&quot;&gt;&lt;b&gt;Data-Transport&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;+ read: pandas.DataFrame&lt;br&gt;+ write: pandas.DataFrame&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;+ stream: pandas.DataFrame&lt;/p&gt;" style="align=left;overflow=fill;html=1;dropTarget=0;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="75" y="190" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-12" value="" style="shape=component;jettyWidth=8;jettyHeight=4;" parent="rpdVHkOTuV7LQ5_BBYuJ-11" vertex="1">
<mxGeometry x="1" width="20" height="20" relative="1" as="geometry">
<mxPoint x="-24" y="4" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=none;endFill=0;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-32" target="rpdVHkOTuV7LQ5_BBYuJ-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=default;startArrow=none;startFill=0;jumpStyle=none;endArrow=none;endFill=0;dashed=1;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-32" target="rpdVHkOTuV7LQ5_BBYuJ-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-32" value="functions registered and setup in a pipeline" style="shape=note2;boundedLbl=1;whiteSpace=wrap;html=1;size=25;verticalAlign=middle;align=left;labelBackgroundColor=none;fontStyle=0;textShadow=0;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="290" y="430" width="225" height="70" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-38" target="rpdVHkOTuV7LQ5_BBYuJ-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-38" value="Data Transport component pass data to other components" style="shape=note2;boundedLbl=1;whiteSpace=wrap;html=1;size=25;verticalAlign=middle;align=left;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="350" y="100" width="240" height="75" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

@ -0,0 +1,73 @@
<mxfile host="Electron" modified="2024-05-29T23:41:59.826Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.4.8 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="s2a9zVy41cilX0VorJTO" version="24.4.8" type="device">
<diagram name="Page-1" id="A6URRxjV3FvGYSSoeV8o">
<mxGraphModel dx="1434" dy="841" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="kf2t0_fmiwDxODz747Ub-1" value="Load Configuration" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="150" y="290" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-2" value="" style="html=1;verticalAlign=bottom;endArrow=open;rounded=0;" edge="1" source="kf2t0_fmiwDxODz747Ub-1" parent="1" target="kf2t0_fmiwDxODz747Ub-3">
<mxGeometry relative="1" as="geometry">
<mxPoint x="130" y="490" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-9" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-3" target="kf2t0_fmiwDxODz747Ub-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-3" value="Read Data" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="150" y="400" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-8" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};" vertex="1" parent="1">
<mxGeometry x="350" y="380" width="10" height="80" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-10" value="Database # 1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="450" y="340" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-11" value="" style="edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=default;rounded=0;" edge="1" source="kf2t0_fmiwDxODz747Ub-10" parent="1" target="kf2t0_fmiwDxODz747Ub-17">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="430" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-13">
<mxGeometry relative="1" as="geometry">
<mxPoint x="650" y="420" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-13" value="Database # 2" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="450" y="400" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-15" target="kf2t0_fmiwDxODz747Ub-17">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-15" value="Database # 3" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="450" y="460" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-17" target="kf2t0_fmiwDxODz747Ub-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-17" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};direction=west;" vertex="1" parent="1">
<mxGeometry x="650" y="380" width="10" height="80" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-20" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=default;" vertex="1" parent="1">
<mxGeometry x="710" y="405" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-23" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;dashPattern=8 8;fillColor=#ffe6cc;strokeColor=#d79b00;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-22" target="kf2t0_fmiwDxODz747Ub-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-22" value="Loading from a JSON configuration file (array/list). Each entry&#39;s source follows the auth-file specifications" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="345" y="160" width="225" height="100" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

@ -0,0 +1,62 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.17 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.17">
<diagram name="Page-1" id="ontOpGGeyPPU7iH7FkDo">
<mxGraphModel dx="1434" dy="844" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-3" target="rpdVHkOTuV7LQ5_BBYuJ-11" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="650" y="235" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-3" value="«plugin»&lt;br&gt;&lt;b&gt;Plug02&lt;/b&gt;" style="html=1;dropTarget=0;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="550" y="330" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-4" value="" style="shape=module;jettyWidth=8;jettyHeight=4;" parent="rpdVHkOTuV7LQ5_BBYuJ-3" vertex="1">
<mxGeometry x="1" width="20" height="20" relative="1" as="geometry">
<mxPoint x="-27" y="7" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-5" target="rpdVHkOTuV7LQ5_BBYuJ-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-5" value="«plugin»&lt;br&gt;&lt;b&gt;Plug01&lt;/b&gt;" style="html=1;dropTarget=0;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="75" y="330" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-6" value="" style="shape=module;jettyWidth=8;jettyHeight=4;" parent="rpdVHkOTuV7LQ5_BBYuJ-5" vertex="1">
<mxGeometry x="1" width="20" height="20" relative="1" as="geometry">
<mxPoint x="-27" y="7" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-11" target="rpdVHkOTuV7LQ5_BBYuJ-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-11" value="&lt;p style=&quot;margin:0px;margin-top:6px;text-align:center;&quot;&gt;&lt;b&gt;Data-Transport&lt;/b&gt;&lt;/p&gt;&lt;hr size=&quot;1&quot; style=&quot;border-style:solid;&quot;&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;+ read: pandas.DataFrame&lt;br&gt;+ write: pandas.DataFrame&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-left:8px;&quot;&gt;+ stream: pandas.DataFrame&lt;/p&gt;" style="align=left;overflow=fill;html=1;dropTarget=0;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="75" y="190" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-12" value="" style="shape=component;jettyWidth=8;jettyHeight=4;" parent="rpdVHkOTuV7LQ5_BBYuJ-11" vertex="1">
<mxGeometry x="1" width="20" height="20" relative="1" as="geometry">
<mxPoint x="-24" y="4" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;endArrow=none;endFill=0;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-32" target="rpdVHkOTuV7LQ5_BBYuJ-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=default;startArrow=none;startFill=0;jumpStyle=none;endArrow=none;endFill=0;dashed=1;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-32" target="rpdVHkOTuV7LQ5_BBYuJ-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-32" value="functions registered and setup in a pipeline" style="shape=note2;boundedLbl=1;whiteSpace=wrap;html=1;size=25;verticalAlign=middle;align=left;labelBackgroundColor=none;fontStyle=0;textShadow=0;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="290" y="430" width="225" height="70" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;" parent="1" source="rpdVHkOTuV7LQ5_BBYuJ-38" target="rpdVHkOTuV7LQ5_BBYuJ-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="rpdVHkOTuV7LQ5_BBYuJ-38" value="Data Transport component pass data to other components" style="shape=note2;boundedLbl=1;whiteSpace=wrap;html=1;size=25;verticalAlign=middle;align=left;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="350" y="100" width="240" height="75" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

@ -0,0 +1,38 @@
.border {
border:1px solid #CAD5E0 ;
}
.border-round {
padding:6px;
border-radius:8px;
}
.border-round-top-left{
border-top-left-radius: 8px;
padding:6px;
}
.border-round-top-right{
border-top-right-radius: 8px;
padding:6px;
}
.border-round-bottom-right{
border-bottom-right-radius: 8px;
padding:6px;
}
.border-round-bottom-left{
border-bottom-left-radius: 8px;
padding:6px;
}
.border-right{
border-right:1px solid #CAD5E0;
}
.border-left{
border-left:1px solid #CAD5E0;
}
.border-bottom { border-bottom:1px solid #CAD5E0}
.border-top { border-top:1px solid #CAD5E0}

@ -0,0 +1,19 @@
/**
* This file styles the footer of the page
*/
.footer {
text-align:center;
display:grid;
grid-template-columns: repeat(3,1fr);
gap:4px;
padding:8px;
font-size:12px;
color:black;
align-items: center;
align-content: center;
text-transform: capitalize;
/* background-color: rgba(255,255,255,0.8); */
grid-column: 1 /span 2;
}

@ -0,0 +1,3 @@
.main .header { display:grid; grid-template-columns:64px auto; gap:4px}
.main .header .title {font-size:28px; font-weight:bold}
.main .header img {width:55px; height:55px;}

@ -0,0 +1,22 @@
.main {
height:98vh; display:grid; grid-template-columns:70% auto; gap:4px;
grid-template-rows:70px 40px auto 32px;
padding-left:2%; padding-right:2%;
line-height: 1.5; font-size:16px; font-family: sans-serif; font-weight:lighter;
}
.main .content{
align-self:center;
}
.main .pane {border-left:1px solid #CAD5E0; height:100%; padding:8px;}
.bold {font-weight:bold}
.small-text {font-size:12px; font-weight:lighter; color :#000000;}
.active {cursor:pointer; padding:2px; margin:2px; border-bottom:2px solid transparent}
.active:hover {border-bottom-color: #4682b4;}
/**
*
*/
.large-text {font-weight:bold; font-size:28px;}

@ -0,0 +1,78 @@
.menu {
padding:8px;
border:1px solid #CAD5E0 ;
display:grid;
grid-column: 1 / span 2;
grid-template-columns: 92px repeat(7,auto);
gap:4px;
text-transform: capitalize;
align-items: center;
}
.menu .icon {padding:4px;}
.menu .icon img {width:30px; height:30px;}
.menu .item {
font-weight:bold;
cursor:pointer;
padding:4px;
text-align: left;
}
.menu .sub-menu {
display:none;
position:absolute;
margin-top:2px;
min-width:10%;
z-index:90;
padding:8px;
font-weight:lighter;
text-align:left;
align-items:left;
background-color: rgba(255,255,255,0.8);
}
.menu .item:hover .sub-menu{
display:block;
height:auto;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}

@ -0,0 +1,2 @@
.main .pane { height:auto;}
.main .pane iframe{ width:100%; border:0px; height:80%;}

@ -0,0 +1,38 @@
.border {
border:1px solid #CAD5E0 ;
}
.border-round {
padding:6px;
border-radius:8px;
}
.border-round-top-left{
border-top-left-radius: 8px;
padding:6px;
}
.border-round-top-right{
border-top-right-radius: 8px;
padding:6px;
}
.border-round-bottom-right{
border-bottom-right-radius: 8px;
padding:6px;
}
.border-round-bottom-left{
border-bottom-left-radius: 8px;
padding:6px;
}
.border-right{
border-right:1px solid #CAD5E0;
}
.border-left{
border-left:1px solid #CAD5E0;
}
.border-bottom { border-bottom:1px solid #CAD5E0}
.border-top { border-top:1px solid #CAD5E0}

@ -0,0 +1,19 @@
/**
* This file styles the footer of the page
*/
.footer {
text-align:center;
display:grid;
grid-template-columns: repeat(3,1fr);
gap:4px;
padding:8px;
font-size:12px;
color:black;
align-items: center;
align-content: center;
text-transform: capitalize;
/* background-color: rgba(255,255,255,0.8); */
grid-column: 1 /span 2;
}

@ -0,0 +1,3 @@
.main .header { display:grid; grid-template-columns:64px auto; gap:4px}
.main .header .title {font-size:28px; font-weight:bold}
.main .header img {width:55px; height:55px;}

@ -0,0 +1,37 @@
/**
* This is the default window and we will have to hide the pane (side)
*/
.main {height:98vh; display:grid; grid-template-columns:75% auto; gap:4px;
grid-template-rows:70px 40px auto 32px;
padding-left:2%; padding-right:2%;
}
.main .header { display:grid; grid-template-columns:64px auto; gap:4px; align-items: center;}
.main .header .title {font-size:28px; font-weight:bold}
.main .header img {width:80px; height:80px;}
.main .index{
align-self:center;
padding:8px;
}
.main .menu {border:1px solid transparent; background-color:#f3f3f3;}
.main .pane {border-left:1px solid #CAD5E0; height:100%; padding:8px; line-height:1.5; font-size: 14px;}
.main .pane div:first-child {margin-top:4px; background-color:#f3f3f3; border-radius: 8px; padding:8px; min-height:150px}
.search-box {display:block; grid-template-columns: none;}
.main .content{
align-self:center;
}
.bold {font-weight:bold}
.small-text {font-size:12px; font-weight:lighter; color :#000000;}
.active {cursor:pointer; padding:2px; margin:2px; border-bottom:2px solid transparent}
.active:hover {border-bottom-color: #4682b4;}
/**
*
*/
.large-text {font-weight:bold; font-size:28px;}

@ -0,0 +1,110 @@
.menu {
padding:8px;
border:1px solid #CAD5E0 ;
display:grid;
grid-column: 1 / span 2;
grid-template-columns: 92px repeat(7,auto);
gap:4px;
text-transform: capitalize;
align-items: center;
}
.menu .icon {padding:4px;}
.menu .icon img {width:30px; height:30px;}
.menu .item {
font-weight:bold;
cursor:pointer;
padding:4px;
text-align: left;
}
.menu .sub-menu {
display:none;
position:absolute;
margin-top:2px;
min-width:10%;
z-index:90;
padding:8px;
font-weight:lighter;
text-align:left;
align-items:left;
background-color: rgba(255,255,255,0.8);
}
.menu .item:hover .sub-menu{
display:block;
height:auto;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}

@ -0,0 +1,38 @@
.border {
border:1px solid #CAD5E0 ;
}
.border-round {
padding:6px;
border-radius:8px;
}
.border-round-top-left{
border-top-left-radius: 8px;
padding:6px;
}
.border-round-top-right{
border-top-right-radius: 8px;
padding:6px;
}
.border-round-bottom-right{
border-bottom-right-radius: 8px;
padding:6px;
}
.border-round-bottom-left{
border-bottom-left-radius: 8px;
padding:6px;
}
.border-right{
border-right:3px dotted #CAD5E0;
}
.border-left{
border-left:3px dotted gray;
}
.border-bottom { border-bottom:1px dotted gray;}
.border-top { border-top:3px dotted gray;}

@ -0,0 +1,22 @@
/**
* This file styles the footer of the page
*/
/* .main .footer { grid-column: 1 / span 2; font-size:13px; font-weight: lighter; padding:8px;} */
.footer {
text-align:center;
display:grid;
grid-template-columns: repeat(3,1fr);
gap:4px;
padding:8px;
font-size:12px;
color:black;
align-items: center;
align-content: center;
text-transform: capitalize;
/* background-color: rgba(255,255,255,0.8); */
grid-column: 1 /span 2;
}

@ -0,0 +1,13 @@
.main .header {
grid-row:1;
grid-column: 1 / span 2;
display:grid;
grid-template-columns: 50px auto; gap:4px;
line-height: 1;
}
.main .header .title {font-size:28px; text-transform: capitalize; font-weight:bold}
.main .header .subtitle {font-size:14px}
.main .header img { width:44px; height:44px;}

@ -0,0 +1,55 @@
.main {
margin:10px;
padding:4px;
display:grid;
grid-template-columns: 50% 50% ; gap:4px;
grid-template-rows: 48px 64px auto 32px;
font-family: sans-serif;
font-weight: lighter;
font-size:18px;
line-height: 1.5;
justify-items: normal;
;
height:96vh;
}
.main .content {
grid-row:3;
grid-column: 1 ;
text-wrap: wrap;
height:100%;
display:grid;
align-content: start;
}
.main .content #index {
text-align: left;
text-wrap: wrap;
}
p {
margin-top:22px;
}
table {
width:99%;
border: 1px solid #CAD5E0;
}
table td {padding:4px; margin:4px;}
table thead {
font-weight:bold;
background-color:#f3f3f3;
}
.bold {font-weight:bold}
.small-text {font-size:12px; font-weight:lighter; color :#000000;}
.active {cursor:pointer; padding:2px; margin:2px; border-bottom:2px solid transparent}
.active:hover {border-bottom-color: #4682b4;}
/**
*
*/
.large-text {font-weight:bold; font-size:28px;}

@ -0,0 +1,110 @@
.menu {
padding:8px;
border-bottom:3px dotted gray ;
display:grid;
grid-column: 1 / span 2;
grid-template-columns: 92px repeat(7,auto);
gap:4px;
text-transform: capitalize;
align-items: center;
}
.menu .icon {padding:4px;}
.menu .icon img {width:30px; height:30px;}
.menu .item {
font-weight:bold;
cursor:pointer;
padding:4px;
text-align: left;
}
.menu .sub-menu {
display:none;
position:absolute;
margin-top:2px;
min-width:10%;
z-index:90;
padding:8px;
font-weight:lighter;
text-align:left;
align-items:left;
background-color: rgba(255,255,255,0.8);
}
.menu .item:hover .sub-menu{
display:block;
height:auto;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}

@ -0,0 +1,14 @@
.main .pane {
border-left:3px dotted gray;
grid-column: 2;
font-family: sans-serif;
padding-left: 10px;
}
.pane iframe {
border:1px solid transparent;
width:99%;
height:100%;
}

@ -0,0 +1,38 @@
.border {
border:1px solid #CAD5E0 ;
}
.border-round {
padding:6px;
border-radius:8px;
}
.border-round-top-left{
border-top-left-radius: 8px;
padding:6px;
}
.border-round-top-right{
border-top-right-radius: 8px;
padding:6px;
}
.border-round-bottom-right{
border-bottom-right-radius: 8px;
padding:6px;
}
.border-round-bottom-left{
border-bottom-left-radius: 8px;
padding:6px;
}
.border-right{
border-right:1px solid #CAD5E0;
}
.border-left{
border-left:1px solid #CAD5E0;
}
.border-bottom { border-bottom:1px solid #CAD5E0}
.border-top { border-top:1px solid #CAD5E0}

@ -0,0 +1,21 @@
/**
* This file styles the footer of the page
*/
.footer {
grid-row:5;
margin-top:10px;
text-align:center;
display:grid;
grid-template-columns: repeat(3,1fr);
gap:4px;
padding:8px;
font-size:12px;
color:black;
align-items: center;
align-content: center;
text-transform: capitalize;
/* background-color: rgba(255,255,255,0.8);
}

@ -0,0 +1,7 @@
.main .header {display:grid; grid-template-columns:64px auto; gap:4px; width:100%; align-items:center;}
.main .header .icon {width:64px; height:64px;}
.main .header .icon img {width:64px; height:64px;}
.main .header .title { font-size:32px; text-transform: uppercase; font-weight:bold}
.main .header .subtitle {font-style:italic;font-size:14px; color:gray; text-transform: capitalize;}

@ -0,0 +1,50 @@
/**
* This file implements theme Open Source Software, the expectation is just a pager that presents a tool/software
*/
body, ul, p, select {
font-size: 16px;
font-weight:lighter;
font-family:sans-serif;
line-height:1.5;
}
.main {
display:grid;
grid-template-columns: 100%;;
margin:1%;
margin-left:10%;
margin-right:10%;
gap:4px;
width:80%;
}
.main .content{
grid-row:4;
align-self:center;
height:100%;
width:100%;
}
.main .content .banner {
background-repeat: no-repeat;
background-size: cover;
background-position: center;
height:200px;
align-items: center;
align-content: center;
display: grid;
}
/* .main .pane {border-left:1px solid #CAD5E0; height:100%; padding:8px;} */
.bold {font-weight:bold}
.small-text {font-size:12px; font-weight:lighter; color :#000000;}
.active {cursor:pointer; padding:2px; margin:2px; border-bottom:2px solid transparent}
.active:hover {border-bottom-color: #4682b4;}
/**
*
*/
.large-text {font-weight:bold; font-size:28px;}

@ -0,0 +1,82 @@
.menu .icon {padding:4px; align-items:center; display:grid;}
.menu .icon img {width:30px; height:30px;}
.main .menu .sub-menu {
display:none;
position:absolute;
margin-top:2px;
min-width:10%;
z-index:90;
padding:8px;
font-weight:lighter;
text-align:left;
align-items:left;
background-color: rgba(255,255,255,0.8);
}
.main .menu .item {
font-weight:bold;
cursor:pointer;
padding:4px;
text-align: left;
}
.main .menu .item:hover .sub-menu{
display:block;
height:auto;
}
.main .menu {
padding:8px;
grid-row:2;
width:100%;
display:none;
/* grid-row:2; grid-column:1 ; */
grid-template-columns: 92px repeat(7,auto);
gap:4px;
text-transform: capitalize;
border:0; height:48px; padding:0px;
display:grid; grid-template:64px repeat(6,1fr); gap:4px;
/* background-color: #f3f3f3; */
align-items: center;
}
.main .menu .icon .button {
border:1px solid #CAD5E0; border-radius:8px; padding:2px;
;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}

@ -0,0 +1 @@
.main .pane {display:block}

@ -0,0 +1,3 @@
@media (max-width: 480px) {
}

@ -0,0 +1,38 @@
.border {
border:1px solid #CAD5E0 ;
}
.border-round {
padding:6px;
border-radius:8px;
}
.border-round-top-left{
border-top-left-radius: 8px;
padding:6px;
}
.border-round-top-right{
border-top-right-radius: 8px;
padding:6px;
}
.border-round-bottom-right{
border-bottom-right-radius: 8px;
padding:6px;
}
.border-round-bottom-left{
border-bottom-left-radius: 8px;
padding:6px;
}
.border-right{
border-right:1px solid #CAD5E0;
}
.border-left{
border-left:1px solid #CAD5E0;
}
.border-bottom { border-bottom:1px solid #CAD5E0}
.border-top { border-top:1px solid #CAD5E0}

@ -0,0 +1,19 @@
/**
* This file styles the footer of the page
*/
.footer {
text-align:center;
display:grid;
grid-template-columns: repeat(3,1fr);
gap:4px;
padding:8px;
font-size:12px;
color:black;
align-items: center;
align-content: center;
text-transform: capitalize;
/* background-color: rgba(255,255,255,0.8); */
grid-column: 1 /span 2;
}

@ -0,0 +1,3 @@
.main .header { display:grid; grid-template-columns:64px auto; gap:4px}
.main .header .title {font-size:28px; font-weight:bold}
.main .header img {width:55px; height:55px;}

@ -0,0 +1,22 @@
.main {
height:98vh; display:grid; grid-template-columns:70% auto; gap:4px;
grid-template-rows:70px 40px auto 32px;
padding-left:2%; padding-right:2%;
line-height: 1.5; font-size:16px; font-family: sans-serif; font-weight:lighter;
}
.main .content{
align-self:center;
}
.main .pane {border-left:1px solid #CAD5E0; height:100%; padding:8px;}
.bold {font-weight:bold}
.small-text {font-size:12px; font-weight:lighter; color :#000000;}
.active {cursor:pointer; padding:2px; margin:2px; border-bottom:2px solid transparent}
.active:hover {border-bottom-color: #4682b4;}
/**
*
*/
.large-text {font-weight:bold; font-size:28px;}

@ -0,0 +1,79 @@
.menu {
padding:8px;
border:1px solid #CAD5E0 ;
display:grid;
grid-column: 1 / span 2;
grid-template-columns: 92px repeat(7,auto);
gap:4px;
text-transform: capitalize;
align-items: center;
}
.menu .icon {padding:4px;}
.menu .icon img {width:30px; height:30px;}
.menu .item {
font-weight:bold;
cursor:pointer;
padding:4px;
text-align: left;
}
.menu .sub-menu {
display:none;
position:absolute;
margin-top:2px;
min-width:10%;
z-index:90;
padding:8px;
font-weight:lighter;
text-align:left;
align-items:left;
background-color: rgba(255,255,255,0.8);
}
.menu .item:hover .sub-menu{
display:block;
height:auto;
}
/**
* TAB SPECIFICATIONS WITH RADIO BUTTONS AND LABELS
*/
.tab-content table { width:99%; border-radius: 8px; padding:8px; border:1px solid #d3d3d3;}
.tab-content table tr:nth-child(even) {background-color: #f3f3f3;}
/* .tab-content {width:80%;} */
.tabs {display:grid; grid-template-columns: repeat(auto-fit,209px); gap:0px; align-content:center;
/* background-color: #f3f3f3; */
padding-top:4px;
padding-left:4px;
padding-right:4px;
}
.tabs input[type=radio] {display:none; }
.tabs input[type=radio] + label { font-weight:lighter;
border:1px solid transparent;
border-bottom-color: #CAD5E0;
background-color: #f3f3f3;
padding:8px;
padding-right:10px; padding-left:10px;
cursor:pointer
}
.tabs input[type=radio]:checked +label {
background-color: #ffffff;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
font-weight:bold;
border-color: #CAD5E0;
border-bottom-color: #FFFFFF;
}

@ -0,0 +1,67 @@
<mxfile host="Electron" modified="2024-05-29T23:33:06.660Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.4.8 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="oZedaAOCRPCz-oQfQCot" version="24.4.8" type="device">
<diagram name="Page-1" id="A6URRxjV3FvGYSSoeV8o">
<mxGraphModel dx="1434" dy="841" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="kf2t0_fmiwDxODz747Ub-1" value="Load Configuration" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;" vertex="1" parent="1">
<mxGeometry x="150" y="290" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-2" value="" style="html=1;verticalAlign=bottom;endArrow=open;rounded=0;" edge="1" source="kf2t0_fmiwDxODz747Ub-1" parent="1" target="kf2t0_fmiwDxODz747Ub-3">
<mxGeometry relative="1" as="geometry">
<mxPoint x="130" y="490" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-9" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-3" target="kf2t0_fmiwDxODz747Ub-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-3" value="Read Data" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;" vertex="1" parent="1">
<mxGeometry x="150" y="400" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-8" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};" vertex="1" parent="1">
<mxGeometry x="350" y="380" width="10" height="80" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-10" value="Database # 1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;" vertex="1" parent="1">
<mxGeometry x="450" y="340" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-11" value="" style="edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=default;rounded=0;" edge="1" source="kf2t0_fmiwDxODz747Ub-10" parent="1" target="kf2t0_fmiwDxODz747Ub-17">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="430" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-13">
<mxGeometry relative="1" as="geometry">
<mxPoint x="650" y="420" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-13" value="Database # 2" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;" vertex="1" parent="1">
<mxGeometry x="450" y="400" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-15" target="kf2t0_fmiwDxODz747Ub-17">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-15" value="Database # 3" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;" vertex="1" parent="1">
<mxGeometry x="450" y="460" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-17" target="kf2t0_fmiwDxODz747Ub-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-17" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};direction=west;" vertex="1" parent="1">
<mxGeometry x="650" y="380" width="10" height="80" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-20" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=default;" vertex="1" parent="1">
<mxGeometry x="710" y="405" width="30" height="30" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

@ -0,0 +1,73 @@
<mxfile host="Electron" modified="2024-05-29T23:41:59.826Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.4.8 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="s2a9zVy41cilX0VorJTO" version="24.4.8" type="device">
<diagram name="Page-1" id="A6URRxjV3FvGYSSoeV8o">
<mxGraphModel dx="1434" dy="841" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="kf2t0_fmiwDxODz747Ub-1" value="Load Configuration" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="150" y="290" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-2" value="" style="html=1;verticalAlign=bottom;endArrow=open;rounded=0;" edge="1" source="kf2t0_fmiwDxODz747Ub-1" parent="1" target="kf2t0_fmiwDxODz747Ub-3">
<mxGeometry relative="1" as="geometry">
<mxPoint x="130" y="490" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-9" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-3" target="kf2t0_fmiwDxODz747Ub-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-3" value="Read Data" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="150" y="400" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-8" target="kf2t0_fmiwDxODz747Ub-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-8" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};" vertex="1" parent="1">
<mxGeometry x="350" y="380" width="10" height="80" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-10" value="Database # 1" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="450" y="340" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-11" value="" style="edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=default;rounded=0;" edge="1" source="kf2t0_fmiwDxODz747Ub-10" parent="1" target="kf2t0_fmiwDxODz747Ub-17">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="430" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-13">
<mxGeometry relative="1" as="geometry">
<mxPoint x="650" y="420" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-13" value="Database # 2" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="450" y="400" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-15" target="kf2t0_fmiwDxODz747Ub-17">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-15" value="Database # 3" style="rounded=1;whiteSpace=wrap;html=1;arcSize=40;strokeWidth=1.5;" vertex="1" parent="1">
<mxGeometry x="450" y="460" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;curved=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-17" target="kf2t0_fmiwDxODz747Ub-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-17" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={&quot;curved&quot;:0,&quot;rounded&quot;:0};direction=west;" vertex="1" parent="1">
<mxGeometry x="650" y="380" width="10" height="80" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-20" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=default;" vertex="1" parent="1">
<mxGeometry x="710" y="405" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-23" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;dashPattern=8 8;fillColor=#ffe6cc;strokeColor=#d79b00;" edge="1" parent="1" source="kf2t0_fmiwDxODz747Ub-22" target="kf2t0_fmiwDxODz747Ub-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="kf2t0_fmiwDxODz747Ub-22" value="Loading from a JSON configuration file (array/list). Each entry&#39;s source follows the auth-file specifications" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="345" y="160" width="225" height="100" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

@ -0,0 +1,134 @@
<style>
.transport, .wizard-frame {line-height: 1.5; font-weight: lighter; font-family:sans-serif; font-size:14px;}
.transport .large-text {font-size:32px}
.main .menu {background-color: #ffffff;}
/* .transport #supported table {
border-spacing: 0px;
border:1px solid #CAD5E0;
width:100%;
border-collapse: collapse;
}
.transport #supported table th {border:0px;}
.transport #supported table td{
border:1px solid #CAD5E0;
margin:0px;
text-transform: capitalize;
} */
/* .dataframe table thead tr{
background-color: #4682b4;color:#FFFFFF;
text-transform: capitalize;
padding:8px; text-align: left; font-weight: bold;
;
} */
.transport .facts {
font-family:sans-serif; font-weight:lighter; line-height: 1.5;
font-size:16px;
height: auto;
}
.transport .facts #features ul,.introduction ul { height:125px}
.transport .facts #install {
grid-row:1; grid-column: 2;
/* border-left:1px solid #CAD5E0; */
padding-left:10px;
}
.transport #facts-right div:first-child{min-height: 250px;}
.transport #facts-left div:first-child{min-height: 250px;}
.transport h3 {
font-size:24px;
margin:0px;
font-family: sans-serif;
border-bottom:1px solid #CAD5E0;
}
.dataframe {
border-collapse: collapse;
margin: 25px 0;
font-size: 0.9em;
font-family: sans-serif;
width:100%;
border:1px solid #CAD5E0;
/* min-width: 400px; */
/* box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); */
}
.dataframe thead tr {
background-color: #4682B4;
color: #ffffff;
text-align: left;
}
.dataframe th,
.dataframe td {
padding: 12px 15px;
}
.dataframe tbody tr {
border-bottom: 1px solid #dddddd;
}
.dataframe tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
}
/* .dataframe tbody tr:last-of-type {
border-bottom: 2px solid #009879;
} */
.dataframe tbody tr.active-row {
font-weight: bold;
color: #009879;
}
.transport .facts {
display:grid;
grid-template-columns: repeat(2,1fr); gap:8px; font-family: sans-serif; font-weight: lighter;
;
}
.transport .banner {
background-image: url("www/html/_assets/images/banner.jpg");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
height:200px;
align-items: center;
align-content: center;
display: grid;
}
</style>
<script>
$(document).ready(function(){
// bootup.init('{{system.context}}',layout)
})
</script>
<div class="transport">
<div align="center" class="banner" >
<div class="large-text">
(Read, Write) Data Anywhere!
</div>
<div align="center" class="bold">
NoSQL <i class="fa-solid fa-minus" sytle="font-size:13px"></i>
SQL<i class="fa-solid fa-minus"></i>
Cloud
</div>
<div align="center">
<span>Version <span id="data-transport-version"></span> Powered by Pandas</span>
</div>
</div>
<div id="facts" class="facts">
<div id="facts-left"></div>
<div id="facts-right"></div>
</div>
<p>
<div align="center" >
<div class="large-text">Thank you,</div>
</div>
</p>
</div>

@ -0,0 +1,14 @@
<div>
<h3>Documentation</h3>
<p >
<div>The documentation is available within the codebase in a folder called <b>notebooks</b>. You will learn to</div>
<ul>
<i class="fa-solid fa-minus"> </i> Read/write to supported databases
<br><i class="fa-solid fa-minus"> </i> Develop plugins for pre/post processing
<br><i class="fa-solid fa-minus"> </i> Use the command line interface (CLI)
</ul>
Feel free to reachout to for questions, feature requests
<br> steve.l.nyemba@vumc.org or steve@the-phi.com
</p>
</div>

@ -0,0 +1,47 @@
<script>
var show_supported = function(){
$('#data-transport-support').slideDown(function(){
jx.dom.hide('bplus')
jx.dom.show('bminus')
})
}
var hide_supported = function(){
$('#data-transport-support').slideUp(function(){
jx.dom.show('bplus')
jx.dom.hide('bminus')
})
}
$(document).ready(function(){
var uri = '{{system.context}}/api/info/about' ;
var http = HttpClient.instance()
http.get(uri,function(x){
var _object = JSON.parse(x.responseText)
jx.dom.set.value('data-transport-support',_object.supported)
jx.dom.set.value('data-transport-version',_object.version)
// setTimeout(function(){
// hide_supported()
// },900)
})
})
</script>
<div>
<h3>Features</h3>
<p>
<ul>
<i class="fa-solid fa-minus"> </i> Built with pandas & designed for & by AI/ML engineers
<br><i class="fa-solid fa-minus"> </i> Support for plugins used in pre/post processing
<br><i class="fa-solid fa-minus"> </i> Read from one source & write to many (different databases)
<br><i class="fa-solid fa-minus"> </i> Includes lightweight ETL command line interface (CLI)
</ul>
</p>
<h3>Supported Technologies</h3>
<div id="data-transport-support"> </div>
</div>

@ -0,0 +1,39 @@
<script>
$(document).ready(()=>{
qcms.source_code()
})
</script>
<div style="height:min-content">
<div class="large-text">Installation</div>
<p>
The assumption here is the you are using virtual environment <b>virtualenv</b> along with <b>pip</b>.
There are various components that can be installed with <b>data-transport</b>. By default <b>SQL</b> support is always available
<ul>
<i class="fa-solid fa-minus"></i> by default sql libraries handle Sqlite3+, Microsoft SQLServer, MySQL, Mariadb, PostgreSQL, duckdb
<br><i class="fa-solid fa-minus"></i> <b>nosql</b> : installs libraries to handle mongodb, cloudant & couchdb
<br><i class="fa-solid fa-minus"></i> <b>cloud</b> : libraries to handle bigquery, databricks, S3, nextcloud
<br><i class="fa-solid fa-minus"></i> <b>warehouse</b> : installs libraries to handle apache iceberg, spark, apache drill
<br><i class="fa-solid fa-minus"></i> <b>other</b> : installs libraries to handle http/https, RabbitMQ, Files
</ul>
</p>
You can specify any combination of <b>nosql, cloud, warehouse, other or all</b>, by default sql support is provided.
<p>
<div class="source-code">
pip install data-transport[nosql,cloud,warehouse,other]@git+https://dev.the-phi.com/git/data-transport/ce
</div>
</p>
A command line interface (CLI) is installed and can be tested by running the following to see what
<p>
<div class="source-code">
$ transport --help</div>
</div>
<div align="left">
<img src="www/html/_assets/images/transport-help.png" style="height:auto">
</div>
</p>
</div>
<div class="details">
</div>

@ -0,0 +1,53 @@
<script>
var InitProduct = function (){
var http = HttpClient.instance()
var uri = '{{system.context}}/api/info/product'
http.get(uri,function(x){
$('.product').html(x.html)
})
}
var intro = {}
intro.show = function (show_ref,hide_ref){
show_ref = '.'+show_ref
hide_ref = '.'+hide_ref
$(hide_ref).slideUp(function(){
$(show_ref).slideDown()
})
}
$(document).ready(function(){
var uri = '{{system.context}}/api/info/about' ;
var http = HttpClient.instance()
http.get(uri,function(x){
var _object = JSON.parse(x.responseText)
// jx.dom.set.value('data-transport-support',_object.supported)
// $('#data-transport-support').html(_object.supported)
jx.dom.set.value('data-transport-version',_object.version)
// var label = $(' .tabs label')[0]
// label.click()
// _layout ={on:{load:{}}}
// _layout.on.load = {'plugins':['www/html/_notes/plugins-intro.html']}
// bootup.init('{{system.context}}',_layout)
})
})
</script>
<div class="introduction">
<div class="large-text">Quick Start</div>
By default basic installation has
<ul>
<li><i class="fa-solid fa-minus"></i> Add a label entry to registry :</li>
<li style="padding-left:48px"> &bull; CLI, learn how</li>
<li style="padding-left:48px"> &bull; Graphical User Interface, learn how</li>
<li><i class="fa-solid fa-minus"></i> Import in python code</li>
</ul>
</div>

@ -0,0 +1 @@
These are basic <b>python functions</b> with a single argument (data:pd.DataFrame). The functions can be used as a pipeline to be called in the context of pre/post processing.

@ -0,0 +1,76 @@
<script>
$(document).ready(()=>{
qcms.source_code()
})
</script>
<div>
<div class="bold">What is the registry</div>
<p> <b>data-transport</b> uses a registry to store database authentication information and referenced by a human readable label.
<ul style="list-style: none;">
<li> <i class="fa-solid fa-minus"></i> The code uses the labels instead of username,passwords ...</li>
<li> <i class="fa-solid fa-minus"></i> This makes sharing notebooks (Jupyter, Zeppelin, ...) without dissipating sensitive information</li>
</ul>
</p>
<div class="bold">Initialize Registry</div>
<p>
The registry can be initialized through the command line (CLI) or in code.
<br>A folder will be created in your home folder <b>$HOME/.data-transport/transport-registry.json</b>
</p>
<p>
<div style="display:grid; grid-template-columns: 50% 50%; gap:4px">
<div>
<b>Command line (CLI)</b>
<p>
<div class="source-code">
# creates folders and files needed
<br>$ transport registry reset < your email >
</div>
<p>
Create a file <b>http-auth.json</b> and it should contain the following
<div class="source-code">
{<br>"provider":"http",
"url":"https://raw.githubusercontent.com/codeforamerica/ohana-api/master/data/sample-csv/addresses.csv"
<br>}
</div>
</p>
Add the created file <b>http-auth.json</b> to the registry under the label <b>address-db</b>
<div class="source-code">
$ transport registry --add address-db http-auth.json
</div>
</p>
</p>
</div>
<div style="border-left:4px dotted #CAD5E0; padding-left:8px;">
<b>In code</b>
<p>
<div class="source-code">
import transport
import io
import json
#
# transport.registry.exists()
_email = 'steve@the-phi.com'
transport.registry.init(_email)
#
# Adding the entry to the registry now that is initialized
_authStr = {"provider":"http",
"url":"https://raw.githubusercontent.com/codeforamerica/ohana-api/master/data/sample-csv/addresses.csv"
}
file = io.StringIO(json.dumps(_authStr))
transport.registry.set('address-db',file)
</div>
</p>
</div>
</div>
</p>
</div>

@ -0,0 +1,23 @@
<div class="paragraph border-round border shadow">
<h3>Run ETL (transport)</h3>
<p>
Simple ETL from the commandline (CLI), you can generate a sample <b>ETL configuration</b>,
<div class="source-code">
$ transport generate ./my-etl-config.json
</div>
<ul>
<i class="fa-solid fa-minus"> </i> The configuration file will specify source and targets for the data.
<br><i class="fa-solid fa-minus"> </i> <b>source</b>, https and <b>targets</b> are both CSV file and SQLite 3+ database
</ul>
Perform the ETL Job given the configuration specifications
<div class="source-code">
$ transport apply ./my-etl-config.json
</div>
</p>
</div>

@ -0,0 +1,90 @@
<script>
$(document).ready(function(){
qcms.source_code()
// $('.source-code').each((_index)=>{
// var _code = $('.source-code')[_index]
// var lines = $(_code).text().split('\n')
// $(_code).empty()
// lines.forEach((line)=>{
// line = line.replace(/import/g,'<b>import</b>').replace(/def/g,'<b>def</b>').replace(/\#/g,'<i style="color:darkgray">#').replace(/#.+(\n$)/g,'</i>')
// line = line.replace(/print/g,'<b>print</b>')
// $(_code).append( $('<div></div>').html(line))
// })
// })
})
</script>
<div style="display:grid; grid-template-columns: calc(50% - 4px) 4px 50%; gap:8px;">
<div>
<div class="bold">Collaborative development</div>
<p>
<b>0.</b> In this scenario we assume the registry has been initialized and that an entry has been added (CLI).
<div class="source-code">
# transport registry add --help
<br>$ transport registry add address-db http-auth.json
</div>
</p>
The python code would look like the following :
<div class="source-code" >
<b>import</b> transport
<pre>
#
# We are assuming here that the label books-db is an entry in the registry
dbreader = transport.get.reader(label='address-db') # <i>No database credentials</i>
_df = dbreader.read(sql="SELECT * FROM books where postal_code like '946%' ")
print (_df.head())
</pre>
</div>
<p style="border-top:4px dotted #CAD5E0">
<b>1.</b> Alternatively it is possible to directly use the authentication file dubbed "<b>auth-file</b>".
<div class="source-code" >
<b>import</b> transport
<pre>
#
# We are assuming here that the label books-db is an entry in the registry
dbreader = transport.get.reader(auth_file='/home/me/http-auth.json') # <i>No database credentials</i>
_df = dbreader.read(sql="SELECT * FROM books where postal_code like '946%' ")
print (_df.head())
</pre>
</div>
</p>
</div>
<div style="border-left:4px dotted #CAD5E0;"></div>
<div>
<div class="bold">Non-collaborative development</div>
<p>
In this scenario, we are using connectivity parameters in the code. We do <b>NOT recommend</b> this if the code will be used/shared.
</p>
<div class="source-code">
<b>import</b> transport
<pre>
#
# In this scenario we are loading an SQLite3+ database
url= "https://raw.githubusercontent.com/codeforamerica/ohana-api/master/data/sample-csv/addresses.csv"
_args = {"provider":"http","database"}
dbreader = transport.get.reader(**_args) # <i>No database credentials</i>
_df = dbreader.read(sql="SELECT * FROM books where postal_code like '946%' ")
print (_df.head())
</pre>
</div>
<p style="border-top:4px dotted #CAD5E0">
<div class="bold">Learn more</div>
It is possible to <b>initialize the registry</b>; <b>run ETL</b> from your code as well as from the command line (CLI). We compiled this in notebooks available in our code repository
</p>
</div>
</div>

@ -0,0 +1,49 @@
<script>
var show_supported = function(){
$('#data-transport-support').slideDown(function(){
jx.dom.hide('bplus')
jx.dom.show('bminus')
})
}
var hide_supported = function(){
$('#data-transport-support').slideUp(function(){
jx.dom.show('bplus')
jx.dom.hide('bminus')
})
}
$(document).ready(function(){
var uri = '{{system.context}}/api/info/about' ;
var http = HttpClient.instance()
http.get(uri,function(x){
var _object = JSON.parse(x.responseText)
jx.dom.set.value('data-transport-support',_object.supported)
jx.dom.set.value('data-transport-version',_object.version)
setTimeout(function(){
hide_supported()
},900)
})
})
</script>
<div style="display:none">
<p>
<div style="height:28px;display:grid; gap:4px; grid-template-columns: auto 64px;">
<div><h3 >Supported Databases</h3></div>
<div class="active" align="center" style="height:24px">
<div id="bplus" class="fa-solid fa-plus" onclick="show_supported()"></div>
<div id="bminus" class="fa-solid fa-minus" onclick="hide_supported()"></div>
</div>
</div>
<div id="data-transport-support"> </div>
</p>
</div>

@ -0,0 +1,49 @@
import transport
import info
from multiprocessing import Process
import pandas as pd
from io import StringIO
import requests
import cms
import os
@cms.Plugin(mimetype='application/json')
def about (**_args):
return {'license':info.__license__,'author':transport.__app_name__, 'version':transport.__version__, 'supported':transport.supported().to_html(index=False,col_space=0,justify='left').replace("\n","").replace('border="1"','')}
#
# loading notebooks from github
@cms.Plugin(mimetype='application/json')
def _data (**_args) :
_csv = f"""provider,label,doc,url,notebook
etl,ETL,"Built-in ETL CLI program",https://healthcareio.the-phi.com/data-transport,etl.ipynb
mongodb,MongoDB,"mongodb is a NoSQL database developed by mongodb",https://mongodb.com,mongodb.ipynb
mysql,MySQL,"mysql is a relational database developed and maintained by Oracle",https://www.mysql.com,mysql.ipynb
postgresql,PostgreSQL,"postgresql is an object - relational database developed and maintained by PostgreSQL Global Development Group",https://www.postgresql.com,postgresql.ipynb
mssqlserver,MS SQL Server,"SQL Server a relational database server developed by Microsoft",https://www.microsoft.com,mssqlserver.ipynb
sqlite,sqlite,"sqlite is portable relational database",https://www.sqlite.com,sqlite.ipynb
s3,AWS S3,"AWS Simple Storage Service",https://www.aws.amazon.com/s3,s3.ipynb
"""
_df = pd.read_csv(StringIO(_csv))
return _df.drop_duplicates().to_dict(orient='records')
# MEM_PRODUCT_FILE = StringIO(f"""_,community,enterprise
# NoSQL,1,1
# RDBMS/SQL,1,1
# Cloud databases,1,1
# Other (MQTT; Files; https),1,1
# Warehouse,1,1
# """)
@cms.Plugin(mimetype="text/html")
def product(**_args):
_config = _args['config']
path = os.sep.join([_config['layout']['location'],_config['layout']['root'],'_assets','data','products.csv'])
_df = pd.read_csv(path)
return _df.to_html(index=0).replace("&gt;",">").replace("&lt;","<").replace("no",'<i class="fa-solid fa-times" style="color:red"></i>').replace("yes",'<i class="fa-solid fa-check" style="color:green"></i>')
@cms.Plugin(mimetype="application/json")
def registry (**_args):
if not transport.registry.isloaded() :
transport.registry.load()
_repo = transport.registry.DATA
_data = [{'label':key,'provider':_repo[key]['provider'],'plugins':([] if 'plugins' not in _repo[key] else _repo[key]['plugins'])} for key in _repo if 'provider' in _repo[key]]
return _data

@ -0,0 +1,13 @@
### What is data-transport
The **data-transport** and is intended to read, write to any supported databases transparently. The framework lowers the barrier to adoption by using **Python Pandas**, **SQLAlchemy** as foundational components to its architecture. The architecture allows
1. seamless reads and writes regardless of the database vendor (SQL, NoSQL, Cloud ...)
2. separates reads from writes to avoid accidental tampering with data
3. works with pandas for reads and writes
4. support for plugin (functions) to apply against the data as pre/post processing
5. supports a lightweight Extract Transform tool (ETL) as a command line interface (CLI)
### Credits
**Data-transport** was designed and developed at the [Health Information Privacy Laboratory](https://hiplab.mc.vanderbilt.edu) at Vanderbilt University Medical Center with the input of all co-workers, interns post-doctoral fellows

@ -0,0 +1 @@
<iframe src="https://dev.the-phi.com/cloud/apps/forms/s/CXqXgBaSk7qkgammbqALWfPM"></iframe>

@ -0,0 +1,37 @@
<script>
$(document).ready(function(){
var uri = '{{system.context}}/api/info/about'
var http = HttpClient.instance()
http.get(uri,function(x){
_info = JSON.parse(x.responseText)
Object.keys(_info).forEach(_id=>{
if ($('.'+_id).length == 1){
value = _info[_id]
$('.'+_id).html(value.replace(/\n/g,'<br>'))
}
})
})
})
</script>
<style>.legal {height:80vh; line-height: 1.5; font-family:sans-serif; font-size:14px; font-weight:lighter}</style>
<div class="legal">
<div style="background-color: #f3f3f3;padding:8px;">
<span class="author bold"></span>, version <span class="version"></span>
</div>
<p>
<div style="display:grid; grid-template-columns: 60% auto; gap:8px;">
<div>
<h3>MIT License</h3>
<div class="license"></div>
</div>
<div>
<h3>Supported Databases</h3>
<div class="supported"></div>
</div>
</div>
</p>
</div>

@ -0,0 +1,8 @@
<div class="large-text">Thank you,</div>
<div>For considering <b>{{layout.header.title}}</b>,
Please feel free to direct bugs/inquiries to :</div>
<ul>
<li type="square">steve.l.nyemba@vumc.org</li>
<li type="square">or info@the-phi.com</li>
<li type="square">clone the source code <span class="active bold" onclick="window.open('https://hiplab.mc.vanderbilt.edu/git/hiplab/parser.git','_git')">here</span></li>
</ul>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,199 @@
<style>
.notebook-pane {
display:grid; grid-template-columns: 40% 60%; gap:8px;;
font-family: sans-serif; line-height: 1.5; padding:8px; font-size:14px;
}
.search-box {display:grid; grid-template-columns: auto 64px; gap:8px; }
.search-box input {padding:8px; border:4px solid transparent; outline: 0; background-color: #f3f3f3; width:99%;}
.search-box input:focus {border-left-color: #4682b4;}
.notebook-search-results-pane {
height:105x;
}
.notebook-search-results {
height:105px; overflow: hidden; overflow-y: auto;
}
.notebook-pane .right-pane .notebook{
height:65vh;
padding:8px;
overflow: hidden ;
}
.notebook-pane .right-pane .notebook iframe{
height:98%;
width:100%;
}
.notebook-pane .right-pane{
display:grid;
grid-template-rows: 32px auto; gap:4px;
}
</style>
<script>
var notebook = {}
notebook.meta ={"postgresql":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0},"redshift":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0}, "mysql":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0},"mariadb":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0}, "bigquery":{"private_key":1,"dataset":1,"table":1},"mongodb":{"db":1,"collection":1,"host":0,"port":0,"username":0,"password":0}, "netezza":{"host":1,"port":1,"username":1,"password":1, "database":1,"table":1}, "sqlite":{"path":1,"table":1}, "sqlserver":{"host":0,"port":0,"username":1,"password":1,"database":1, "table":1}
,"databricks":{"host":1,"token":1,"schema":1,"cluster_path":1,"table":1},"couchdb":{"url":0,"dbname":1,"doc":1,"username":0,"password":0},"cloudant":{"url":0,"dbname":1,"doc":1,"username":0,"password":0}
}
notebook.meta.etl = "transport generate ./my-etl-config.json<br>transport apply ./my-etl-config.json"
notebook.meta.s3 = {"access_key":1,"secret_key":1, "file":1, "bucket":1, "region":1}
notebook.meta['mssqlserver'] = notebook.meta.sqlserver
notebook.init = function (){
var uri = '{{system.context}}/api/info/_data'
var http = HttpClient.instance()
http.post(uri,function(x){
if(x.status == 200 && x.readyState == 4){
var _data = JSON.parse(x.responseText)
notebook.render(_data)
notebook.search('sqlite')
$('.notebook-pane input').val('sqlite')
$('.notebook-pane .left-pane .sqlite').click()
}else{
//
// Find a way to alert of the error
//
;
}
})
}
notebook.render = function (data){
data.forEach(_item =>{
var _div = jx.dom.get.instance('DIV')
_div.innerHTML = _item.label
_div.data = _item
_div.onclick = function (){
$('.notebook-pane .label').html(this.data.label)
$('.notebook-pane .left-pane .vendor-info').html(this.data.doc)
$('.notebook-pane .left-pane .vendor-url').html(this.data.url)
_uri = 'www/html/docs/html/'+this.data.provider.trim()+'.html'
// _context = '{{system.context}}'
// if (_context != '') {
// _uri = _context + '/'+_uri
// }
frame = jx.dom.get.instance('IFRAME')
frame.frameBorder = 0
frame.className = ''
frame.src = _uri //'{{system.context}}'+'/www/html/docs/html/'+this.data.provider.trim()+'.html'
$('.notebook-pane .right-pane .notebook').empty()
$('.notebook-pane .right-pane .notebook').append(frame)
$('.notebook-pane .search-box input').focus()
_info = notebook.meta[this.data.provider]
$('.notebook-pane .left-pane .source-code').html(JSON.stringify(_info))
} //-- binding
_div.className = 'active notebook-item '+_item.provider
$('.notebook-search-results').append(_div)
})
// $('.notebook-search-results .notebook-item').slideUp()
}
notebook.search = function (term) {
_count = 0
if (term == ''){
$('.notebook-search-results .notebook-item').slideDown()
}else{
var nodes = jx.dom.get.children('notebook-search-results')
var _regx = new RegExp(term,"ig")
jx.utils.patterns.visitor(nodes,function (node){
if (node.data.provider.match(_regx) || node.data.label.match(_regx)) {
$(node).slideDown()
_count += 1
}else{
$(node).slideUp()
}
})
}
$('.notebook-pane .found').html(_count)
}
notebook.find = function (){
var term = $('.search-box input').val().trim()
notebook.search(term)
}
notebook.clear = function (){
$('.notebook-pane .search-box input').val('')
notebook.search('')
$('.notebook-pane .search-box input').focus()
$('.notebook-pane .right-pane .notebook').empty()
$('.notebook-pane .label').html('')
$('.notebook-pane .left-pane .vendor-info').html('')
$('.notebook-pane .left-pane .vendor-url').html('')
$('.notebook-pane .source-code').html('&nbsp;')
// $('.notebook-pane .search-box input').focus()
}
notebook.open_wizard =function(){
try{
_args = {{layout.overwrite.wizard}}
menu.events._dialog(_args,'{{context}}')
}catch(e){}
}
$(document).ready(function (){
notebook.init()
$('.search-box .active').on('click',notebook.clear)
$('.search-box input').on('keypress',notebook.find)
})
</script>
<div class="notebook-pane">
<div class="left-pane">
<div class="search-box border-round border">
<div class="border-right"><input type="search" placeholder="[provider or vendor]"/></div>
<div class="active" align="center"><i class="fa-solid fa-trash"></i></div>
</div>
<p><div class="border-round border notebook-search-results-pane">
<div align="right" class="">
<span class="found"></span><span> Found </span>
</div>
<div id = "notebook-search-results" class="notebook-search-results"></div>
</div>
<div style="height:125px">
<ul>
<i class="fa-solid fa-minus "></i> Preview notebooks with database providers/vendors
<br><i class="fa-solid fa-minus "></i> The notebooks show how to use <b>data-transport</b> as a library
<br><i class="fa-solid fa-minus "></i> <span class="vendor-info"></span>
<br><i class="fa-solid fa-minus "></i> <span class="vendor-url"></span>
</ul>
</div>
<div class="border-top">&nbsp;</div>
<p>
<h3>Generated: auth-file <span class="label" style="text-transform: uppercase;"></span></h3>
<ul>
<i class="fa-solid fa-minus "></i> An <b>auth-file</b> is a file used to store database parameters.
<br><i class="fa-solid fa-minus "></i> Copy the code above to the auth-file and fill with appropriate values
<br><i class="fa-solid fa-minus "></i> Attributes with zero i.e 0 are optional
</ul>
<div class="source-code"></div>
<ul>
<b>Note:</b>
<br><i class="fa-solid fa-minus "></i> The database providers/vendors above is exhaustive
<br><i class="fa-solid fa-minus "></i> Generate files for database provider/vendors <span class="bold active" onclick="notebook.open_wizard()">click here</span>
</ul>
</p>
</p>
</div>
<div class="right-pane">
<div>
<div style="text-transform: capitalize;">
<div class="label bold" style="font-size:20px; text-transform: uppercase;"></div>
<div>Jupyter Notebook preview</div>
</div>
</div>
<p><div class="notebook border border-round"></div>
</div>
</div>

@ -0,0 +1,166 @@
<script>
_layout = {on:{load:{'plugin-intro':['www/html/_notes/plugins-intro.html']}}}
var _plugins = {}
_plugins.open = function (_id){
$('.tab-content').slideUp(function (){
})
_id = '.'+_id
$(_id).slideDown()
}
_plugins.copy = function(_node) {
var _code = $(_node.parentNode).text().trim().replace(/ {8}/g,'').replace(/ {4}/g,'\t').replace(/\r/g,'\n')
navigator.clipboard.writeText(_code);
$(_node).empty()
$(_node).html('<i class="fa-solid fa-check"></i>')
setTimeout(function(){
$(_node).empty()
$(_node).html('<i class="fa-regular fa-copy"></i>')
},750)
}
$(document).ready(function(){
bootup.init('{{system.context}}',_layout)
// _plugins.open('makeplug-src')
var label = $('.process-steps .tabs label')[0]
label.click()
})
</script>
<style>
/* .source-code {background-color:#f3f3f3; color:black;} */
.source-code b {color: yellow;}
.split-1 {display:grid; grid-template-columns: 45% auto; gap:4px}
.split-2 {display:grid; grid-template-columns: 55% auto; gap:4px}
.process-steps .list { font-size:16px; padding:4px; margin-left:8px; background-color: #f3f3f3;}
.process-steps .list div {margin:8px;}
/* .fa-copy {float:right; cursor:pointer; padding:4px; margin:4px; background-color: transparent;} */
/* .fa-copy:hover {color:#4682b4;} */
</style>
<div style="min-height:650px;">
<div class="split-2">
<div>
<h3>Plugins: Usage & Development</h3>
<p>
<div id="plugin-intro" >
</div>
</p>
<p>
<h3>Plugins: Registry</h3>
The plugins registry is a registry of plugins intended to be used in pre/post processing. This feature comes in handy :
<ul>
<div><i class="fa-solid fa-minus"></i> During ETL: Cleanup data, adding columns enforcing data-typing, removing/encrypting PHI ... </div>
<div><i class="fa-solid fa-minus"></i> In a collaborative environment (Jupyter-x; Zeppelin; AWS Service Workbench)</div>
</ul>
</p>
<p>
<h3>Plugins: Architecture & Design</h3>
Plugins are designed around <b class="active" onclick="window.open('https://en.wikipedia.org/wiki/Plug-in_(computing)','_doc')">plugin architecture</b> using <b class="active" onclick="window.open('https://en.wikipedia.org/wiki/Iterator_pattern','doc')">Iterator design-pattern</b>. In that respect and function as a <b>pipeline</b> i.e executed sequentially in the order in which they are expressed in the parameter. Effectively the output of one function will be the input to the next.
<p>
<div class="border figure" align="center" >
<img src="www/html/_assets/images/plugins-components.png">
<div class="small border-top" align="center" style="margin-top:4px; padding-top:4px;">Data Transport UML Plugin Component View</div>
</div>
</p>
</p>
</div>
<div class="process-steps" >
<h3>Quick Start</h3>
<div class="tabs">
<input type="radio" name="step" id="makeplug">
<label for="makeplug" onclick="_plugins.open('makeplug-src')">1. Make Plugin</label>
<input type="radio" name="step" id="regplug">
<label for="regplug" onclick="_plugins.open('regplug-src')">2. Register Plugin</label>
<input type="radio" name="step" id="useplug">
<label for="useplug" onclick="_plugins.open('useplug-src')">3. Use The Plugin</label>
</div>
<div class="tab-content makeplug-src">
<p>
<div class="split-x">
<div>
<ul class="list">
<div><i class="fa-solid fa-minus"></i> The code here shows a function that will be registered as <b><i>"autoincrement"</i></b>.</div>
<div><i class="fa-solid fa-minus"></i> The data, will always be a <b>pandas.DataFrame</b></b></div>
<div><i class="fa-solid fa-minus"></i> For the sake of this example the file will be <b>my-plugin.py</b></div>
</ul>
</div>
<div class="source-code"><i class="fa-regular fa-copy" onclick="_plugins.copy(this)"></i>
<b>import</b> transport
<div><b>import</b> numpy <b>as</b> np</div>
<br>
<br>_index = 0
<br><div>@transport.Plugin(name='autoincrement')</div>
<div><b>def</b> _incr (_data):</div>
<ul>
<div><b>global</b> _index</div>
<div>_data['_id'] = _index + np.arange(_data.shape[0])</div>
<div>_index = _data.shape[0]</div>
<div><b>return</b> _data</div>
</ul>
</div>
</div>
</p>
</div>
<!-- register plugin-->
<div class="tab-content regplug-src">
<p>
<div class="">
<div>
<b>data-transport</b> comes with a built-in command line interface (CLI). It allows plugins to be registered and reused.
<ul class="list">
<div><i class="fa-solid fa-minus"></i> Registered functions are stored in <b><i>$HOME/.data-transport/plugins/code</i></b></div>
<div><i class="fa-solid fa-minus"></i> Any updates to <b>my-plugin.py</b> will require re-registering the file</div>
<div><i class="fa-solid fa-minus"></i> Additional plugin registry functions (list, test) are available </div>
</ul>
</div>
<div>
<div class="source-code"><i class="fa-regular fa-copy" onclick="_plugins.copy(this)"></i>
<b>$</b> transport plugin-add demo ./my-plugin.py
</div>
<p>
The following command allows <b>data-transport</b> to determine what is knows about the function i.e <b>real name</b> and <b>name</b> to be used in code.
<div class="source-code"><i class="fa-regular fa-copy" onclick="_plugins.copy(this)"></i>
<b>$</b> transport plugin-test demo.autoincrement
</div>
</p>
</div>
</div>
</p>
</div>
<!-- useplug-src -->
<div class="tab-content useplug-src">
<p>
Once registered, the plugins are ready for use within code or configuration file (auth-file).
<div class="source-code"><i class="fa-regular fa-copy" onclick="_plugins.copy(this)"></i><b>import</b> transport
<div><b>from</b> transport <b>import</b> providers</div>
_args = {
<div>"provider":providers.HTTP,</div>
<div>"url":"https://raw.githubusercontent.com/codeforamerica/ohana-api/master/data/sample-csv/addresses.csv",</div>
<div>"plugins":["demo@autoincrement"]</div>
}
<div>reader = transport.get.reader(**_args)</div>
<div>_data = reader.read()</div>
<div>print (_data.head())</div>
</div>
</p>
</div>
</div>
</div>
</div>

@ -0,0 +1,114 @@
<style>
.docs {
display: grid;
grid-template-columns: 30% auto;
grid-template-rows: min-content;
}
.docs > div{
padding:8px;
margin:8px;
}
/* .docs div:nth-child(even){
border-left:2px dotted #CAD5E0;
} */
.docs .search-box {
display:grid;
gap:4px;
grid-template-columns: auto 48px;
}
.docs .search-box input[type=text]{
outline: 0;
padding:8px;
border:4px solid transparent;
background-color: #f3f3f3;
}
.docs .search-box input[type=text]:focus{
border-left-color: #4682B4;
}
.source-code , source-code pre{
background-color: #f3f3f3;
color:black;
font-size:14px;
font-family:courier;
font-weight:lighter;
}
.source-code {margin-left:4px;}
.source-code b {color:#4682b4; font-weight: bold;}
</style>
<script>
var qstart = {}
qstart.open = function (_path){
// var _URI = ([qcms.context,'api/disk/read?doc='+uri]).join('/')
if (_path.match(/\?/)){
_path = _path.split('?')[1]
}
var uri = qcms.context+'/page'
var http = HttpClient.instance()
uri = uri + '?'+_path
http.get(uri, function (x){
$('.docs .full-docs').html(x.responseText)
var script = $('.docs .full-docs script')
eval($(script).text())
})
}
qstart.find = function (){
qcms.search('qstart-input','qstart-menu')
}
$(document).ready( function(){
qstart.open('www/html/_notes/install.html')
})
</script>
<div class="docs">
<div class="">
<div class="search-box border">
<input id="qstart-input" type="text" placeholder="[ search : term or keyword]" onkeyup="qstart.find()"/>
<div class="active" align="center">
<i class="fa-solid fa-trash"></i>
</div>
</div>
<div id="qstart-menu" class="border-right" style="height:69vh; margin-top:28px;">
<div class="install">
<div class="active bold" onclick="qstart.open('www/html/_notes/install.html')">0. Installation</div>
<ul class="small">
Install using pip or from code and test installation from https://dev.the-phi.com/git/qcms/cms
</ul>
</div>
<div class="install" onclick="qstart.open('www/html/_notes/registry.html')">
<div class="active bold">1. Initialize registry</div>
<ul class="small">
Keep database authentication parameters out of sight, in a collaborative environment
</ul>
</div>
<div class="import-code">
<div class="active bold" onclick="qstart.open('www/html/_notes/source-code.html')">2. Import into Code</div>
<ul class="small">
How to use {{layout.header.title}} in python source code (notebooks, or files)
</ul>
</div>
<div class="src-code">
<div class="active bold" onclick="qstart.open('www/html/about/license.html')">3. Source code</div>
<ul class="small">
{{layout.header.title}} is available uner MIT license and available on github. Contribute, share at will ;-)
</ul>
</div>
</div>
</div>
<div class="full-docs">
</div>
</div>

@ -0,0 +1,186 @@
<style>
.terminal {
display:grid; grid-template-columns: 55% 45%; gap:8px; font-weight: lighter;
}
hr{border:0px; border-top:3px dotted #CAD5E0; width:50%; margin-left:25%}
.source-code pre {font-size:12px; font-weight:lighter; font-family: courier;}
</style>
<script>
layout = {on:{load:{'install':['www/html/_notes/install.html'],'documentation':['www/html/_notes/documentation.html']}}}
// bootup.init('{{system.context}}',layout)
var label = $('.terminal .tabs label')[0]
label.click()
// menu.events._openTabs('.terminal .tab-content','etl-conf-tab')
// menu.events._openTabs('.make-config','.manual')
label = $('.terminal .etl-conf-tab .tabs label')[0]
label.click()
</script>
<div class="terminal">
<div>
<p>
<h3>ETL: Introduction</h3>
Extract Load & Transform (ETL) consists in copying data from one database to one or many others. This can be done in two different ways:
<ul>
<div><i class="fa-solid fa-minus"></i> Command Line Interface (CLI), driven by JSON configuration</div>
<div><i class="fa-solid fa-minus"></i> Or within custom python code</div>
</ul>
The ETL process will take advantage of registries for <b>plugins</b> and <b>labeled database connectivity</b> to perform <b>pre</b>/<b>post</b> processing tasks.
</p>
<hr>
<p>
<h3>ETL: Command Line Interface</h3>
<p>
The configuration file needed to run the ETL is a JSON formatted file where each entry contains:
<ul>
<div><i class="fa-solid fa-minus"></i> <b>source</b> with the content of an <b>auth-file</b></div>
<div><i class="fa-solid fa-minus"></i> <b>target</b> with <b>list</b> of elements of an <b>auth-file</b></div>
</ul>
<!-- The auth-file<span class="active bold" onclick="menu.events._dialog({type:'dialog',uri:'www/html/wizard/wizard.html',title:'Auth-file Generator'},'{{system.context}}')">generator</span>, shows how the auth-file entry is structured. -->
<div>
The <b>CLI</b> (transport), is capable of generating a demo ETL :
<ul>
<div><i class="fa-solid fa-minus"></i> with <b>source</b>: reads CSV data from github</b></div>
<div><i class="fa-solid fa-minus"></i> and <b>target</b>: writes the data to CSV & SQLite3 database</div>
</ul>
<div class="source-code"><i class="fa-solid fa-copy" onclick="_plugins.copy(this)"></i>
$ transport generate ./demo-etl.json
</div>
</div>
</p>
</p>
<br>
<hr>
<br><div align="center" class="border figure"><img src="www/html/_images/uml-activity.png">
<div class="small border-top" style="margin-top:4px; padding-top:4px">
Data-transport UML Extract-Load-Transform (ETL) Workflow
</div>
</div>
</div>
<div>
<div>
<div class="tabs" >
<input type="radio" name="etl" id="etl-conf"/>
<label for="etl-conf" onclick="menu.events._openTabs('.terminal .tab-content','etl-conf-tab')">1. Configuration</label>
<input type="radio" name="etl" id="etl-exe"/>
<label for="etl-exe" onclick="menu.events._openTabs('.terminal .tab-content','etl-exe-tab')">2. Run ETL CLI</label>
<input type="radio" name="etl" id="etl-code"/>
<label for="etl-code" onclick="menu.events._openTabs('.terminal .tab-content','etl-code-tab')">ETL: Custom Code</label>
<input type="radio" name="etl" id="none" disabled>
<label for="none" style="grid-column:4">&nbsp;</label>
</div>
</div>
<p>
<div class="tab-content">
<div class="etl-exe-tab">
<p>
The command-line interface should be instructed to run the ETL by calling the <b>apply</b> function.
</p>
<p>
<div class="source-code">
$ transport apply ./demo-etl.json
</div>
</p>
<p>
Additional parameters can be invoked by providing the <b>--help</b> switch
</p>
<p>
<div class="source-code">
$ transport apply --help
</div>
</p>
</div>
<div class="etl-code-tab"></div>
<div class="etl-conf-tab">
The following examples shows simple configuration files that do NOT require any database to be installed. Feel free to change and edit at your own discression.
<br>
<p>
<h3>Example # 1: Basic ETL</h3>
<div class="tabs" style="margin:0px; padding:0px; background-color:#ffffff;grid-template-columns: 50% 50%; display:grid;" align="center">
<input type="radio" name="mk-conf" id="mk-man">
<label for="mk-man" onclick="menu.events._openTabs('.make-config','.manual')" style="background-color:#ffffff; border-radius:0px;">Manual</label>
<input type="radio" name="mk-conf" id="mk-gen">
<label for="mk-gen" onclick="menu.events._openTabs('.make-config','.generated')" style="background-color:#ffffff; border-radius:0px;">Generate</label>
</div>
<div style="border-top:0px; min-height:400px;">
<div class="make-config">
<div class="generated">
<p>
<b>data-transport</b> comes with a CLI integrated that will
<ul>
<div><i class="fa-solid fa-minus"></i> <b>generate</b> an EL configuration file</div>
<div class=" source-code"><i class="fa-solid fa-copy" onclick="_plugins.copy(this)"></i>
<span>$ transport generate ./demo-etl.json</span>
</div>
</ul>
<div><i class="fa-solid fa-minus"></i> <b>NOTE:</b>The configuration file supports <b>labels</b> and/or <b>plugins</b>, these would have to be done manually</div>
</p>
</div>
<div class="manual">
<p>Copy the content and save it to a file <b>"demo-etl.json"</b></p>
<div class="source-code" style="text-overflow: ellipsis;">
<i class="fa-solid fa-copy" onclick="code.copy(this)"></i>
<pre>[{
"source": {
"provider": "http",
"url": "https://github.com/codeforamerica/ohana-api/blob/master/data/sample-csv/addresses.csv"
},
"target": [
{"provider": "files", "path": "addresses.csv", "delimiter": ","},
{"provider": "sqlite3", "database": "sample.db3", "table": "addresses"}
]}]</pre>
</div>
</div>
</div>
</div>
</p>
<hr>
<p>
<h3>Example # 2: ETL With Plugins</h3>
<p>Copy the content and save it to a file <b>"demo-etl.json"</b></p>
<div class="source-code" style="text-overflow: ellipsis;">
<i class="fa-solid fa-copy" onclick="code.copy(this)"></i>
<pre >[{
"source": {
"provider": "http",
"plugins":["demo@autoincrement"],
"url": "https://github.com/codeforamerica/ohana-api/blob/master/data/sample-csv/addresses.csv"
},
"target": [
{"provider": "files", "path": "addresses.csv", "delimiter": ","},
{"provider": "sqlite3", "database": "sample.db3", "table": "addresses"}
]}]</pre>
</div>
</p>
</div>
</div>
</p>
<!-- <div class="border-round border">
<h3 style="border-color: transparent;">UML Activity Diagram - ETL</h3>
<br><div class="border-top">
<ul>
<i class="fa-solid fa-minus"> </i> The diagram shows <b>1-to-many</b> database support
<br><i class="fa-solid fa-minus"> </i> The ETL job is specified by JSON configuration file
</ul>
</div>
</div>
<br><div id="documentation" class="border-round border" style="min-height:250px"></div> -->
</div>
</div>

@ -0,0 +1,194 @@
<style>
.small {font-size:13px; font-weight:lighter;}
.title-x {display:grid; grid-template-columns: 50% 50%; gap:8px;;
}
.dataframe {
border-collapse: collapse;
margin: 25px 0;
font-size: 0.9em;
font-family: sans-serif;
width:100%;
border:1px solid #CAD5E0;
/* min-width: 400px; */
/* box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); */
}
.dataframe thead tr {
background-color: #4682B4;
color: #ffffff;
text-align: left;
}
.dataframe th,
.dataframe td {
padding: 12px 15px;
}
.dataframe tbody tr {
border-bottom: 1px solid #dddddd;
}
.dataframe tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
}
/* .dataframe tbody tr:last-of-type {
border-bottom: 2px solid #009879;
} */
.dataframe tbody tr.active-row {
font-weight: bold;
color: #009879;
}
.transport .facts {
font-family:sans-serif; font-weight:lighter; line-height: 1.5;
font-size:16px;
height: auto;
}
.transport .facts .details {display:none}
.transport .facts #features ul,.introduction ul { height:125px}
.transport .facts #install {
grid-row:1; grid-column: 2;
/* border-left:1px solid #CAD5E0; */
padding-left:10px;
}
.transport h3 {
font-size:24px;
margin:0px;
font-family: sans-serif;
border-bottom:1px solid #CAD5E0;
}
/* .transport .facts {
display:grid;
grid-template-columns: repeat(2,1fr); gap:8px; font-family: sans-serif; font-weight: lighter;
;
} */
.transport .paragraph { min-height:270px; margin:8px;}
/* .transport #facts-right div:first-child{min-height: 270px;} */
/* .transport #facts-left div:first-child{min-height: 270px;} */
.shadow {
box-shadow: 10px 5px 5px #d3d3d3;
}
.figure {padding:1%; margin:8px;}
.poster {
background-image: url("www/html/_assets/images/banner.jpg");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
align-items: center;
align-content: center;
display: block;
padding:0px;
}
.transport ul { list-style-type: none;}
.transport ul .line-item {
margin:4px; padding:4px;
}
.line-item .fa-check {color:green;}
.product i {font-size:22px;}
.product table {width:100%; }
.product table th , .product table td {text-transform: capitalize; font-weight:bold; text-align: center;}
.product table tr td {border:1px solid #CAD5E0;}
.product table td:first-child{text-align: left;}
.product table thead th{background-color: #4682B4; font-size:18;}
.product table thead th:first-child{background-color: rgba(242,242,242,1);}
.features {display:grid; grid-template-columns: repeat(2,1fr);
gap:4px;}
</style>
<script>
var InitProduct = function (){
var http = HttpClient.instance()
var uri = '{{system.context}}/api/info/product'
http.get(uri,function(x){
$('.product').html(x.responseText)
})
}
if (!qcms){
var qcms = {}
}
qcms.source_code = function (){
}
$(document).ready(()=>{
InitProduct()
})
</script>
<div class="transport">
<p>
<div class="title-x " align="center">
<div>
<div class="large-text bold poster" style="height:58%; align-self:center">
<div style="align-self: center;">
<div>Read, Write & Stream Data</div>
<div>Anywhere</div>
<div class="small">
version
<span id="data-transport-version" ></span>
</div>
</div>
</div>
<div class="features">
<div align="left" class="border-round border" style="background-color: #f3f3f3;">
<div align="center" class="bold">Open-Source</div>
<p>
<div align="left" class="small">Built with python, easy install and available under MIT license on github</div>
</p>
</div>
<div class="border-round border" style="background-color: #f3f3f3;">
<div class="bold">Multiple Databases</div>
<p>
<div align="left" class="small">Seamless & consistent access to SQL, NoSQL, Cloud & Warehouse databases</div>
</p>
</div>
<div class="border-round border" style="background-color: #f3f3f3;">
<div class="bold">Secure Collaboration</div>
<p>
<div class="small" align="left">
Uses a registry to prevent sensitive data connectivity to be in a notebook (Zeppelin, Jypterlab ...)
</div>
</p>
</div>
<div class="border-round border" style="background-color: #f3f3f3;">
<div class="bold">Pipelines</div>
<p>
<div align="left" class="small">
Apply user-defined functions across database technologies for consistent results
</div>
</p>
</div>
</div>
</div>
<div class="" >
<div class="product" ></div>
<div style="display:grid; grid-template-columns:40% 30% 30%; gap:1px; align-content: center;" align="center">
<div></div>
<div></div>
<div class="">
<div class="">
<div class="border-round border">
<div class="small bold"> <i class="fa-solid fa-envelope"></i>
info@the-phi.com</div>
<div class="small bold">Contact US </div>
</div>
</div>
</div>
</div>
</div>
</div>
</p>
</div>

@ -0,0 +1,83 @@
<style>
.configurator {
width:70%; margin-left:15%;
}
.configurator input[type=text] {
padding:8px;
outline:0px;
border:0px;
font-family:sans-serif; font-size:18px;
background-color: #f3f3f3f3;;
font-weight: normal; color:#000000; line-height: 1.5;
}
.configurator .search-box {
display:grid;
grid-template-columns: auto 64px; gap:8px;
background-color: #f3f3f3f3;;
align-items: center;
align-content:center;
}
.configurator .source .item-select {display:grid;
grid-template-columns: 50% 25% 25%;
padding:4px; gap:8px;
margin:4px;
/* text-transform: capitalize; */
}
</style>
<script>
var _setup = {}
_setup.render = {}
_setup.render.source = function (_data) {
var _select = $('.configurator .source')[0]
_data.forEach(_item=>{
var _label = jx.dom.get.instance('DIV')
var _provider = jx.dom.get.instance('DIV')
var _plugins = jx.dom.get.instance('DIV')
_label.innerHTML = _item.label
_provider.innerHTML = _item.provider
_plugins.innerHTML = JSON.stringify(_item.plugins)
_provider.align='left'
_provider.className = ''
var _pane = jx.dom.get.instance('DIV')
_pane.appendChild(_label)
_pane.appendChild(_provider)
_pane.appendChild(_plugins)
_pane.data = _item
_pane.className = 'item-select active'
_select.appendChild(_pane)
})
}
_setup.init = function (){
var uri='{{system.context}}/api/info/registry'
var http = HttpClient.instance()
http.get(uri,function (x){
_setup.render.source ( JSON.parse(x.responseText))
})
}
$(document).ready(function(){
_setup.init()
})
</script>
<div class="configurator">
<div class="tabs">
<input type="radio" id="etl-tab" name="setup-tabs"/>
<label for="etl-tab">ETL : CLI</label>
<input type="radio" id="store-tab" name="setup-tabs"/>
<label for="store-tab">Read/Write</label>
</div>
<div class="tab-content">
<div class="tab-content-container">
<div>
<h3>Source: Database Technology</h3>
<div class="small">Select a database technology as a <b>source</b></div>
<div class="search-box">
<input type="text" class="source-label" placeholder="Name of the label"/>
<div class="border-left"><div class="active" align="center"><i class="fa-solid fa-times"></i></div></div>
</div>
<div class="source border-top"></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,199 @@
<script>
var _meta ={"postgresql":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0},"redshift":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0}, "mysql":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0},"mariadb":{"host":0,"port":0,"database":1,"table":1,"username":0,"password":0}, "bigquery":{"private_key":1,"dataset":1,"table":1},"mongodb":{"db":1,"collection":1,"host":0,"port":0,"username":0,"password":0}, "netezza":{"host":1,"port":1,"username":1,"password":1, "database":1,"table":1}, "sqlite":{"path":1,"table":1}, "sqlserver":{"host":0,"port":0,"username":1,"password":1,"database":1, "table":1}
,"databricks":{"host":1,"token":1,"schema":1,"cluster_path":1,"table":1},"couchdb":{"url":0,"dbname":1,"doc":1,"username":0,"password":0},"cloudant":{"url":0,"dbname":1,"doc":1,"username":0,"password":0}
}
var wizard = {}
wizard.init = function (){
Object.keys(_meta).forEach( function (_name){
var _div = jx.dom.get.instance('DIV')
_div.innerHTML = _name
_div.data = _meta[_name]
_div.data.provider = _name
_div.data.context = 'write'
_div.className = 'search-item active'
_div.placeholder = 'use '+_name+' provider'
_div.onclick = function (){
wizard.write_code(this.data)
$('.wizard-code').slideDown()
}
jx.dom.append('search-meta-items',_div)
})
jx.dom.set.value('search-provider','sqlite')
wizard.search()
}
wizard.write_code = function (_info){
$('.provider').html(_info.provider)
$('#auth-file').html( JSON.stringify(_info))
}
wizard.search = function (){
var term = jx.dom.get.value('search-provider').trim()
wizard.show(term)
}
wizard.clear = function (){
jx.dom.set.value('search-provider','')
wizard.show('')
jx.dom.set.focus('search-provider')
}
wizard.show = function (term){
_count = 0
$('.wizard-code').slideUp()
if (term == ''){
$('.search-item').slideDown()
}else{
var nodes = jx.dom.get.children('search-meta-items')
var _regx = new RegExp(term,"ig")
jx.utils.patterns.visitor(nodes,function (node){
if (node.data.provider.match(_regx)){
$(node).slideDown()
_count += 1
}else{
$(node).slideUp()
}
})
}
$('.found-items').html(_count)
}
wizard.supported_providers = function (){
var uri = '{{system.context}}/api/info/about' ;
var http = HttpClient.instance()
http.get(uri,function(x){
var _object = JSON.parse(x.responseText)
jx.dom.set.value('wiz-vendors',_object.supported)
var layout = {on:{load:{'contact-wizard':['www/html/contact.html']}}}
bootup.init('{{system.context}}',layout)
})
}
$(document).ready(function(){
_node = jx.dom.get.instance('wz-clear-search')
_node.onclick = wizard.clear
_node = jx.dom.get.instance('search-provider')
_node.onkeyup=wizard.search
$('.wizard-code').slideUp()
wizard.supported_providers()
wizard.init()
})
</script>
<style>
.wizard-frame input {
background-color:#f3f3f3; width:96%;
padding:8px; border:4px solid transparent; outline: 0;
color:#000000;
}
.wizard-frame input:focus {
border-left-color: #4682b4;
}
.search-meta-frame {
width:calc(100% - 64px) ;
margin-top:4px;
}
#search-meta{
height:100px; overflow: hidden; overflow-y: auto;
padding:8px;
}
#search-meta .search-item {padding:4px; text-transform: capitalize;}
.wizard-code .provider {text-transform: uppercase;}
.supported-vendors table {width:100%; padding:4px; border:1px solid #CAD5E0;}
.supported-vendors thead tr {
background-color: #4682B4;
color: #ffffff;
text-align: left;
}
.supported-vendors tbody tr {
border-bottom: 1px solid #dddddd;
}
.supported-vendors tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
}
</style>
<div class="wizard-frame" style="display:grid; grid-template-columns: 650px auto; gap:8px;">
<div>
<div class="large-text">Wizard: auth file generator</div>
<p>
<div>This wizard generates an <b>auth-file</b>. It is a template file to be used to setup a <b>data-transport</b> database connectivity to help with best practice when it comes to sensitive information in code.
<ul>
<i class="fa-solid fa-minus"></i> search for the database provider / vendors
<br><i class="fa-solid fa-minus"></i> click on the vendor and copy the generated code to a file
</ul>
</div>
</p>
<p>
<div style="display:grid; grid-template-columns: auto 48px; gap:4px">
<div>
<input id="search-provider" type="text" placeholder="[database provider]" onkeyup="wizard.search()">
</div>
<div>
<div id="wz-clear-search" class="active" align="center"><i class="fa-solid fa-trash"></i></div>
</div>
</div>
<div class="search-meta-frame border-round border">
<div align="right">
<span class="found-items">0</span><span> found</span>
</div>
<div id="search-meta"><div id="search-meta-items"></div></div>
</div>
</p>
<p>
<div style="height:150px;">
<div class="wizard-code">
<div class="provider bold"></div>
<div id="auth-file" class="source-code" style="text-wrap: wrap; overflow: hidden; overflow-x: auto;"> &nbsp;</div>
<br><b>Note :</b>
<br><i class="fa-solid fa-minus"> </i> Copy the code above to the <b>auth-file</b> and fill with appropriate values
<br><i class="fa-solid fa-minus"> </i> Attributes with <b>zero</b> i.e <b>0</b> are optional
</div>
</div>
</p>
<p>
<div id="contact-wizard"></div>
</p>
</div>
<div>
<div class="large-text">Prerequisites</div>
<ul class="border-left">
<li type="square">Familiarity with JSON format</li>
<li type="square">Understand your current database security access policy
<br><i class="fa-solid fa-minus"> </i> Insure your policy (permissions) match your use case
<br>
</li>
</ul>
<div class="large-text">Thing to know</div>
<ul class="border-left">
<li type="square">Values assigned to attributes
<br><i class="fa-solid fa-minus"> </i> value of <b>one</b> i.e <b>1</b> suggests a value must be provided
<br><i class="fa-solid fa-minus"> </i> value of <b>zero</b> i.e <b>0</b> suggests the attribute is optional and can be removed
</li>
<li type="square">
Supported databases (or database providers) to use in search
<div id="wiz-vendors" class="supported-vendors"></div>
</li>
</ul>
</div>
</div>
Loading…
Cancel
Save