Source code for auto_emailer.config.credentials

import io
import json
import warnings

import six

from auto_emailer.config import environment_vars


[docs]class Credentials: """Base class for Auto Emailer credentials.""" def __init__(self, sender_email=None, password=None, port=None, host=None): """ Args: sender_email (Optional[str]): The user name to authenticate SMTP client. Can be None if environment variables are configured. Equivalent environment variable: `EMAILER_SENDER`. password (Optional[str]): The password to authenticate SMTP client. Can be None if environment variables are configured. Equivalent environment variable: `EMAILER_PASSWORD`. port (Optional[str]): The port number of SMTP server. Equivalent environment variable: `EMAILER_HOST`. If neither config nor environment variable are set, then it will default to 587. host (Optional[str]): Host name of SMTP server. Equivalent environment variable: `EMAILER_PORT`. If neither config nor environment variable are set, then it will attempt to guess the host from the `emailer_address`. Warnings: Raises warning if port or host are none. """ self._sender_email = sender_email self._password = password self._port = port self._host = host if (self._port is None) or (self._host is None): warnings.simplefilter("always") warnings.warn('If explicitly passing args to initialize ' 'Credentials, please pass in `port` and `host` or ' 'use environment variables for configuration ' '{} and {}'.format(environment_vars.EMAILER_PORT, environment_vars.EMAILER_HOST) ) @property def sender_email(self): """User name for SMTP client.""" return self._sender_email @property def password(self): """Password for SMTP client.""" return self._password @property def port(self): """Port where SMTP server is listening.""" return self._port @property def host(self): """SMTP server host name.""" return self._host
[docs] @staticmethod def fill_missing_user_info(info): """Fills in automatically assigns `EMAILER_PORT` or `EMAILER_HOST` if they not set. Sets the default port to 587 and attempts to guess the host from the `EMAILER_SENDER`. Args: info (dict): Config dictionary object in auto_emailer format for initializing :func:`auto_emailer.config.credentials.Credentials` class instance. Returns: dict: Dictionary object with missing information filled. Raises: ValueError: If it cannot guess `EMAILER_HOST` from `EMAILER_SENDER`. """ if not info or not isinstance(info, dict): return info if (info['EMAILER_PORT'] is None) or (info['EMAILER_PORT'] is ""): info['EMAILER_PORT'] = 587 if (info['EMAILER_HOST'] is None) or (info['EMAILER_HOST'] is ""): if ('@outlook.com' in info['EMAILER_SENDER']) or \ ('@hotmail.com' in info['EMAILER_SENDER']): info['EMAILER_HOST'] = 'smtp.office365.com' elif '@gmail.com' in info['EMAILER_SENDER']: info['EMAILER_HOST'] = 'smtp.gmail.com' elif '@yahoo.com' in info['EMAILER_SENDER']: info['EMAILER_HOST'] = 'smtp.mail.yahoo.com' else: raise ValueError('Cannot guess host given email. ' 'Please explicitly set `EMAILER_HOST`.') return info
[docs] @classmethod def from_authorized_user_info(cls, info): """Creates a Credentials instance from parsed authorized user info. Args: info (dict): Config dictionary object in auto_emailer format for initializing :func:`auto_emailer.config.credentials.Credentials` class instance. Returns: auto_emailer.config.credentials.Credentials: The constructed credentials created from user configuration object. Raises: ValueError: If the authorized user info is not in the expected format (missing keys). """ keys_needed = {'EMAILER_SENDER', 'EMAILER_PASSWORD', 'EMAILER_HOST', 'EMAILER_PORT'} missing = keys_needed.difference(six.iterkeys(info)) if missing: raise ValueError('Authorized user info was not in the expected ' 'format, missing fields {}.' .format(', '.join(missing)) ) cls.fill_missing_user_info(info) return Credentials( sender_email=info['EMAILER_SENDER'], password=info['EMAILER_PASSWORD'], host=info['EMAILER_HOST'], port=info['EMAILER_PORT'])
[docs] @classmethod def from_authorized_user_file(cls, file_name): """Creates a Credentials instance from an authorized user json file. Args: file_name (str): The string path to the authorized user json file Returns: auto_emailer.config.credentials.Credentials: The constructed credentials created from user file attributes. Raises: ValueError: If the authorized user file is not in the expected format (json). """ with io.open(file_name, 'r', encoding='utf-8') as json_file: try: data = json.load(json_file) except ValueError: raise ValueError('File {} is not a valid json file.' .format(file_name) ) return cls.from_authorized_user_info(data)