Skip to content

Conversation

@anuragxxd
Copy link
Member

@anuragxxd anuragxxd commented Aug 25, 2025

…DBNAME overrides

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have updated the documentation (or documentation does not need to be updated)
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have not reduced the existing code coverage

Summary by Sourcery

Enhance MongoDB client registration to support using a full MONGO_URI environment variable with optional database name overrides via MONGO_DBNAME, falling back to legacy component-based configuration if not provided.

New Features:

  • Allow providing a full MongoDB connection string via MONGO_URI environment variable
  • Enable overriding the database name in the URI using the MONGO_DBNAME environment variable

Tests:

  • Add tests to verify client creation with MONGO_URI and with MONGO_URI plus MONGO_DBNAME override

@sourcery-ai
Copy link

sourcery-ai bot commented Aug 25, 2025

Reviewer's Guide

Enhance MongoDB client registration to prioritize a full connection URI from environment variables (MONGO_URI) with optional database name override (MONGO_DBNAME), while retaining legacy component-based construction; added corresponding tests for these scenarios.

Sequence diagram for MongoDB client creation with MONGO_URI and MONGO_DBNAME overrides

sequenceDiagram
    participant App as Flask App
    participant Env as Environment Variables
    participant PyMongo as PyMongo
    participant Logger as Logger
    App->>Env: Get MONGO_URI
    alt MONGO_URI is set
        App->>Env: Get MONGO_DBNAME
        alt MONGO_DBNAME is set
            App->>App: Parse and override DB name in URI
        else MONGO_DBNAME not set
            App->>App: Use provided MONGO_URI as-is
        end
        App->>PyMongo: Register client with MONGO_URI
        App->>Logger: Log registration with DB name
    else MONGO_URI not set
        App->>Env: Get legacy components (username, password, host, etc.)
        App->>PyMongo: Register client with constructed URI
    end
Loading

Class diagram for enhanced MongoDB client registration

classDiagram
    class Flask {
    }
    class PyMongo {
    }
    class MongoConfig {
    }
    class DBConfig {
    }
    class register_mongodb {
        +_create_mongo_client(app, db, config)
    }
    Flask --> PyMongo : uses
    register_mongodb --> Flask : receives app
    register_mongodb --> PyMongo : creates client
    register_mongodb --> MongoConfig : uses config
    register_mongodb --> DBConfig : uses config
Loading

File-Level Changes

Change Details Files
Prefer environment-provided MONGO_URI for MongoDB client construction with optional database override
  • Import urlparse and urlunparse for URI parsing and reconstruction
  • Add code branch to detect MONGO_URI and optionally replace its path using MONGO_DBNAME
  • Configure app.config['MONGO_URI'], initialize PyMongo, log the registration, and return early
foca/database/register_mongodb.py
Add tests for MONGO_URI support and database override behavior
  • Verify that setting only MONGO_URI leads to correct config and PyMongo instantiation
  • Verify that setting both MONGO_URI and MONGO_DBNAME overrides the database segment in the URI
tests/database/test_register_mongodb.py

Possibly linked issues

  • add .gitignore #1: The PR implements MONGO_URI environment variable support and MONGO_DBNAME overrides, directly fulfilling the issue's request.

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!

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

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • The broad exception in the URI override block can mask unexpected issues—consider catching only specific parsing errors so other problems aren’t swallowed.
  • Extract the URI parsing and database‐override logic into a dedicated helper to simplify and improve the readability of _create_mongo_client.
  • It would help to log the actual overridden database name (or a sanitized form of the final URI) to make it easier to verify which connection string is in use.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The broad exception in the URI override block can mask unexpected issues—consider catching only specific parsing errors so other problems aren’t swallowed.
- Extract the URI parsing and database‐override logic into a dedicated helper to simplify and improve the readability of _create_mongo_client.
- It would help to log the actual overridden database name (or a sanitized form of the final URI) to make it easier to verify which connection string is in use.

## Individual Comments

### Comment 1
<location> `foca/database/register_mongodb.py:144` </location>
<code_context>
+                    parsed.query,
+                    parsed.fragment,
+                ))
+            except Exception:
+                # In case of any parsing issues, fall back to using the
+                # provided URI as-is; PyMongo will validate later.
</code_context>

<issue_to_address>
Avoid broad exception handling for URI parsing.

Catching only relevant exceptions like ValueError will prevent unrelated errors from being hidden.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
            except Exception:
                # In case of any parsing issues, fall back to using the
                # provided URI as-is; PyMongo will validate later.
                pass
=======
            except ValueError:
                # In case of any parsing issues, fall back to using the
                # provided URI as-is; PyMongo will validate later.
                pass
>>>>>>> REPLACE

</suggested_fix>

### Comment 2
<location> `foca/database/register_mongodb.py:150` </location>
<code_context>
+                pass
+        app.config['MONGO_URI'] = provided_uri
+        mongo = PyMongo(app)
+        logger.info(
+            "Registered database '{db}' using provided MONGO_URI.".format(
+                db=os.environ.get('MONGO_DBNAME', db)
+            )
</code_context>

<issue_to_address>
Consider logging the actual URI or its components for traceability.

Including more details from the URI (excluding sensitive information) in the log will improve traceability and aid in debugging connection problems.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
        app.config['MONGO_URI'] = provided_uri
        mongo = PyMongo(app)
        logger.info(
            "Registered database '{db}' using provided MONGO_URI.".format(
                db=os.environ.get('MONGO_DBNAME', db)
            )
        )
        return mongo
=======
        app.config['MONGO_URI'] = provided_uri
        mongo = PyMongo(app)
        # Parse URI for traceability (excluding credentials)
        try:
            from urllib.parse import urlparse
            parsed_uri = urlparse(provided_uri)
            host_info = parsed_uri.hostname
            port_info = parsed_uri.port
            db_name = os.environ.get('MONGO_DBNAME', db)
            logger.info(
                "Registered database '%s' using MONGO_URI host='%s', port='%s', db='%s'.",
                db_name,
                host_info,
                port_info,
                parsed_uri.path.lstrip('/') if parsed_uri.path else db_name
            )
        except Exception as e:
            logger.info(
                "Registered database '%s' using provided MONGO_URI (could not parse components: %s).",
                os.environ.get('MONGO_DBNAME', db),
                str(e)
            )
        return mongo
>>>>>>> REPLACE

</suggested_fix>

### Comment 3
<location> `tests/database/test_register_mongodb.py:84` </location>
<code_context>
     assert isinstance(res, MongoConfig)


+def test__create_mongo_client_with_mongo_uri(monkeypatch):
+    """When MONGO_URI environment variable IS defined, prefer it."""
+    # SRV style and options should be accepted without modification
+    mongo_uri = "mongodb://user:pass@db1.example.com:27017,db2.example.com:27017/admin?replicaSet=rs0&ssl=true"
+    monkeypatch.setenv("MONGO_URI", mongo_uri)
+    app = Flask(__name__)
+    res = _create_mongo_client(app)
+    assert isinstance(res, PyMongo)
+    assert app.config['MONGO_URI'] == mongo_uri
+
+
</code_context>

<issue_to_address>
Missing test for invalid MONGO_URI values.

Add a test with an invalid MONGO_URI to confirm the function handles errors and falls back correctly.
</issue_to_address>

### Comment 4
<location> `tests/database/test_register_mongodb.py:95` </location>
<code_context>
+    assert app.config['MONGO_URI'] == mongo_uri
+
+
+def test__create_mongo_client_with_mongo_uri_and_db_override(monkeypatch):
+    """When MONGO_URI and MONGO_DBNAME are both defined, override db name."""
+    mongo_uri = "mongodb://localhost:27017/old_db?retryWrites=true&w=majority"
+    monkeypatch.setenv("MONGO_URI", mongo_uri)
+    monkeypatch.setenv("MONGO_DBNAME", "new_db")
+    app = Flask(__name__)
+    res = _create_mongo_client(app)
+    assert isinstance(res, PyMongo)
+    assert app.config['MONGO_URI'].startswith("mongodb://localhost:27017/new_db")
+    assert "retryWrites=true" in app.config['MONGO_URI']
+
+
</code_context>

<issue_to_address>
Missing test for MONGO_DBNAME override when MONGO_URI has no path.

Add a test case where MONGO_URI lacks a database path and MONGO_DBNAME is set to verify correct URI construction.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +144 to +147
except Exception:
# In case of any parsing issues, fall back to using the
# provided URI as-is; PyMongo will validate later.
pass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Avoid broad exception handling for URI parsing.

Catching only relevant exceptions like ValueError will prevent unrelated errors from being hidden.

Suggested change
except Exception:
# In case of any parsing issues, fall back to using the
# provided URI as-is; PyMongo will validate later.
pass
except ValueError:
# In case of any parsing issues, fall back to using the
# provided URI as-is; PyMongo will validate later.
pass

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, given that FOCA will manage error handling gracefully, I don't think the try-except block is not needed at all here - certainly not if we just catch a broad exception and then just silently ignore it. So either catch a ValueError and log an appropriate warning OR just remove the try/catch altogether.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right—silently catching all exceptions can mask real issues and make debugging harder. Since FOCA will handle errors gracefully, you have two solid options:

  1. Remove the try/except block entirely: If the URI is malformed, let the error propagate. PyMongo or FOCA's error handling will catch and log it appropriately. This keeps the code clean and transparent.

  2. Catch only ValueError and log a warning: If you want to handle just URI parsing errors, catch ValueError and log a warning so users know their override was ignored. For example:

try:
    parsed = urlparse(provided_uri)
    new_path = f"/{db_override}"
    provided_uri = urlunparse((
        parsed.scheme,
        parsed.netloc,
        new_path,
        parsed.params,
        parsed.query,
        parsed.fragment,
    ))
except ValueError:
    logger.warning(
        "Failed to parse MONGO_URI for DBNAME override; using original URI."
    )

Both approaches are valid, but logging a warning is more user-friendly if you expect misconfiguration to happen. If you prefer simplicity and trust downstream error handling, removing the block is fine too.

Let me know if you'd like a specific code suggestion for either approach!

Comment on lines +148 to +155
app.config['MONGO_URI'] = provided_uri
mongo = PyMongo(app)
logger.info(
"Registered database '{db}' using provided MONGO_URI.".format(
db=os.environ.get('MONGO_DBNAME', db)
)
)
return mongo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider logging the actual URI or its components for traceability.

Including more details from the URI (excluding sensitive information) in the log will improve traceability and aid in debugging connection problems.

Suggested change
app.config['MONGO_URI'] = provided_uri
mongo = PyMongo(app)
logger.info(
"Registered database '{db}' using provided MONGO_URI.".format(
db=os.environ.get('MONGO_DBNAME', db)
)
)
return mongo
app.config['MONGO_URI'] = provided_uri
mongo = PyMongo(app)
# Parse URI for traceability (excluding credentials)
try:
from urllib.parse import urlparse
parsed_uri = urlparse(provided_uri)
host_info = parsed_uri.hostname
port_info = parsed_uri.port
db_name = os.environ.get('MONGO_DBNAME', db)
logger.info(
"Registered database '%s' using MONGO_URI host='%s', port='%s', db='%s'.",
db_name,
host_info,
port_info,
parsed_uri.path.lstrip('/') if parsed_uri.path else db_name
)
except Exception as e:
logger.info(
"Registered database '%s' using provided MONGO_URI (could not parse components: %s).",
os.environ.get('MONGO_DBNAME', db),
str(e)
)
return mongo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that logging is very useful, but the suggested implementation is quite clunky. See whether you can sanitize the MONGO_URI in a way that printing it without errors is ensured (so that the try-catch is not needed). Also, use f-strings instead of %s.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right—logging should be both informative and clean. You can sanitize the MONGO_URI for logging by parsing it and reconstructing a version that omits credentials, then log the relevant components using f-strings. Since urlparse does not raise exceptions for malformed URIs, you can avoid the try-catch block entirely.

Here's a suggested approach:

from urllib.parse import urlparse

app.config['MONGO_URI'] = provided_uri
mongo = PyMongo(app)
parsed = urlparse(provided_uri)

# Sanitize URI for logging (omit username and password)
host_info = parsed.hostname or 'unknown-host'
port_info = parsed.port or 'default-port'
db_name = os.environ.get('MONGO_DBNAME', db)
uri_scheme = parsed.scheme or 'mongodb'
uri_path = parsed.path.lstrip('/') or db_name

logger.info(
    f"Registered database '{db_name}' using {uri_scheme}://{host_info}:{port_info}/{uri_path} (sanitized)."
)

This will ensure the log is both readable and safe, and uses f-strings for clarity. Let me know if you'd like further refinements!

Comment on lines 84 to 92
def test__create_mongo_client_with_mongo_uri(monkeypatch):
"""When MONGO_URI environment variable IS defined, prefer it."""
# SRV style and options should be accepted without modification
mongo_uri = "mongodb://user:[email protected]:27017,db2.example.com:27017/admin?replicaSet=rs0&ssl=true"
monkeypatch.setenv("MONGO_URI", mongo_uri)
app = Flask(__name__)
res = _create_mongo_client(app)
assert isinstance(res, PyMongo)
assert app.config['MONGO_URI'] == mongo_uri
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Missing test for invalid MONGO_URI values.

Add a test with an invalid MONGO_URI to confirm the function handles errors and falls back correctly.

Comment on lines 95 to 104
def test__create_mongo_client_with_mongo_uri_and_db_override(monkeypatch):
"""When MONGO_URI and MONGO_DBNAME are both defined, override db name."""
mongo_uri = "mongodb://localhost:27017/old_db?retryWrites=true&w=majority"
monkeypatch.setenv("MONGO_URI", mongo_uri)
monkeypatch.setenv("MONGO_DBNAME", "new_db")
app = Flask(__name__)
res = _create_mongo_client(app)
assert isinstance(res, PyMongo)
assert app.config['MONGO_URI'].startswith("mongodb://localhost:27017/new_db")
assert "retryWrites=true" in app.config['MONGO_URI']
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Missing test for MONGO_DBNAME override when MONGO_URI has no path.

Add a test case where MONGO_URI lacks a database path and MONGO_DBNAME is set to verify correct URI construction.

@uniqueg uniqueg changed the title feat: enhance MongoDB client creation to support MONGO_URI and MONGO_… feat(db): support MONGO_URI for db creation Aug 26, 2025
Copy link
Member

@uniqueg uniqueg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @anuragxxd! Please add the stuff we discussed and address the issues raised by Sourcery (and commented by me). Otherwise, looks good :)

Comment on lines +144 to +147
except Exception:
# In case of any parsing issues, fall back to using the
# provided URI as-is; PyMongo will validate later.
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, given that FOCA will manage error handling gracefully, I don't think the try-except block is not needed at all here - certainly not if we just catch a broad exception and then just silently ignore it. So either catch a ValueError and log an appropriate warning OR just remove the try/catch altogether.

Comment on lines +148 to +155
app.config['MONGO_URI'] = provided_uri
mongo = PyMongo(app)
logger.info(
"Registered database '{db}' using provided MONGO_URI.".format(
db=os.environ.get('MONGO_DBNAME', db)
)
)
return mongo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that logging is very useful, but the suggested implementation is quite clunky. See whether you can sanitize the MONGO_URI in a way that printing it without errors is ensured (so that the try-catch is not needed). Also, use f-strings instead of %s.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants