Skip to content

Naming

By having consistent naming conventions, we make our code more readable at first sight. Additionally, it gives us hints about what exactly we are importing from a module.

All asynchronous functions must be prefixed with a_.

async def a_call_api() -> Response:

In some cases, we have sync and async versions of the same function. In this case, the prefix should be the only difference between the two.

async def a_call_api() -> Response:
def call_api() -> Response:

All endpoints must be prefixed with e_.

@app.get("/user")
async def e_get_user() -> User:

With this, we avoid potential conflicts between endpoints and functions that perform actions closely tied to those endpoints.

For example, suppose we want to implement an endpoint to retrieve a template given its name.

templates.py
def get_template(name: str) -> Template:

We can use this function in an endpoint.

from templates import get_template
@app.get("/template")
async def get_template(name: str) -> Template:
return get_template(name)

In this case, this causes a clash between the two function names. We could rename one of them with a synonym, but that’s typically not the cleanest solution.

We avoid this by prefixing the endpoint function with e_.

from templates import get_template
@app.get("/template")
async def e_get_template(name: str) -> Template:
return get_template(name)

All database calls must be prefixed with db_.

from modules.db.core.synchronous import db_get_document
@app.get("/document")
async def e_get_document(id: str) -> Document:
return db_get_document(id)

For the vector database, we use the dbv_ prefix.

from modules.db.vector.synchronous import dbv_get_document_summaries
@app.get("/document/summaries")
async def e_get_document_summaries(id: str) -> list[str]:
return dbv_get_document_summaries(id)

Asynchronous database calls must include the a_ prefix as well. This translates to adb_ for the regular database and adbv_ for the vector database.

Celery tasks must be prefixed with t_. This makes importing them straightforward, avoiding any confusion with regular functions.

from tasks import t_generate_presentation
@app.post("/presentation/generate")
async def e_generate_presentation() -> JSONResponse:
return t_generate_presentation.delay()

If a task access the database, we also include the database prefix. This results in the prefix tdb_ for regular database calls and tdbv_ for vector database calls.

Private functions are functions that are only used within a module. To mark this, they must be prefixed with a single underscore _. They should always be declared as top level private functions of the module. For example:

def _print_letter(letter: str) -> None:
print(f"Letter: {letter}")

Across our codebase, we have naming conventions for files. These conventions convey information about the content and purpose of the file.

Here is an overview of all of these conventions.

  • api.py: Endpoints.
  • tasks.py: Celery tasks.
  • models.py: Pydantic models.
  • exceptions.py: Custom errors.
  • agents.py: AI agents.
  • prompts.py: LLM prompts.
  • config.py: Constants.
  • tests.py: Test suites.