Skip to content

Commit 0cd353c

Browse files
eimrekml-evs
authored andcommitted
docs: create_app docstring, multiple_apps section, and integrated.md fixes
1 parent 73f65c4 commit 0cd353c

File tree

4 files changed

+68
-18
lines changed

4 files changed

+68
-18
lines changed

docs/deployment/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
title: "Deployment"
22
nav:
33
- integrated.md
4+
- multiple_apps.md
45
- container.md

docs/deployment/integrated.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
The `optimade` package can be used to create a standalone web application that serves the OPTIMADE API based on a pre-configured MongoDB backend.
44
In this document, we are going to use `optimade` differently and use it to add an OPTIMADE API implementation alongside an existing API that employs an Elasticsearch storage layer.
55

6-
Let's assume we already have a *FastAPI* application that runs an unrelated web service, and that we use an Elasticsearch backend that contains all structure data, but not necessarily in a form that OPTIMADE expects.
6+
Let's assume we already have a _FastAPI_ application that runs an unrelated web service, and that we use an Elasticsearch backend that contains all structure data, but not necessarily in a form that OPTIMADE expects.
77

88
## Providing the `optimade` configuration
99

@@ -13,7 +13,7 @@ If you run `optimade` code inside another application, you might want to provide
1313
Let's say you have a file `optimade_config.json` as part of the Python module that you use to create your OPTIMADE API.
1414

1515
!!! tip
16-
You can find more detailed information about configuring the `optimade` server in the [Configuration](../configuration.md) section.
16+
You can find more detailed information about configuring the `optimade` server in the [Configuration](../configuration.md) section.
1717

1818
Before importing any `optimade` modules, you can set the `OPTIMADE_CONFIG_FILE` environment variable to refer to your config file:
1919

@@ -37,30 +37,21 @@ structures.structures_coll = MyElasticsearchStructureCollection()
3737

3838
You can imagine that `MyElasticsearchStructureCollection` either sub-classes the default `optimade` Elasticsearch implementation ([`ElasticsearchCollection`][optimade.server.entry_collections.elasticsearch.ElasticCollection]) or sub-classes [`EntryCollection`][optimade.server.entry_collections.entry_collections.EntryCollection], depending on how deeply you need to customize the default `optimade` behavior.
3939

40-
## Mounting the OPTIMADE Python tools *FastAPI* app into an existing *FastAPI* app
40+
## Mounting the OPTIMADE Python tools _FastAPI_ app into an existing _FastAPI_ app
4141

42-
Let's assume you have an existing *FastAPI* app `my_app`.
42+
Let's assume you have an existing _FastAPI_ app `my_app`.
4343
It already implements a few routers under certain path prefixes, and now you want to add an OPTIMADE implementation under the path prefix `/optimade`.
4444

45-
First, you have to set the `root_path` in the `optimade` configuration, so that the app expects all requests to be prefixed with `/optimade`.
45+
The primary thing to modify is the `base_url` to match the new subpath. The easiest is to just update your configuration file or env parameters.
4646

47-
Second, you simply mount the `optimade` app into your existing app `my_app`:
47+
Then one can just simply do the following:
4848

4949
```python
50-
from optimade.server.config import CONFIG
50+
from optimade.server.main import main as optimade
5151

52-
CONFIG.root_path = "/optimade"
53-
54-
from optimade.server import main as optimade
55-
56-
optimade.add_major_version_base_url(optimade.app)
5752
my_app.mount("/optimade", optimade.app)
5853
```
5954

60-
!!! tip
61-
In the example above, we imported `CONFIG` before `main` so that our config was loaded before app creation.
62-
To avoid the need for this, the `root_path` can be set in your JSON config file, passed as an environment variable, or declared in a custom Python module (see [Configuration](../configuration.md)).
63-
64-
See also the *FastAPI* documentation on [sub-applications](https://fastapi.tiangolo.com/advanced/sub-applications/).
55+
See also the _FastAPI_ documentation on [sub-applications](https://fastapi.tiangolo.com/advanced/sub-applications/).
6556

66-
Now, if you run `my_app`, it will still serve all its routers as before and in addition it will also serve all OPTIMADE routes under `/optimade/` and the versioned URLs `/optimade/v1/`.
57+
Now, if you run `my_app`, it will still serve all its routers as before and in addition it will also serve all OPTIMADE routes under `/optimade/`.

docs/deployment/multiple_apps.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Serve multiple OPTIMADE APIs within a single python process
2+
3+
One can start multiple OPTIMADE API apps within a single FastAPI instance and mount them at different subpaths.
4+
5+
This is enabled by the `create_app` method that allows to override parts of the configuration for each specific app, and set up separate loggers.
6+
7+
Here's a simple example that sets up two OPTIMADE APIs and an Index Meta-DB respectively at subpaths `/app1`, `/app2` and `/idx`.
8+
9+
```python
10+
from fastapi import FastAPI
11+
12+
from optimade.server.config import ServerConfig
13+
from optimade.server.create_app import create_app
14+
15+
parent_app = FastAPI()
16+
17+
base_url = "http://127.0.0.1:8000"
18+
19+
conf1 = ServerConfig()
20+
conf1.base_url = f"{base_url}/app1"
21+
conf1.mongo_database = "optimade_1"
22+
app1 = create_app(conf1, logger_tag="app1")
23+
parent_app.mount("/app1", app1)
24+
25+
conf2 = ServerConfig()
26+
conf2.base_url = f"{base_url}/app2"
27+
conf2.mongo_database = "optimade_2"
28+
app2 = create_app(conf2, logger_tag="app2")
29+
parent_app.mount("/app2", app2)
30+
31+
conf3 = ServerConfig()
32+
conf3.base_url = f"{base_url}/idx"
33+
conf3.mongo_database = "optimade_idx"
34+
app3 = create_app(conf3, index=True, logger_tag="idx")
35+
parent_app.mount("/idx", app3)
36+
```
37+
38+
Note that `ServerConfig()` returns the configuration based on the usual sources - env variables or json file (see [Configuration](../configuration.md) section).

optimade/server/create_app.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,26 @@ def create_app(
188188
index: bool = False,
189189
logger_tag: str | None = None,
190190
) -> FastAPI:
191+
"""
192+
Create and configure a FastAPI app for the OPTIMADE API.
193+
194+
Sets up logging, middleware, exception handlers, routers, and optional
195+
test/JSONL data insertion. Can be used for both a regular OPTIMADE API
196+
or the index meta-database variant.
197+
198+
Note that the global ServerConfig instance is read from the "OPTIMADE_"
199+
env variables or the config json file, but this function allows to
200+
override config options for individual apps by passing a custom ServerConfig.
201+
202+
Args:
203+
config: ServerConfig instance to override config options specific to this app.
204+
index: If True, create an index meta-database instance.
205+
logger_tag: Optional tag for the logger.
206+
207+
Returns:
208+
Configured FastAPI application.
209+
"""
210+
191211
# create app-specific logger
192212
logger = create_logger(logger_tag, config)
193213

0 commit comments

Comments
 (0)