Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REF] Move environment variable handling to Pydantic BaseSettings class #416

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

alyssadai
Copy link
Contributor

@alyssadai alyssadai commented Feb 21, 2025

Changes proposed in this pull request:

  • Replace all global variables for environment variables with a single Settings class using pydantic-settings
  • Use pytest-env to set a subset of environment vars to non-default values in the environment before any tests run, to allow basic test that environment variables are read in correctly
    • otherwise, since environment variables are read in on app startup (meaning the TestClient used by tests already has a settings instance), modifying settings values are done through simply monkeypatching attributes
  • Change dummy test of invalid credentials to a meaningful integration test

Housekeeping:

  • Update some leftover Pydantic v1 syntax
  • Update README badges

Checklist

This section is for the PR reviewer

  • PR has an interpretable title with a prefix ([ENH], [FIX], [REF], [TST], [CI], [MNT], [INF], [MODEL], [DOC]) (see our Contributing Guidelines for more info)
  • PR has a label for the release changelog or skip-release (to be applied by maintainers only)
  • PR links to GitHub issue with mention Closes #XXXX
  • Tests pass
  • Checks pass
  • If the PR changes the SPARQL query template, the default Neurobagel query file has also been regenerated

For new features:

  • Tests have been added

For bug fixes:

  • There is at least one test that would fail under the original bug conditions.

Summary by Sourcery

This pull request refactors the application to use Pydantic's BaseSettings for managing environment variables. This change improves code maintainability and type safety by centralizing environment variable configuration and validation within a dedicated settings class. The application now uses a settings object to access environment variables, and tests have been updated to reflect this change.

Enhancements:

  • Migrated environment variable handling to Pydantic BaseSettings class for improved type safety and validation.
  • Replaced direct access to environment variables with the new settings object.

Tests:

  • Updated tests to use the new settings object instead of directly patching environment variables.
  • Added a new test module to verify that settings are read correctly from environment variables.

Summary by Sourcery

Refactors the application to use Pydantic's BaseSettings for managing environment variables, improving code maintainability and type safety. Tests have been updated to reflect this change.

Enhancements:

  • Migrated environment variable handling to Pydantic BaseSettings class for improved type safety and validation.
  • Replaced direct access to environment variables with a settings object.

Tests:

  • Updated tests to use the new settings object instead of directly patching environment variables.
  • Added a new test module to verify that settings are read correctly from environment variables.
  • Added an integration test to verify that the app returns a 401 status code when given invalid credentials for the graph.

Chores:

  • Updated some leftover Pydantic v1 syntax.

@alyssadai alyssadai added the pr-internal Non-user-facing code improvement, will increment patch version when merged (0.0.+1) label Feb 21, 2025
Copy link

sourcery-ai bot commented Feb 21, 2025

Reviewer's Guide by Sourcery

This pull request refactors the application to use Pydantic's BaseSettings for managing environment variables. This change improves code maintainability and type safety by centralizing environment variable configuration and validation within a dedicated settings class. The application now uses a settings object to access environment variables, and tests have been updated to reflect this change. Additionally, pytest-env was implemented to set environment variables for testing.

Sequence diagram for accessing graph database

sequenceDiagram
    participant App
    participant Settings
    participant httpx

    App->>Settings: Access settings.query_url, settings.graph_username, settings.graph_password
    Settings-->>App: Return values
    App->>httpx: Post query to graph database using httpx.post(url=settings.query_url, auth=(settings.graph_username, settings.graph_password))
    httpx-->>App: Return response
Loading

Updated class diagram for Settings

classDiagram
    class Settings {
        +root_path: str
        +allowed_origins: str
        +graph_username: str | None
        +graph_password: str | None
        +graph_address: str
        +graph_db: str
        +graph_port: int
        +return_agg: bool
        +min_cell_size: int
        +auth_enabled: bool
        +client_id: str | None
        +query_url: str
    }
    note for Settings "Pydantic BaseSettings class for managing environment variables"
Loading

File-Level Changes

Change Details Files
Replaced global variables for environment variables with a Settings class using pydantic-settings.
  • Created a Settings class to manage environment variables.
  • Replaced direct access to environment variables with the new settings object.
  • Updated code to use the settings object to access environment variables.
  • Added a computed field for the query URL.
app/api/utility.py
app/main.py
app/api/crud.py
app/api/security.py
app/api/config.py
tests/test_settings.py
Implemented pytest-env to set environment variables for testing.
  • Installed pytest-env.
  • Configured pytest.ini to set environment variables for testing.
  • Updated tests to use the new settings object instead of directly patching environment variables.
  • Added a new test module to verify that settings are read correctly from environment variables.
tests/test_query.py
tests/test_app_events.py
tests/conftest.py
pytest.ini
tests/test_attribute_factory_routes.py
tests/test_pipelines.py
tests/test_attributes.py
tests/test_security.py
Updated Pydantic v1 syntax to v2.
  • Updated leftover Pydantic v1 syntax to v2.
app/api/crud.py
Improved integration test for invalid credentials.
  • Changed dummy test of invalid credentials to a meaningful integration test.
tests/test_query.py
tests/test_app_events.py

Assessment against linked issues

Issue Objective Addressed Explanation
#316 Refactor the environment variable reading to allow for easier testing and dynamic replacement of variable values.
#316 Use pydantic-settings to load environment variables.
#316 Ensure that the environment variables are read at import time.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

codecov bot commented Feb 21, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.30%. Comparing base (bc90678) to head (0659c2b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #416      +/-   ##
==========================================
+ Coverage   97.24%   97.30%   +0.05%     
==========================================
  Files          24       26       +2     
  Lines         835      852      +17     
==========================================
+ Hits          812      829      +17     
  Misses         23       23              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@alyssadai alyssadai marked this pull request as ready for review February 21, 2025 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-internal Non-user-facing code improvement, will increment patch version when merged (0.0.+1)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor environment variable reading using pydantic-settings
1 participant