PythonNest / PyNest

PyNest is a Python framework built on top of FastAPI that follows the modular architecture of NestJS
https://pythonnest.github.io/PyNest
MIT License
643 stars 45 forks source link

ERROR: mongodb+srv:// URIs must not include a port number #42

Open MauroPerna opened 5 months ago

MauroPerna commented 5 months ago

I am using Mongo Atlas and the configuration needs "srv", I didn't specify the port number but get an error:

This is my database service:

import re
from src.services.database.entities.example.example_model import Example
from src.services.database.entities.property.property_model import properties
from src.common.utils.get_env import get_env
from src.services.config.config_service import ConfigService
from nest.core.database.odm_provider import OdmProvider

class DatabaseService:

    def __init__(self):
        config = ConfigService(get_env())
        mongo_uri = config.get('MONGO_URI')

        pattern = r"mongodb\+srv://([^:]+):([^@]+)@([^/]+)/([^?]+)"
        match = re.match(pattern, mongo_uri)

        if match:
            username, password, host, db_name = match.groups()
        else:
            raise ValueError("Unable to parse MONGO_URI")

        self.database = OdmProvider(
            config_params={
                "db_name": db_name,
                "host": host,
                "user": username,
                "password": password,
                "srv": True,
            },
            document_models=[properties, Example],
        )

    async def connect(self):
        await self.database.create_all()

And I get this error:

INFO:     Waiting for application startup.
ERROR:    Traceback (most recent call last):
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/starlette/routing.py", line 677, in lifespan
    async with self.lifespan_context(app) as maybe_state:
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/starlette/routing.py", line 566, in __aenter__
    await self._router.startup()
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/starlette/routing.py", line 654, in startup
    await handler()
  File "/Users/Mauro/imajine/mena-homes/analytics-service/app.py", line 32, in on_startup
    await database_service.connect()
  File "/Users/Mauro/imajine/mena-homes/analytics-service/src/services/database/database_service.py", line 35, in connect
    await self.database.create_all()
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/nest/core/database/odm_provider.py", line 48, in create_all
    client = AsyncIOMotorClient(self.config_url)
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/motor/core.py", line 163, in __init__
    delegate = self.__delegate_class__(*args, **kwargs)
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/pymongo/mongo_client.py", line 771, in __init__
    res = uri_parser.parse_uri(
  File "/Users/Mauro/imajine/mena-homes/analytics-service/venv/lib/python3.9/site-packages/pymongo/uri_parser.py", line 552, in parse_uri
    raise InvalidURI(f"{SRV_SCHEME} URIs must not include a port number")
pymongo.errors.InvalidURI: mongodb+srv:// URIs must not include a port number

Looking into this file venv/lib/python3.9/site-packages/nest/core/database/odm_config.py, I realized the port is always in the URI despite the server "srv" is True.

The solution I implemented is the following, replace the get_engine_url method by this one:

    def get_engine_url(self) -> str:
        """
        Returns the engine URL for the ORM.

        Returns:
            str: The engine URL.

        """

        if self.user and self.password:
            return f"mongodb{'+srv' if self.srv else ''}://{self.user}:{self.password}@{self.host}{f':{self.port}' if not(self.srv) else ''}"
        return f"mongodb{'+srv' if self.srv else ''}://{self.host}{f':{self.port}' if not(self.srv) else ''}"

Notice the port now is given under the srv condition. I will make a pull request solving this error.

Best regards, Mauro.

ItayTheDar commented 5 months ago

Hi @MauroPerna

This is really cool, i have no idea about this error!

Could you tag me as a reviwer once you open the pull request? It seems like an elegant solution for this issue.

By the way, is there a chance to see the whole code of your application? I wander how it looks like (especially the config service).

MauroPerna commented 4 months ago

Hi @ItayTheDar, sorry for the delay. I was on vacation haha.

I don't know why but I can't make the pull request.

I would be happy to show you my code, if you have an email I will be happy to share it with you.

ItayTheDar commented 4 months ago

Amazing! This is my email - itay2803@gmail.com

ItayTheDar commented 1 month ago

Hi @MauroPerna!

Could you share with me your code?