def login(self, adapter, provider_name, callback=None,<EOL>session=None, session_saver=None, **kwargs):
if provider_name:<EOL><INDENT>provider_settings = self.config.get(provider_name)<EOL>if not provider_settings:<EOL><INDENT>raise ConfigError('<STR_LIT>'<EOL>.format(provider_name))<EOL><DEDENT>if not (session is None or session_saver is None):<EOL><INDENT>session = session<EOL>session_saver = session_saver<EOL><DEDENT>else:<EOL><INDENT>session = Session(adapter=adapter,<EOL>secret=self.secret,<EOL>max_age=self.session_max_age,<EOL>name=self.prefix,<EOL>secure=self.secure_cookie)<EOL>session_saver = session.save<EOL><DEDENT>class_ = provider_settings.get('<STR_LIT>')<EOL>if not class_:<EOL><INDENT>raise ConfigError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(provider_name))<EOL><DEDENT>ProviderClass = resolve_provider_class(class_)<EOL>ProviderClass._logger = self._logger<EOL>provider = ProviderClass(self,<EOL>adapter=adapter,<EOL>provider_name=provider_name,<EOL>callback=callback,<EOL>session=session,<EOL>session_saver=session_saver,<EOL>**kwargs)<EOL>return provider.login()<EOL><DEDENT>else:<EOL><INDENT>self.backend(adapter)<EOL><DEDENT>
If :data:`provider_name` specified, launches the login procedure for
corresponding :doc:`provider </reference/providers>` and returns
:class:`.LoginResult`.

If :data:`provider_name` is empty, acts like
:meth:`.Authomatic.backend`.

.. warning::

    The method redirects the **user** to the **provider** which in
    turn redirects **him/her** back to the *request handler* where
    it has been called.

:param str provider_name:
    Name of the provider as specified in the keys of the :doc:`config`.

:param callable callback:
    If specified the method will call the callback with
    :class:`.LoginResult` passed as argument and will return nothing.

:param bool report_errors:

.. note::

    Accepts additional keyword arguments that will be passed to
    :doc:`provider <providers>` constructor.

:returns:
    :class:`.LoginResult`