Fides Documentation – Ethyca

Development Tips

This page is dedicated to providing further context and information around specific implementation details such as code organization, running migrations and more.

If you're looking for a general getting started guide, please see the Overview.

API Endpoints Permalink for this section

API URLs Permalink for this section

We define API URLs for specific API versions as constants within fides.api.api.v1.urn_registry (where v1 can be substituted for that particular API version), then import those URLs into their specific API views. Since we are on the first version, there is no clear precedent set for overriding URLs between versions yet. The most likely change is that we'll override the APIRouter class instantiation with a different base path (ie. /api/v2 instead of /api/v1). For example:

PRIVACY_REQUEST = "/privacy-request"
PRIVACY_REQUEST_DETAIL = "/privacy-request/{privacy_request_id}"

would both resolve as /api/v1/privacy-request and /api/v1/privacy-request/{privacy_request_id} respectively.

Database and Models Permalink for this section

The ORM -- SQLAlchemy Permalink for this section

SQLAlchemy is an Object Relational Mapper, allowing us to avoid writing direct database queries within our codebase, and access the database via Python code instead. The ORM provides an additional configuration layer allowing user-defined Python classes to be mapped to database tables and other constructs, as well as an object persistence mechanism known as the Session. Some common uses cases are listed below, for a more comprehensive guide see here. (opens in a new tab)

Adding models Permalink for this section

Database tables are defined with model classes. Model files should live in src/fides/api/models/. Individual model classes must inherit from our custom base class at fides.api.db.base_class.Base to ensure uniformity within the database. Multiple models per file are encouraged so long as they fit the same logical delineation within the project. An example model declaration is added below. For a comprehensive guide see here. (opens in a new tab) You should also import your model in src/fides/api/db/base.py so it is visible for Alembic.

class Book(Base):
    __tablename__ = 'book'

id = Column(Integer, primary_key=True)
    name = Column(String, index=True)
    page_count = Column(Integer, nullable=True)
    author_id = Column(Integer, ForeignKey("author.id"), nullable=False)

When models are added to the project, we must then add them to the database in a recordable and repeatable fashion using migrations.

Using the database via models Permalink for this section

Once you've added database tables via project models, you're ready to read, write, and update them via Python code. Some examples of common use cases here are listed below. Official documentation is here (opens in a new tab)

SessionLocal = get_db_session(config)
db = SessionLocal()
db_obj = User(
    email="admin@fides.app",
    full_name="Fides Admin",
    is_superuser=True,
    is_active=True,
)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
user.email = "updated@fides.app"
db.add(user)
db.commit()
db.refresh()

Connecting to the database Permalink for this section

When you run nox -s dev, the database will spin up in a Docker container with port 5432 exposed on localhost. You can connect to it using the credentials found in .fides.toml, e.g.

Alembic migrations Permalink for this section

Some common Alembic commands are listed below. For a comprehensive guide see here (opens in a new tab).

The commands will need to be run inside a shell on your Docker containers, which can be opened with nox -s dev -- shell.

In the /src/fides/api/alembic directory:

When working on a PR with a migration, ensure that down_revision in the generated migration file correctly references the previous migration before submitting/merging the PR.

Exception Handling Permalink for this section

Our preference for exception handling is by overriding the nearest sensible error, for example:

class SomeException(ValueError):
    "a docstring"

def some_method():
    raise SomeException("a message")

General debugging -- pdb Permalink for this section

The project uses pdb for debugging as a dev-requirement. You can set breakpoints with pdb in much the same way you'd set them using debugger in Javascript. Insert import pdb; pdb.set_trace() into the line where you want the breakpoint to set, then run your Python code.

Docker Permalink for this section

As a last resort you may need to tear everything down in Docker and rebuild. The following commands will achieve that, but be warned that rebuild times can be long!

nox -s clean

!!! warning If you find yourself feeling the need to run this command regularly, open an issue or slack a member of the dev team as it is not expected that this will need to be run regularly.