diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..58fbd75 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +DYNARAG_API_TOKEN= +DYNARAG_BASE_URL= diff --git a/README.md b/README.md index 58144c2..587644c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,23 @@ # DynaRAG -This is the Python client to the [DynaRAG API](https://www.dynarag.com). +This is the Python client to [DynaRAG](https://github.com/Predixus/DynaRAG). -DynaRAG provides a simple and fast interface to implement RAG (Retrieval Augemented Generation) into your application. +DynaRAG provides a simple and fast interface to implement RAG (Retrieval Augemented Generation) +into your application. ## Configuration -DynaRAG only requires an API token to get started. You can obtain an API token by going to the [DynaRAG App](https://app.dynarag.com), +DynaRAG requires some environment variables to get started: +- `DYNARAG_API_TOKEN` - a signed JWT that contains data needed by DynaRAG. Follow the spec in the [DynaRAG](https://github.com/Predixus/DynaRAG) +service repo. +- `DYNARAG_BASE_URL` - url to the DynaRAG service. e.g. http://localhost:7890 + +You can obtain an API token by going to the [DynaRAG App](https://app.dynarag.com), logging in and navigating to dashboard>developer. From here you can generate an API token. -> :warning: **API Token**: Put your API token into an environment varibale called `DYNARAG_API_TOKEN` in order for the DynaRAG Client to discover it. +> :warning: **API Token**: Put your API token into an environment variable called `DYNARAG_API_TOKEN` +> in order for the DynaRAG Client to discover it. This must be a JWT that follows the spec of the +> [DynaRAG service](https://github.com/Predixus/DynaRAG). ## Usage diff --git a/dynarag/constants.py b/dynarag/constants.py deleted file mode 100644 index a160495..0000000 --- a/dynarag/constants.py +++ /dev/null @@ -1 +0,0 @@ -DYNARAG_BASE_URL = "https://api.dynarag.com" diff --git a/dynarag/exceptions.py b/dynarag/exceptions.py index f38549c..fbb9a01 100644 --- a/dynarag/exceptions.py +++ b/dynarag/exceptions.py @@ -8,3 +8,7 @@ class MissingAPIToken(BaseException): class BadAPIRequest(BaseException): """Raised if a request to the DynaRAG API fails""" + + +class BadEnvironment(BaseException): + """Raised when the environment is bad""" diff --git a/dynarag/main.py b/dynarag/main.py index 057c544..44e0392 100644 --- a/dynarag/main.py +++ b/dynarag/main.py @@ -5,11 +5,18 @@ import urllib.request from typing import Any, Dict, List, TypeVar, Optional, TypedDict, cast -from dynarag.constants import DYNARAG_BASE_URL -from dynarag.exceptions import BadAPIRequest, MissingAPIToken +from dynarag.exceptions import BadAPIRequest, BadEnvironment, MissingAPIToken LOGGER = logging.getLogger(__name__) +try: + from dotenv import load_dotenv + + load_dotenv() + LOGGER.info("Environment variables loaded from .env file if it exists") +except ImportError: + LOGGER.debug("python-dotenv not installed, skipping .env loading") + T = TypeVar("T") @@ -51,17 +58,26 @@ class DynaRAGClient: def __init__(self) -> None: """Initialise the DynaRAG client.""" api_token = os.environ.get("DYNARAG_API_TOKEN", None) + base_url = os.environ.get("DYNARAG_BASE_URL", None) if not api_token: + error_str = "Could not find the `DYNARAG_API_TOKEN` environment variable. " + LOGGER.error(error_str) + raise MissingAPIToken(error_str) + if not base_url: error_str = ( - "Could not find the `DYNARAG_API_TOKEN` environment variable." - "You can obtain one by going to https://app.dynarag.com/dashboard/developer and generate a token." + "Could not find the `DYNARAG_BASE_URL` environment variable. " + "Set it to the URL of your DynaRAG service, e.g. http://localhost:7890. " + "Follow the instructions in the DynaRAG service repo to get started: " + "https://github.com/predixus/dynarag?tab=readme-ov-file#getting-started" ) LOGGER.error(error_str) - raise MissingAPIToken(error_str) + raise BadEnvironment(error_str) - LOGGER.info("Obtained DynaRAG API key. Successfully initialised.") + LOGGER.info( + "Obtained DynaRAG API key and service URL. Successfully initialised." + ) - self.base_url = DYNARAG_BASE_URL + self.base_url = base_url self.api_token = api_token def _make_request( diff --git a/poetry.lock b/poetry.lock index 669f58b..40273df 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "colorama" @@ -178,6 +178,20 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "pyyaml" version = "6.0.2" @@ -322,4 +336,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "892def42ce1f95dbe21baa7885ad6f91ed1e3e6617c3f40b49812d86cab27845" +content-hash = "5615a82ff69788b71fb9e8b04dc720307087c28b66a363aa2113f86935c78028" diff --git a/pyproject.toml b/pyproject.toml index edbbc3f..f469081 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ poethepoet = "^0.31.1" pytest = "^8.3.4" ruff = "^0.8.4" mypy = "^1.13.0" +python-dotenv = "^1.0.1" [build-system] requires = ["poetry-core"]