Python Driver
  1. Python Driver
  2. PYTHON-199

Connection requires use of *optional* username:password@ when uri is used

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major - P3 Major - P3
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None
    • Environment:
      pymongo 1.9
    • # Replies:
      11
    • Last comment by Customer:
      false

      Description

      pymongo.Connection(host="mongodb://mongohost/mongodb")

      yields

      raise InvalidURI("cannot specify database without "
      pymongo.errors.InvalidURI: cannot specify database without a username and password

        Activity

        Hide
        Roger Binns
        added a comment -
        Your tool can just do pymongo.Connection(<uri>).<database name>. No extra parameters required.

        That then requires the database name to be supplied as a separate parameter. An example of one of my tools is something that copies content from one database to another (excluding/updating some items as appropriate).

        $ tool.py --from mongodb://localhost/srcdb --to mongodb://server/destdb

        If the database can't be part of the URI then I'd need another two parameters to specify source and destination database names.

        I'd be happy with another API - eg pymongo.fromURI() - that takes a URI and returns the right thing. (It would be quite nice if the collection could be mentioned too.) Python does have a urlparse module but unfortunately it uses a hard coded list of which schemes take a hostname assuming not by default. You can monkeypatch it to add mongodb. But then you have to play games to provide a subset of the parsed URI back to pymongo to get the options parsed, multiple host:ports supported etc.

        Show
        Roger Binns
        added a comment - Your tool can just do pymongo.Connection(<uri>).<database name>. No extra parameters required. That then requires the database name to be supplied as a separate parameter. An example of one of my tools is something that copies content from one database to another (excluding/updating some items as appropriate). $ tool.py --from mongodb://localhost/srcdb --to mongodb://server/destdb If the database can't be part of the URI then I'd need another two parameters to specify source and destination database names. I'd be happy with another API - eg pymongo.fromURI() - that takes a URI and returns the right thing. (It would be quite nice if the collection could be mentioned too.) Python does have a urlparse module but unfortunately it uses a hard coded list of which schemes take a hostname assuming not by default. You can monkeypatch it to add mongodb. But then you have to play games to provide a subset of the parsed URI back to pymongo to get the options parsed, multiple host:ports supported etc.
        Hide
        Oscar Steele
        added a comment -

        Agreed, I ran into this issue because Im writing similar tools and some of our databases require username/password and some do not. The code would be much simpler if URI was implemented as documented.

        Show
        Oscar Steele
        added a comment - Agreed, I ran into this issue because Im writing similar tools and some of our databases require username/password and some do not. The code would be much simpler if URI was implemented as documented.
        Hide
        Bernie Hackett
        added a comment -

        I think we'll have to go with a separate API for this. We can't return a Database object calling pymongo.Connection() for the reason I mentioned above. Even if Python allowed this it would still be a bad idea.

        I'll work on a solution to solve your use cases.

        Show
        Bernie Hackett
        added a comment - I think we'll have to go with a separate API for this. We can't return a Database object calling pymongo.Connection() for the reason I mentioned above. Even if Python allowed this it would still be a bad idea. I'll work on a solution to solve your use cases.
        Hide
        Roger Binns
        added a comment -

        I have a half assed implementation in my code. It allows mongodb://user@host/db/collection where each part is optional although collection requires db.

        Sample code although it has some bugs to do with the authentication (should pass db name as well) and urlparse probably screws up the more complicated mongodb URI options.

        urlparse.uses_netloc.append("mongodb")
        urlparse.uses_relative.append("mongodb")
        urlparse.uses_params.append("mongodb")
        urlparse.uses_query.append("mongodb")

        def from_uri(uri):
        o=urlparse.urlparse(uri)

        if o.scheme!="mongodb":
        raise ValueError("Not a mongodb url")

        conn=pymongo.Connection("mongodb://"
        +(o.netloc if o.netloc else "localhost")
        +("/?"+o.query if o.query else ""))
        if not o.path or o.path=="/":
        return conn

        p=o.path
        if p[0]=="/":
        p=p[1:]
        parts=p.split("/", 1)
        db=conn[urlparse.unquote(parts[0])]

        if len(parts)==1:
        return db

        return db[urlparse.unquote(parts[1])]

        Show
        Roger Binns
        added a comment - I have a half assed implementation in my code. It allows mongodb://user@host/db/collection where each part is optional although collection requires db. Sample code although it has some bugs to do with the authentication (should pass db name as well) and urlparse probably screws up the more complicated mongodb URI options. urlparse.uses_netloc.append("mongodb") urlparse.uses_relative.append("mongodb") urlparse.uses_params.append("mongodb") urlparse.uses_query.append("mongodb") def from_uri(uri): o=urlparse.urlparse(uri) if o.scheme!="mongodb": raise ValueError("Not a mongodb url") conn=pymongo.Connection("mongodb://" +(o.netloc if o.netloc else "localhost") +("/?"+o.query if o.query else "")) if not o.path or o.path=="/": return conn p=o.path if p [0] =="/": p=p [1:] parts=p.split("/", 1) db=conn[urlparse.unquote(parts [0] )] if len(parts)==1: return db return db[urlparse.unquote(parts [1] )]
        Hide
        Bernie Hackett
        added a comment -

        I've opened PYTHON-243 to track moving the URI parser out of connection.py into it's own module. This work is mostly complete already. I'm hoping this will work for the use cases listed here. I'm going to close this bug. Feel free to reopen if my proposed solution won't work and we can discuss other workarounds.

        Show
        Bernie Hackett
        added a comment - I've opened PYTHON-243 to track moving the URI parser out of connection.py into it's own module. This work is mostly complete already. I'm hoping this will work for the use cases listed here. I'm going to close this bug. Feel free to reopen if my proposed solution won't work and we can discuss other workarounds.

          People

          • Votes:
            3 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since reply:
              3 years, 1 day ago
              Date of 1st Reply: