Skip to content

new_user

plantimager.webui.new_user Link

User Registration Components for Plant Imager Web UI.

This module provides the user interface components and functionality for creating new user accounts in the Plant Imager system.

Key Features
  • User registration form with validation
  • Real-time username availability checking
  • Password confirmation validation
  • Secure account creation via REST API
  • Comprehensive error handling and user feedback

register_user Link

register_user(n_clicks, username, fullname, password, confirm_password, host, port, prefix)

Process user registration by validating inputs and creating a new account.

This callback handles the complete user registration process, including input validation, password matching, and account creation through the backend API.

Parameters:

Name Type Description Default
n_clicks int or None

Number of times the register button has been clicked. None before the first click.

required
username str

The desired username for the new account.

required
fullname str

The full name of the user.

required
password str

The desired password for the new account.

required
confirm_password str

Password confirmation entry.

required
host str

The hostname or IP address of the PlantDB REST API server.

required
port int

The port number of the PlantDB REST API server.

required
prefix str

The prefix of the PlantDB REST API server.

required

Returns:

Type Description
Union[str, Alert]

Either an empty string (if no clicks) or a Bootstrap alert component containing: - Success message if registration is successful - Error message if validation fails or API request fails

Notes

The function performs the following validations: - Username must not yet exist in the Backend API - All fields must be non-empty - Passwords must match - Backend API must successfully create the account

Raises:

Type Description
RequestException

If there are network connectivity issues or API errors.

JSONDecodeError

If the API response contains invalid JSON data.

Source code in plantimager/webui/new_user.py
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
@callback(
    Output("registration-message", "children"),
    [Input("register-button", "n_clicks")],
    [State("new-username-input", "value"),
     State("new-fullname-input", "value"),
     State("new-password-input", "value"),
     State("confirm-password-input", "value"),
     State("rest-api-host", "data"),
     State("rest-api-port", "data"),
     State("rest-api-prefix", "data")],
    prevent_initial_call=True
)
def register_user(n_clicks: int | None, username: str, fullname: str, password: str, 
               confirm_password: str, host: str, port: str, prefix:str) -> str | dbc.Alert:
    """Process user registration by validating inputs and creating a new account.

    This callback handles the complete user registration process, including input
    validation, password matching, and account creation through the backend API.

    Parameters
    ----------
    n_clicks : int or None
        Number of times the register button has been clicked. ``None`` before the first click.
    username : str
        The desired username for the new account.
    fullname : str
        The full name of the user.
    password : str
        The desired password for the new account.
    confirm_password : str
        Password confirmation entry.
    host : str
       The hostname or IP address of the PlantDB REST API server.
    port : int
        The port number of the PlantDB REST API server.
    prefix : str
        The prefix of the PlantDB REST API server.

    Returns
    -------
    Union[str, dbc.Alert]
        Either an empty string (if no clicks) or a Bootstrap alert component containing:
        - Success message if registration is successful
        - Error message if validation fails or API request fails

    Notes
    -----
    The function performs the following validations:
    - Username must not yet exist in the Backend API
    - All fields must be non-empty
    - Passwords must match
    - Backend API must successfully create the account

    Raises
    ------
    requests.exceptions.RequestException
        If there are network connectivity issues or API errors.
    json.JSONDecodeError
        If the API response contains invalid JSON data.
    """
    if not n_clicks:
        return ""

    if not _validate_new_username(username, host, port, prefix):
        return dbc.Alert(f"Username '{username}' is unavailable!", color="danger", class_name="mb-0")

    if not all([username, fullname, password, confirm_password]):
        return dbc.Alert("All fields are required!", color="danger", class_name="mb-0")

    if password != confirm_password:
        return dbc.Alert("Passwords do not match!", color="danger", class_name="mb-0")

    try:
        response = requests.post(
            urljoin(base_url(host, port, prefix), 'register'),
            data=json.dumps({
                'username': username,
                'fullname': fullname,
                'password': password
            }),
            headers={'Content-Type': 'application/json'}
        )

        if response.ok:
            return dbc.Alert("Registration successful! You can now login.", color="success", class_name="mb-0")
        else:
            error_msg = "Registration failed"
            try:
                error_data = response.json()
                if 'message' in error_data:
                    error_msg = error_data['message']
            except json.JSONDecodeError:
                error_msg = response.text
            return dbc.Alert(error_msg, color="danger", class_name="mb-0")

    except requests.exceptions.RequestException as e:
        return dbc.Alert(f"Connection error: {str(e)}", color="danger", class_name="mb-0")

toggle_register_modal Link

toggle_register_modal(new_user_clicks, is_open)

Toggle the visibility state of the new user registration modal.

This callback controls the opening and closing of the registration modal dialog when the new user button is clicked.

Parameters:

Name Type Description Default
new_user_clicks int or None

Number of times the new user button has been clicked. None before first click.

required
is_open bool

Current state of the modal dialog (True if open, False if closed).

required

Returns:

Type Description
bool

The new state of the modal dialog - toggled from current state if button was clicked.

Source code in plantimager/webui/new_user.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
@callback(
    Output("new-user-modal", "is_open"),
    Input("new-user-button", "n_clicks"),
    State("new-user-modal", "is_open"),
    prevent_initial_call=True
)
def toggle_register_modal(new_user_clicks: int | None, is_open: bool) -> bool:
    """Toggle the visibility state of the new user registration modal.

    This callback controls the opening and closing of the registration modal dialog
    when the new user button is clicked.

    Parameters
    ----------
    new_user_clicks : int or None
        Number of times the new user button has been clicked. ``None`` before first click.
    is_open : bool
        Current state of the modal dialog (True if open, False if closed).

    Returns
    -------
    bool
        The new state of the modal dialog - toggled from current state if button
        was clicked.
    """
    if new_user_clicks:
        return not is_open
    return is_open

validate_new_username Link

validate_new_username(new_username, is_modal_open, host, port, prefix)

Validate if the entered username is available for registration.

Makes an API request to check if the username already exists in the system. Updates the validation state of the username input field accordingly.

Parameters:

Name Type Description Default
new_username str or None

The username entered by the user to validate.

required
is_modal_open bool

Current state of the registration modal.

required
host str

The hostname or IP address of the PlantDB REST API server.

required
port int

The port number of the PlantDB REST API server.

required
prefix str

The prefix of the PlantDB REST API server.

required

Returns:

Type Description
Tuple[bool, bool]

A tuple containing: - bool: True if username is available (valid new username), False otherwise. - bool: True if username exists or there's an error (invalid new username), False otherwise.

Raises:

Type Description
RequestException

If there are network connectivity issues or API errors.

Source code in plantimager/webui/new_user.py
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
207
208
209
210
211
212
213
214
215
216
@callback(
    Output('new-username-input', 'valid'),
    Output('new-username-input', 'invalid'),
    Input('new-username-input', 'value'),
    State('new-user-modal', 'is_open'),
    State('rest-api-host', 'data'),
    State('rest-api-port', 'data'),
    State('rest-api-prefix', 'data'),
)
def validate_new_username(new_username: str | None, is_modal_open: bool, host: str, port: str, prefix:str) -> tuple[bool, bool]:
    """Validate if the entered username is available for registration.

    Makes an API request to check if the username already exists in the system.
    Updates the validation state of the username input field accordingly.

    Parameters
    ----------
    new_username : str or None
        The username entered by the user to validate.
    is_modal_open : bool
        Current state of the registration modal.
    host : str
       The hostname or IP address of the PlantDB REST API server.
    port : int
        The port number of the PlantDB REST API server.
    prefix : str
        The prefix of the PlantDB REST API server.

    Returns
    -------
    Tuple[bool, bool]
        A tuple containing:
        - bool: ``True`` if username is available (valid new username), ``False`` otherwise.
        - bool: ``True`` if username exists or there's an error (invalid new username), ``False`` otherwise.

    Raises
    ------
    requests.exceptions.RequestException
        If there are network connectivity issues or API errors.
    """
    if not is_modal_open or not new_username:
        return False, False
    valid_username = _validate_new_username(new_username, host, port, prefix)
    return valid_username, ~valid_username

validate_password_match Link

validate_password_match(password, confirm_password)

Validate that the password and confirmation password match.

Provides real-time validation feedback for both password input fields, ensuring they contain identical values.

Parameters:

Name Type Description Default
password str or None

The value entered in the new password field.

required
confirm_password str or None

The value entered in the password confirmation field.

required

Returns:

Type Description
Tuple[bool, bool, bool, bool]

A tuple of four boolean values in the order: - bool: True if passwords match and not empty, False otherwise. - bool: True if passwords don't match, False otherwise. - bool: True if passwords match and not empty, False otherwise. - bool: True if passwords don't match, False otherwise.

Notes

Returns all False values if either password field is empty.

Source code in plantimager/webui/new_user.py
219
220
221
222
223
224
225
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
266
267
268
269
270
@callback(
    [
        Output("new-password-input", "valid"),
        Output("new-password-input", "invalid"),
        Output("confirm-password-input", "valid"),
        Output("confirm-password-input", "invalid")
    ],
    [
        Input("new-password-input", "value"),
        Input("confirm-password-input", "value")
    ]
)
def validate_password_match(password: str | None, confirm_password: str | None) -> tuple[bool, bool, bool, bool]:
    """Validate that the password and confirmation password match.

    Provides real-time validation feedback for both password input fields,
    ensuring they contain identical values.

    Parameters
    ----------
    password : str or None
        The value entered in the new password field.
    confirm_password : str or None
        The value entered in the password confirmation field.

    Returns
    -------
    Tuple[bool, bool, bool, bool]
        A tuple of four boolean values in the order:
        - bool: ``True`` if passwords match and not empty, ``False`` otherwise.
        - bool: ``True`` if passwords don't match, ``False`` otherwise.
        - bool: ``True`` if passwords match and not empty, ``False`` otherwise.
        - bool: ``True`` if passwords don't match, ``False`` otherwise.

    Notes
    -----
    Returns all ``False`` values if either password field is empty.
    """
    if not password or not confirm_password:
        return (
            False,  # new password not valid
            False,  # new password not invalid
            False,  # confirm password not valid
            False  # confirm password not invalid
        )
    passwords_match = password == confirm_password
    return (
        passwords_match,  # new password valid state
        not passwords_match,  # new password invalid state
        passwords_match,  # confirm password valid state
        not passwords_match  # confirm password invalid state
    )