Skip to content

app

Dash UI for FSDBSync - PlantDB Database Synchronization ToolLink

This module provides a web-based user interface for the FSDBSync class, allowing users to easily configure and manage database synchronization between different database types (local, SSH, HTTP).

Usage exampleLink

Local Path to Local PathLink

>>> from plantdb.commons.test_database import test_database
>>> # Create a test source database
>>> db_source = test_database()
>>> # Create a test target database
>>> db_target = test_database(dataset=None)
>>> # ---------------------------------------------------------------------
>>> # Synchronize the database using the WebUI
>>> # Use the path printed out during the test FSDB initialization
>>> # ---------------------------------------------------------------------
>>> db_source.disconnect()  # Remove the test database
>>> db_target.disconnect()  # Remove the test database

Local Path to HTTP REST APILink

>>> from plantdb.server.test_rest_api import TestRestApiServer
>>> from plantdb.commons.test_database import test_database
>>> # Create a test source database
>>> db_source = test_database("all")
>>> # Create a test target database
>>> db_target = TestRestApiServer(test=True, empty=True)
>>> db_target.start()
>>> # ---------------------------------------------------------------------
>>> # Synchronize the database using the WebUI
>>> # Use the path and URL printed out during the test FSDB initialization
>>> # ---------------------------------------------------------------------
>>> db_target.stop()

create_database_config_card Link

create_database_config_card(title, db_side)

Create a card for database configuration

Source code in plantdb/client/sync_app/app.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def create_database_config_card(title, db_side):
    """Create a card for database configuration"""
    return dbc.Card([
        dbc.CardHeader(html.H4([html.I(className="bi bi-database me-2"), title], className="mb-0")),
        dbc.CardBody([
            # Database type selection
            dbc.Row([
                dbc.Col([
                    dbc.Label([html.I(className="bi bi-hdd-network me-1"), "Database Type:"]),
                    dbc.Select(
                        id=f"{db_side}-type",
                        options=[
                            {"label": "Local Path", "value": "local"},
                            {"label": "SSH/SFTP", "value": "ssh"},
                            {"label": "HTTP REST API", "value": "http"}
                        ],
                        value="local"
                    )
                ], width=12)
            ], className="mb-3"),

            # Pre-register all possible input IDs as hidden components to avoid callback errors
            html.Div([
                # Source inputs
                create_local_inputs(db_side),
                create_ssh_inputs(db_side),
                create_http_inputs(db_side),
            ]),

            # Test connection button and status
            dbc.Row([
                dbc.Col([
                    dbc.Button([
                        html.I(className="bi bi-plug me-1"),
                        "Test Connection"
                    ],
                        id=f"{db_side}-test-btn",
                        color="primary",
                        size="md",
                        disabled=True
                    ),
                    html.Div(id=f"{db_side}-status", className="mt-2")
                ], width=12)
            ])
        ])
    ], className="mb-4")

create_http_inputs Link

create_http_inputs(db_side)

Create inputs for HTTP database configuration

Source code in plantdb/client/sync_app/app.py
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def create_http_inputs(db_side):  # db_side is "source" or "target"
    """Create inputs for HTTP database configuration"""
    return dbc.Row([
        dbc.Col([
            dbc.InputGroup([
                dbc.InputGroupText(html.I(className="bi bi-link-45deg")),
                dbc.Input(
                    id=f"{db_side}-url",
                    placeholder="http://api.example.com:5000",
                    type="text",
                    value=""
                )
            ])
        ], width=12)
    ], id=f"{db_side}-http-inputs", className="mb-3", style={"display": "none"})

create_local_inputs Link

create_local_inputs(db_side)

Create inputs for local database configuration

Source code in plantdb/client/sync_app/app.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
def create_local_inputs(db_side):  # db_side is "source" or "target"
    """Create inputs for local database configuration"""
    return dbc.Row([
        dbc.Col([
            dbc.InputGroup([
                dbc.InputGroupText(html.I(className="bi bi-folder2-open")),
                dbc.Input(
                    id=f"{db_side}-path",
                    placeholder="/path/to/database",
                    type="text",
                    value=""
                )
            ])
        ], width=12)
    ], id=f"{db_side}-local-inputs", className="mb-3", style={"display": "none"})

create_scan_list_card Link

create_scan_list_card(title, list_id, search_id=None)

Create a card for displaying scan lists

Source code in plantdb/client/sync_app/app.py
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
def create_scan_list_card(title, list_id, search_id=None):
    """Create a card for displaying scan lists"""
    search_component = []
    if search_id:
        search_component = [
            dbc.InputGroup([
                dbc.InputGroupText(html.I(className="bi bi-search")),
                dbc.Input(
                    id=search_id,
                    placeholder="Search scans...",
                    type="text"
                ),
                dbc.Button([
                    html.I(className="bi bi-x-circle"),
                    " Clear"
                ],
                    id=f"{search_id}-clear",
                    color="secondary",
                    outline=True
                )
            ], className="mb-3")
        ]

    return dbc.Card([
        dbc.CardHeader(html.H4([html.I(className="bi bi-card-list me-2"), title], className="mb-0")),
        dbc.CardBody([
            *search_component,
            dbc.Checklist(
                id=list_id,
                options=[],
                value=[],
                inline=False,
                switch=True
            ),
            html.Div([
                html.I(className="bi bi-info-circle me-1"),
                html.Span(id=f"{list_id}-info")
            ], className="mt-2 text-muted small")
        ])
    ])

create_ssh_inputs Link

create_ssh_inputs(db_side)

Create inputs for SSH database configuration

Source code in plantdb/client/sync_app/app.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def create_ssh_inputs(db_side):  # db_side is "source" or "target"
    """Create inputs for SSH database configuration"""
    return html.Div([
        dbc.Row([
            dbc.Col([
                dbc.InputGroup([
                    dbc.InputGroupText(html.I(className="bi bi-globe")),
                    dbc.Input(
                        id=f"{db_side}-hostname",
                        placeholder="server.example.com",
                        type="text",
                        value=""
                    )
                ])
            ], width=6),
            dbc.Col([
                dbc.InputGroup([
                    dbc.InputGroupText(html.I(className="bi bi-folder2")),
                    dbc.Input(
                        id=f"{db_side}-ssh-path",
                        placeholder="/path/to/database",
                        type="text",
                        value=""
                    )
                ])
            ], width=6)
        ], className="mb-3"),
        dbc.Row([
            dbc.Col([
                dbc.InputGroup([
                    dbc.InputGroupText(html.I(className="bi bi-person")),
                    dbc.Input(
                        id=f"{db_side}-username",
                        placeholder="username",
                        type="text",
                        value=""
                    )
                ])
            ], width=6),
            dbc.Col([
                dbc.InputGroup([
                    dbc.InputGroupText(html.I(className="bi bi-key")),
                    dbc.Input(
                        id=f"{db_side}-password",
                        placeholder="password",
                        type="password",
                        value=""
                    )
                ])
            ], width=6)
        ], className="mb-3")
    ], id=f"{db_side}-ssh-inputs", style={"display": "none"})

get_scans_for_db Link

get_scans_for_db(config)

Get list of scans for a database configuration

Source code in plantdb/client/sync_app/app.py
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
def get_scans_for_db(config):
    """Get list of scans for a database configuration"""

    def _try_refresh(url):
        try:
            response = make_api_request(url)
        except Exception as e:
            refreshed = False
        else:
            refreshed = response.status_code == 200
        return refreshed

    try:
        if config["type"] == "local":
            path = Path(config["spec"])
            db = FSDB(path)
            db.connect()
            try:
                return db.list_scans(owner_only=False)
            finally:
                db.disconnect()
        elif config["type"] == "http":
            from plantdb.client.rest_api import refresh_url
            from plantdb.client.rest_api.requests import make_api_request
            url = refresh_url(**config)
            refreshed = _try_refresh(url)
            n_attempts = 0
            while not refreshed:
                if n_attempts >= 3:
                    break
                n_attempts += 1
                time.sleep(5)
                refreshed = _try_refresh(url)
            return request_scan_names_list(**config)
        elif config["type"] == "ssh":
            # For SSH, we'll need to use the sync instance's SSH methods
            # This is a simplified version - in practice you'd use the FSDBSync methods
            return []
        return []
    except Exception:
        return []

main Link

main(port, debug)

Dash UI for FSDBSync - PlantDB Database Synchronization Tool

A web-based user interface for synchronizing databases between different types (local, SSH, HTTP).

Source code in plantdb/client/sync_app/app.py
874
875
876
877
878
879
880
881
882
883
884
885
886
@click.command(context_settings=dict(help_option_names=["-h", "--help"]))
@click.option("--port", type=int, default=8050, help="Port to run the web application on")
@click.option("--debug", is_flag=True, help="Enable debug mode")
def main(port, debug):
    """Dash UI for FSDBSync - PlantDB Database Synchronization Tool

    A web-based user interface for synchronizing databases between different types (local, SSH, HTTP).
    """
    # Get the logger and change the level if needed:
    logger = get_logger(os.environ.get('ROMI_APP_LOGGER', __name__))
    logger.setLevel(DEFAULT_LOG_LEVEL)  # Using default log level for web app

    app.run(host="0.0.0.0", port=port, debug=debug)