diff --git a/docs/how-tos/images/ragna-config-wizard.png b/docs/how-tos/images/ragna-config-wizard.png deleted file mode 100644 index 9575f2bc..00000000 --- a/docs/how-tos/images/ragna-config-wizard.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cdcb5768d034e99f1074a9b8652f9f1390b15cbd816bfe68e699890930eb2397 -size 1071739 diff --git a/docs/how-tos/set-configuration.md b/docs/how-tos/set-configuration.md deleted file mode 100644 index 0e38804b..00000000 --- a/docs/how-tos/set-configuration.md +++ /dev/null @@ -1,62 +0,0 @@ -# Set configuration - -Ragna's configuration includes setting the LLM, source storage, API endpoint, UI port, -and more. Your chat will use these configurations by default when provided. - -## Create a configuration file - -Storing your Ragna configuration in a file is the recommended approach for any serious -workflows. Ragna includes a CLI wizard to walk you through the process of creating this -file. - -Run the following command, and answer the questions when prompted: - -```bash -ragna init -``` - -![ragna config executed in the terminal showing questions and selections of the form: Which of the following statements describes best what you want to do? I want to try Ragna and its builtin components; How do you want to select the components? I want to manually select the builtin components I want to use. This continues to allow selecting the [Chroma] source storage and the [OpenAI/gpt-4] assistant.](images/ragna-config-wizard.png) - -At the end, this will create a `ragna.toml` file based on your choices. - -Here's an example configuration file: - -```toml -local_cache_root = "/Users//.cache/ragna" - -[core] -queue_url = "/Users//.cache/ragna/queue" -document = "ragna.core.LocalDocument" -source_storages = ["ragna.source_storages.Chroma"] -assistants = ["ragna.assistants.Gpt4"] - -[api] -url = "http://127.0.0.1:31476" -database_url = "sqlite:////Users//.cache/ragna/ragna.db" -authentication = "ragna.core.RagnaDemoAuthentication" -upload_token_secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -upload_token_ttl = 300 - -[ui] -url = "http://127.0.0.1:31477" -``` - -## Set configuration using the file - -You can use `ragna.toml` for setting configurations in your applications: - - - -```py -from ragna import Config - -config_path ="path-to-config-file" -config = Config.from_file(config_path) -``` - -!!! note - - In the Python API, the [ragna.Rag.chat][] function also allows you to set certain RAG-specific configurations like `document` and `assistants`. diff --git a/docs/references/config.md b/docs/references/config.md new file mode 100644 index 00000000..1d796ba2 --- /dev/null +++ b/docs/references/config.md @@ -0,0 +1,116 @@ +# Configuration reference + +Ragna uses [TOML](https://toml.io/en/) as language for its configuration file. The +`ragna` CLI defaults to `ragna.toml` in the current working directory. This behavior can +be overritten in two ways: + +1. The `RAGNA_CONFIG` environment variable. +2. The `-c` / `--config` option of the `ragna` CLI subcommands. + +The CLI option takes precedence over the environment variable. + +There are two main ways to generate a configuration file: + +1. Running `ragna init` in a terminal starts an interactive wizard that guides you + through the generation. The example configuration below is the result of choosing the + first option the wizard offers you. +2. The configuration can also be created programmatically from Python. The example + configuration below is the result of the following snippet. + + ```python + from ragna.deploy import Config + + config = Config() + config.to_file("ragna.toml") + ``` + +## Example + +```toml +{{ config }} +``` + +## Referencing Python objects + +Some configuration options reference Python objects, e.g. +`document = ragna.core.LocalDocument`. You can inject your own objects here and do not +need to rely on the defaults by Ragna. To do so, make sure that the module the object is +defined in is on the +[`PYTHONPATH`](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH). The +`document` configuration mentioned before internally is roughly treated as +`from ragna.core import LocalDocument`. + +## Environment variables + +All configuration options can be set or overritten by environment variables by using the +`RAGNA_` prefix. For example, `document = ragna.core.LocalDocument` in the configuration +file is equivalent to setting `RAGNA_DOCUMENT=ragna.core.LocalDocument`. + +For configuration options in subsections, the subsection name needs to be appended to +the prefix, e.g. `RAGNA_COMPONENTS_`. The value needs to be in JSON format. For example + +```toml +[components] +assistants = [ + "ragna.assistants.RagnaDemoAssistant", +] +``` + +is equivalent to +`RAGNA_COMPONENTS_ASSISTANTS='["ragna.assistants.RagnaDemoAssistant"]'`. + +## Configuration options + +### `local_cache_root` + +### `document` + +[ragna.core.Document][] class to use to upload and read documents. + +### `authentication` + +[ragna.deploy.Authentication][] class to use for authenticating users. + +### `components` + +#### `source_storages` + +[ragna.core.SourceStorage][]s to be available for the user to use. + +#### `assistants` + +[ragna.core.Assistant][]s to be available for the user to use. + +### `api` + +#### `url` + +1. Hostname and port the REST API server will be bound to. +2. URL of the REST API to be accessed by the web UI. + +#### `origins` + +[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) origins that are allowed +to connect to the REST API. The URL of the web UI is required for it to function. + +#### `database_url` + +URL of a SQL database that will be used to store the Ragna state. See +[SQLAlchemy documentation](https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls) +on how to format the URL. + +#### `root_path` + +A path prefix handled by a proxy that is not seen by the REST API, but is seen by +external clients. + +### `ui` + +#### `url` + +Hostname and port the web UI server will be bound to. + +#### `origins` + +[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) origins that are allowed +to connect to the web UI. diff --git a/docs/tutorials/python-api.md b/docs/tutorials/python-api.md index 28a0d084..02f71bb5 100644 --- a/docs/tutorials/python-api.md +++ b/docs/tutorials/python-api.md @@ -40,7 +40,7 @@ config = Config() config ``` -Learn more in [Set configuration](../how-tos/set-configuration.md). +Learn more in [Configuration reference](../references/config.md). ## Step 2: Upload relevant documents diff --git a/docs/tutorials/rest-api.md b/docs/tutorials/rest-api.md index f24211ff..4b4adede 100644 --- a/docs/tutorials/rest-api.md +++ b/docs/tutorials/rest-api.md @@ -28,7 +28,7 @@ from ragna import Config config = Config.from_file("ragna.toml") ``` -Learn more in [How to set configuration](../how-tos/set-configuration.md). +Learn more in [Configuration reference](../references/config.md). ## Step 2: Start and connect to the API diff --git a/mkdocs.yml b/mkdocs.yml index fbe07a5a..48bc48ca 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -80,14 +80,13 @@ nav: - "tutorials/python-api.md" - "tutorials/rest-api.md" - "tutorials/web-app.md" - - How-to: - - "how-tos/set-configuration.md" - Community: - "community/welcome.md" - "community/contribute.md" - References: - "references/python-api.md" - - "references/rest-api.md" - "references/cli.md" + - "references/config.md" + - "references/rest-api.md" - "references/faq.md" - "references/release-notes.md" diff --git a/ragna/deploy/_config.py b/ragna/deploy/_config.py index 9cb20fbc..758b6512 100644 --- a/ragna/deploy/_config.py +++ b/ragna/deploy/_config.py @@ -110,6 +110,11 @@ def from_file(cls, path: Union[str, Path]) -> Config: with open(path) as file: return cls.model_validate(tomlkit.load(file).unwrap()) + def __str__(self) -> str: + toml = tomlkit.item(self.model_dump(mode="json")) + self._set_multiline_array(toml) + return toml.as_string() + def _set_multiline_array(self, item: tomlkit.items.Item) -> None: if isinstance(item, tomlkit.items.Array): item.multiline(True) @@ -128,8 +133,5 @@ def to_file(self, path: Union[str, Path], *, force: bool = False) -> None: if path.exists() and not force: raise RagnaException(f"{path} already exist.") - toml = tomlkit.item(self.model_dump(mode="json")) - self._set_multiline_array(toml) - with open(path, "w") as file: - file.write(toml.as_string()) + file.write(str(self)) diff --git a/scripts/docs/gen_files.py b/scripts/docs/gen_files.py index f3d4c757..c50beb00 100644 --- a/scripts/docs/gen_files.py +++ b/scripts/docs/gen_files.py @@ -15,6 +15,7 @@ def main(): cli_reference() api_reference() + config_reference() def cli_reference(): @@ -54,4 +55,12 @@ def api_reference(): json.dump(openapi_json, file) +def config_reference(): + with mkdocs_gen_files.open("references/config.md", "r+") as file: + content = file.read().replace("{{ config }}", str(Config())) + file.seek(0) + file.write(content) + file.truncate() + + main()