Skip to content

test_rest_api

plantdb.server.test_rest_api Link

TestRestApiServer Link

TestRestApiServer(db_path=None, port=5000, host='127.0.0.1', prefix='', ssl=False, test=False, empty=False, models=False)

A test REST API server that runs in a separate thread for testing purposes.

This class creates a Flask application that serves a PlantDB REST API and runs it in a separate thread so it doesn't block the current interpreter.

Attributes:

Name Type Description
db_path Path

Path to the database directory

port int

Port number for the server

host str

Host address for the server

prefix str

URL prefix for API endpoints

ssl bool

Whether to use SSL/HTTPS

test bool

Whether to run in test mode, that is to populate with the test dataset (default: False)

empty bool

Whether to create an empty database (default: False)

models bool

Whether to create a database with models (default: False)

app Flask

Flask application instance

server BaseWSGIServer

WSGI server instance

thread Thread

Thread running the server

Examples:

>>> from plantdb.server.test_rest_api import TestRestApiServer
>>> from plantdb.client.rest_api import list_scan_names
>>>
>>> # EXAMPLE 1 - Create a test database and start the Flask App serving a REST API
>>> server = TestRestApiServer(test=True)
>>> server.start()
>>> scans_list = list_scan_names(host=server.host, port=server.port, prefix=server.prefix, ssl=server.ssl)
>>> print(scans_list)
['arabidopsis000', 'real_plant', 'real_plant_analyzed', 'virtual_plant', 'virtual_plant_analyzed']
>>> server.stop()
>>>
>>> # EXAMPLE 2 - Serve an existing database
>>> from plantdb.commons.test_database import test_database
>>> test_db = test_database()  # set up a temporary test database
>>> print(test_db.path())
/tmp/ROMI_DB_********
>>> server = TestRestApiServer(db_path=test_db.path())
>>> server.start()
>>> list_scan_names(host=server.host, port=server.port, prefix=server.prefix, ssl=server.ssl)
>>> print(scans_list)
['real_plant_analyzed']
>>> server.stop()

Initialize the test REST API server.

Parameters:

Name Type Description Default
db_path str or Path

Path to the database directory to serve

None
port int

Port number for the server (default: 5000)

5000
host str

Host address for the server (default: '127.0.0.1')

'127.0.0.1'
prefix str

URL prefix for API endpoints (default: '')

''
ssl bool

Whether to use SSL/HTTPS (default: False)

False
test bool

Whether to run in test mode, that is to populate with the test dataset (default: False)

False
empty bool

Whether to create an empty database (default: False)

False
models bool

Whether to create a database with models (default: False)

False
Source code in plantdb/server/test_rest_api.py
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def __init__(self, db_path=None, port=5000, host='127.0.0.1', prefix='', ssl=False, test=False, empty=False,
             models=False):
    """Initialize the test REST API server.

    Parameters
    ----------
    db_path : str or pathlib.Path, optional
        Path to the database directory to serve
    port : int, optional
        Port number for the server (default: 5000)
    host : str, optional
        Host address for the server (default: '127.0.0.1')
    prefix : str, optional
        URL prefix for API endpoints (default: '')
    ssl : bool, optional
        Whether to use SSL/HTTPS (default: False)
    test : bool, optional
        Whether to run in test mode, that is to populate with the test dataset (default: False)
    empty : bool, optional
        Whether to create an empty database (default: False)
    models : bool, optional
        Whether to create a database with models (default: False)
    """
    self.db_path = db_path if db_path else _mkdtemp_romidb()
    self.port = port
    self.host = host
    self.prefix = prefix
    self.ssl = ssl
    self.test = test
    self.empty = empty
    self.models = models
    self.app = None
    self.server = None
    self.thread = None
    self.logger = get_logger(__name__)
    self._setup_flask_app()

__enter__ Link

__enter__()

Context manager entry.

Source code in plantdb/server/test_rest_api.py
190
191
192
193
def __enter__(self):
    """Context manager entry."""
    self.start()
    return self

__exit__ Link

__exit__(exc_type, exc_val, exc_tb)

Context manager exit.

Source code in plantdb/server/test_rest_api.py
195
196
197
def __exit__(self, exc_type, exc_val, exc_tb):
    """Context manager exit."""
    self.stop()

get_base_url Link

get_base_url()

Get the base URL for the API.

Returns:

Type Description
str

The base URL for the API.

Source code in plantdb/server/test_rest_api.py
175
176
177
178
179
180
181
182
183
184
def get_base_url(self):
    """Get the base URL for the API.

    Returns
    -------
    str
        The base URL for the API.
    """
    protocol = 'https' if self.ssl else 'http'
    return f"{protocol}://{self.host}:{self.port}{self.prefix}"

get_server_config Link

get_server_config()

Get the server configuration settings.

Source code in plantdb/server/test_rest_api.py
186
187
188
def get_server_config(self):
    """Get the server configuration settings."""
    return {"host": self.host, "port": self.port, "prefix": self.prefix, "ssl": self.ssl}

is_running Link

is_running()

Check if the server is running.

Source code in plantdb/server/test_rest_api.py
171
172
173
def is_running(self):
    """Check if the server is running."""
    return self.thread is not None and self.thread.is_alive()

start Link

start()

Start the REST API server in a separate thread.

Source code in plantdb/server/test_rest_api.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
def start(self):
    """Start the REST API server in a separate thread."""
    if self.thread is not None and self.thread.is_alive():
        return  # Already running

    # Check if port is available
    if not self._is_port_available():
        raise RuntimeError(f"Port {self.port} is already in use on host {self.host}")

    # Create server
    self.server = make_server(self.host, self.port, self.app, threaded=True)

    # Start server in separate thread
    self.thread = threading.Thread(target=self.server.serve_forever, daemon=True)
    self.thread.start()

    # Wait a bit for server to start
    time.sleep(0.5)

    self.logger.info(f"Test REST API server started at {self.get_base_url()}")

stop Link

stop()

Stop the REST API server.

Source code in plantdb/server/test_rest_api.py
159
160
161
162
163
164
165
166
167
168
169
def stop(self):
    """Stop the REST API server."""
    if self.server:
        self.server.shutdown()
        self.server = None

    if self.thread and self.thread.is_alive():
        self.thread.join(timeout=5.0)
        self.thread = None

    self.logger.info("Test REST API server stopped")

test_rest_api Link

test_rest_api(db_path, port=5000, host='127.0.0.1', prefix='', ssl=False)

Create and return a TestRestApi instance.

This is a convenience function that creates a TestRestApi instance with the specified parameters. The returned instance can be used to start/stop a test REST API server.

Parameters:

Name Type Description Default
db_path str or Path

Path to the database directory to serve

required
port int

Port number for the server (default: 5000)

5000
host str

Host address for the server (default: '127.0.0.1')

'127.0.0.1'
prefix str

URL prefix for API endpoints (default: '/api/v1')

''
ssl bool

Whether to use SSL/HTTPS (default: False)

False

Returns:

Type Description
TestRestApiServer

Configured TestRestApi instance

Examples:

>>> from plantdb.commons.test_database import test_database
>>> from plantdb.server.test_rest_api import test_rest_api
>>> # Create test database
>>> db = test_database(dataset=None)
>>> # Create and start REST API server
>>> api = test_rest_api(db.path(), port=8080)
>>> api.start()
>>> # Use the API
>>> print(f"API running at: {api.get_base_url()}")
>>> # Stop the server
>>> api.stop()
>>>
>>> # Or use as context manager
>>> with test_rest_api(db.path(), port=8080) as api:
...     # API is running here
...     print(f"API URL: {api.get_base_url()}")
>>> # API is automatically stopped here
Source code in plantdb/server/test_rest_api.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
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
def test_rest_api(db_path, port=5000, host='127.0.0.1', prefix='', ssl=False):
    """Create and return a TestRestApi instance.

    This is a convenience function that creates a TestRestApi instance with the
    specified parameters. The returned instance can be used to start/stop a
    test REST API server.

    Parameters
    ----------
    db_path : str or pathlib.Path
        Path to the database directory to serve
    port : int, optional
        Port number for the server (default: 5000)
    host : str, optional
        Host address for the server (default: '127.0.0.1')
    prefix : str, optional
        URL prefix for API endpoints (default: '/api/v1')
    ssl : bool, optional
        Whether to use SSL/HTTPS (default: False)

    Returns
    -------
    TestRestApiServer
        Configured TestRestApi instance

    Examples
    --------
    >>> from plantdb.commons.test_database import test_database
    >>> from plantdb.server.test_rest_api import test_rest_api
    >>> # Create test database
    >>> db = test_database(dataset=None)
    >>> # Create and start REST API server
    >>> api = test_rest_api(db.path(), port=8080)
    >>> api.start()
    >>> # Use the API
    >>> print(f"API running at: {api.get_base_url()}")
    >>> # Stop the server
    >>> api.stop()
    >>>
    >>> # Or use as context manager
    >>> with test_rest_api(db.path(), port=8080) as api:
    ...     # API is running here
    ...     print(f"API URL: {api.get_base_url()}")
    >>> # API is automatically stopped here
    """
    return TestRestApiServer(db_path, port, host, prefix, ssl)