Source code for bcp.connections

"""
This module contains data structures required to connect to a database. While Auth can be instantiated on its own,
you would generally create it at the same time as the connection. Since the Auth object will contain credentials, it's
recommended to set these through secure means, such as environmental variables, so as to not accidentally check in your
credentials to your source control. Even your host name can be considered sensitive data, depending on your and your
company's policies.

Example:

.. code-block:: python

    import os
    import bcp

    host = os.environ['HOST']
    username = os.environ['USERNAME']
    password = os.environ['PASSWORD']

    conn = bcp.Connection(host, 'mssql', username, password)
    my_bcp = bcp.BCP(conn)
"""
from .exceptions import DriverNotSupportedException, InvalidCredentialException


[docs]class Auth: """ This data structure collects the username and password as an authentication object. Args: username: username for the authorization password: password for the authorization """ def __init__(self, username: str = None, password: str = None): self.username = username self.password = password assert self.type @property def type(self) -> str: """ This property identifies the authorization type depending on the username/password provided. The two options for authorization are Trusted and Credential. A Trusted connection is created when no username and no password are provided. In this case, the local user's credentials and authorization method are used. A Credential connection is created when both a username and a password are provided. If only one of username and password are provided, this raises an InvalidCredentialException. Returns: the type of connection ('Trusted' or 'Credential') """ if self.username is None and self.password is None: return 'Trusted' elif self.username is not None and self.password is not None: return 'Credential' else: raise InvalidCredentialException def __repr__(self): return f'Auth(username={self.username}, password={len(self.password)})'
[docs]class Connection: """ This data structure describes a connection to be used to instantiate a BCP instance. A host and driver must be supplied. A username/password combination can also be supplied upon instantiation to automatically create an associated Auth object. Alternatively, this can be set as an attribute after instantiation. If the username/password are not provided, the connection will assume a Trusted authorization in the meantime. Args: driver: the type of database (mssql, etc.) host: the host where the database exists port: the port for the database server username: the username for authentication password: the password for authentication """ def __init__(self, driver: str, host: str, port: int = None, username: str = None, password: str = None): self.host = host self.port = port self.auth = Auth(username, password) self.driver = driver @property def driver(self) -> str: return self._driver @driver.setter def driver(self, value: str = None): if value not in ['mssql']: raise DriverNotSupportedException self._driver = value def __repr__(self): """ This differs from __str__() because we don't want tracebacks to accidentally display credentials in plain text. """ return f'Connection(driver={self.driver}, host={self.host}, port={self.port}, auth={repr(self.auth)})' def __str__(self): """ This will generate a BCP formatted connection string in the dialect of the associated database. Returns: a BCP formatted, dialect-specific, connection string """ if self.driver == 'mssql': if self.auth.type == 'Trusted': auth_string = f'-T' else: auth_string = f'-U {self.auth.username} -P {self.auth.password}' if self.port: machine = f'{self.host},{self.port}' else: machine = self.host return f'-S {machine} {auth_string}'