Skip to content

utils

plantimager.webui.utils Link

Utility Functions for Plant Imager Web UI.

This module provides common utility functions used across the Plant Imager web interface, particularly for interacting with the PlantDB REST API and handling configuration files.

config_upload Link

config_upload()

The TOML configuration file upload component.

Returns:

Type Description
Upload

A Dash Upload component configured for TOML files.

Source code in plantimager/webui/utils.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def config_upload() -> dcc.Upload:
    """The TOML configuration file upload component.

    Returns
    -------
    dcc.Upload
        A Dash Upload component configured for TOML files.
    """
    return dcc.Upload(
        children=['Drag and Drop or Select a TOML configuration file.'],
        id="cfg-upload",
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
        },
        accept=".toml",
        # Do not allow multiple files to be uploaded
        multiple=False
    )

get_dataset_dict Link

get_dataset_dict(host, port, prefix, ssl, access_token)

Returns the dataset dictionary for the PlantDB REST API at a given host url and port.

Parameters:

Name Type Description Default
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
ssl bool

Whether the PlantDB REST API server is using SSL or not.

required
access_token str

The PlantDB REST API access token.

required

Returns:

Type Description
dict[str, Any] | None

The dataset dictionary for the PlantDB REST API at a given host url and port. Returns None if no scans are found.

Examples:

>>> from plantimager.webui.utils import get_dataset_dict
>>> from plantdb.server.test_rest_api import TestRestApiServer
>>> server = TestRestApiServer("/data/ROMI/shared_fsdb")
>>> server.start()
>>> dataset_dict = get_dataset_dict('localhost', port=5000, prefix='', ssl=False)
>>> print(list(dataset_dict))
['arabidopsis000', 'real_plant', 'real_plant_analyzed', 'virtual_plant', 'virtual_plant_analyzed']
>>> print(list(dataset_dict['real_plant_analyzed']['metadata']))
['date', 'species', 'plant', 'environment', 'nbPhotos', 'files']
>>> server.stop()
See Also

plantdb.rest_api_client.request_scan_names_list plantdb.rest_api_client.parse_scans_info

Source code in plantimager/webui/utils.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def get_dataset_dict(host: str, port: int, prefix: str, ssl: bool, access_token: str) -> dict[str, Any] | None:
    """Returns the dataset dictionary for the PlantDB REST API at a given host url and port.

    Parameters
    ----------
    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.
    ssl : bool
        Whether the PlantDB REST API server is using SSL or not.
    access_token
        The PlantDB REST API access token.

    Returns
    -------
    dict[str, Any] | None
        The dataset dictionary for the PlantDB REST API at a given host url and port.
        Returns ``None`` if no scans are found.

    Examples
    --------
    >>> from plantimager.webui.utils import get_dataset_dict
    >>> from plantdb.server.test_rest_api import TestRestApiServer
    >>> server = TestRestApiServer("/data/ROMI/shared_fsdb")
    >>> server.start()
    >>> dataset_dict = get_dataset_dict('localhost', port=5000, prefix='', ssl=False)
    >>> print(list(dataset_dict))
    ['arabidopsis000', 'real_plant', 'real_plant_analyzed', 'virtual_plant', 'virtual_plant_analyzed']
    >>> print(list(dataset_dict['real_plant_analyzed']['metadata']))
    ['date', 'species', 'plant', 'environment', 'nbPhotos', 'files']
    >>> server.stop()

    See Also
    --------
    plantdb.rest_api_client.request_scan_names_list
    plantdb.rest_api_client.parse_scans_info
    """
    scans_list = sorted(request_scan_names_list(host, port=port, prefix=prefix, ssl=ssl, session_token=access_token))
    if len(scans_list) > 0:
        dataset_dict = parse_scans_info(host, port=port, prefix=prefix, ssl=ssl, session_token=access_token)
    else:
        dataset_dict = None
    return dataset_dict

load_image_from_url Link

load_image_from_url(url, access_token=None)

Load an image from a given URL and encode it to a base64 data URI.

Parameters:

Name Type Description Default
url str

The base URL to request.

required
access_token str

An access token used to authenticate against PlantDB.

None

Returns:

Type Description
str

A base64‑encoded data URI containing the image, or a fallback string such as "No Image" or "Error Loading" when the fetch is unsuccessful.

Examples:

>>> from plantimager.webui.utils import load_image_from_url
>>> from plantdb.server.test_rest_api import TestRestApiServer
>>> from plantdb.client.rest_api import scan_image_url
>>> server = TestRestApiServer("/data/ROMI/shared_fsdb")
>>> server.start()
>>> # Load a very small image:
>>> load_image_from_url(scan_image_url('localhost', "real_plant", "images", "00000_rgb", port=5000, size='10'))
'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUEBAQEAwUEBAQGBQUGCA0ICAcHCBALDAkNExAUExIQEhIUFx0ZFBYcFhISGiMaHB4fISEhFBkkJyQgJh0gISD/2wBDAQUGBggHCA8ICA8gFRIVICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICD/wAARCAAIAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5asPtK6SrCMOiqCTz8oJ71zUxzPIf9o/zooqVuwP/2Q=='
>>> load_image_from_url(scan_image_url('localhost', "real_plant", "images", "00000_rgb", port=5000, size='10', as_base64=True))
'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUEBAQEAwUEBAQGBQUGCA0ICAcHCBALDAkNExAUExIQEhIUFx0ZFBYcFhISGiMaHB4fISEhFBkkJyQgJh0gISD/2wBDAQUGBggHCA8ICA8gFRIVICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICD/wAARCAAIAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5asPtK6SrCMOiqCTz8oJ71zUxzPIf9o/zooqVuwP/2Q=='
>>> server.stop()
Source code in plantimager/webui/utils.py
152
153
154
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
def load_image_from_url(url, access_token=None):
    """Load an image from a given URL and encode it to a base64 data URI.

    Parameters
    ----------
    url : str
        The base URL to request.
    access_token : str
        An access token used to authenticate against PlantDB.

    Returns
    -------
    str
        A base64‑encoded data URI containing the image, or a fallback string
        such as "No Image" or "Error Loading" when the fetch is unsuccessful.

    Examples
    --------
    >>> from plantimager.webui.utils import load_image_from_url
    >>> from plantdb.server.test_rest_api import TestRestApiServer
    >>> from plantdb.client.rest_api import scan_image_url
    >>> server = TestRestApiServer("/data/ROMI/shared_fsdb")
    >>> server.start()
    >>> # Load a very small image:
    >>> load_image_from_url(scan_image_url('localhost', "real_plant", "images", "00000_rgb", port=5000, size='10'))
    'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUEBAQEAwUEBAQGBQUGCA0ICAcHCBALDAkNExAUExIQEhIUFx0ZFBYcFhISGiMaHB4fISEhFBkkJyQgJh0gISD/2wBDAQUGBggHCA8ICA8gFRIVICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICD/wAARCAAIAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5asPtK6SrCMOiqCTz8oJ71zUxzPIf9o/zooqVuwP/2Q=='
    >>> load_image_from_url(scan_image_url('localhost', "real_plant", "images", "00000_rgb", port=5000, size='10', as_base64=True))
    'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUEBAQEAwUEBAQGBQUGCA0ICAcHCBALDAkNExAUExIQEhIUFx0ZFBYcFhISGiMaHB4fISEhFBkkJyQgJh0gISD/2wBDAQUGBggHCA8ICA8gFRIVICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICD/wAARCAAIAAoDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5asPtK6SrCMOiqCTz8oJ71zUxzPIf9o/zooqVuwP/2Q=='
    >>> server.stop()
    """
    # Fetch image and convert to base64
    try:
        response = make_api_request(url=url, session_token=access_token, timeout=5)
        if response.ok:
            content_type = response.headers.get('Content-Type')
            encoding = response.headers.get("X-Content-Encoding")
            if encoding == 'binary':
                # Convert binary streaming to base64 encoding:
                encoded_img = pybase64.b64encode(response.content).decode('ascii')
                img_data = f"data:{content_type};base64,{encoded_img}"
            elif encoding == 'base64':
                # A base64 encoded image from JSON:
                content_type = response.json()['content-type']
                img_str = response.json()['image']
                img_data = f"data:{content_type};base64,{img_str}"
            else:
                img_data = f"Error processing sent image: Unknown content type: {content_type}"
        else:
            img_data = f"No Image: {response.status_code}"
    except Exception as e:
        img_data = f"Error Loading: {e}"
    return img_data