# Path: cliche/config.py
# class ConfigDict(dict):
#     """Almost the same to the built-in :class:`dict` except it raises
#     :exc:`ConfigKeyError` instead of :exc:`KeyError` with finer error
#     message.
# 
#     """
# 
#     def __getitem__(self, key):
#         try:
#             return super().__getitem__(key)
#         except KeyError:
#             raise ConfigKeyError(key)
# 
# def read_config(filename):
#     """Read Cliche app configuration from the given filename.  ::
# 
#         config = read_config(filename='dev.cfg.yml')
# 
#     Note that it takes only one keyword argument at a time.  All parameters
#     are mutually exclusive for each other.
# 
#     :param filename: read config from a *filename* of yaml or
#                      python source code
#     :type filename: :class:`pathlib.Path`
#     :returns: the parsed dictionary with uppercase keys
#     :rtype: :class:`ConfigDict`
# 
#     """
#     if not isinstance(filename, pathlib.Path):
#         raise TypeError(
#             'expected an instance of {0.__module__}.{0.__qualname__}'
#             ', not {1!r}'.format(pathlib.Path, filename)
#         )
#     if filename.suffix in ('.yml', '.yaml'):
#         return read_config_from_yaml(filename=filename)
#     if filename.suffix != '.py':
#         warnings.warn(
#             'the suffix of {0} represents niether Python (.py) nor '
#             'YAML (.yml/.yaml);  treat it as Python',
#             RuntimeWarning, stacklevel=2
#         )
#     return read_config_from_python(filename=filename)
# 
# Path: cliche/orm.py
# def make_repr(self):
# def get_alembic_config(engine):
# def initialize_database(engine):
# def get_database_revision(engine):
#     def get_revision(rev, context):
# def upgrade_database(engine, revision='head'):
#     def upgrade(rev, context):
#         def update_current_rev(old, new):
# def downgrade_database(engine, revision):
# def import_all_modules(dry_run=False):  # FIXME


import os
import pathlib
from celery import Celery, current_app, current_task
from celery.loaders.base import BaseLoader
from celery.signals import celeryd_init, task_failure, task_postrun
from raven import Client
from raven.conf import setup_logging
from raven.handlers.logging import SentryHandler
from sqlalchemy.engine import Engine, create_engine
from .config import ConfigDict, read_config
from .orm import Session, import_all_modules
            'CELERY_CONFIG_MODULE',
            os.environ.get('CLICHE_CONFIG')
        )
        if config_path is not None:
            config = read_config(pathlib.Path(config_path))
        config['CELERY_IMPORTS'] = import_all_modules()
        config['CELERY_ACCEPT_CONTENT'] = ['pickle', 'json']
        return config


def get_database_engine() -> Engine:
    """Get a database engine.

    :returns: a database engine
    :rtype: :class:`sqlalchemy.engine.base.Engine`

    """
    config = current_app.conf
    if 'DATABASE_ENGINE' not in config:
        db_url = config['DATABASE_URL']
        config['DATABASE_ENGINE'] = create_engine(db_url)
        if 'BROKER_URL' not in config:
            config['BROKER_URL'] = 'sqla+' + db_url
        if 'CELERY_RESULT_BACKEND' not in config and \
                'CELERY_RESULT_DBURI' not in config:
            config['CELERY_RESULT_BACKEND'] = 'database'
            config['CELERY_RESULT_DBURI'] = db_url
    return config['DATABASE_ENGINE']



# Path: cliche/config.py
# class ConfigDict(dict):
#     """Almost the same to the built-in :class:`dict` except it raises
#     :exc:`ConfigKeyError` instead of :exc:`KeyError` with finer error
#     message.
# 
#     """
# 
#     def __getitem__(self, key):
#         try:
#             return super().__getitem__(key)
#         except KeyError:
#             raise ConfigKeyError(key)
# 
# def read_config(filename):
#     """Read Cliche app configuration from the given filename.  ::
# 
#         config = read_config(filename='dev.cfg.yml')
# 
#     Note that it takes only one keyword argument at a time.  All parameters
#     are mutually exclusive for each other.
# 
#     :param filename: read config from a *filename* of yaml or
#                      python source code
#     :type filename: :class:`pathlib.Path`
#     :returns: the parsed dictionary with uppercase keys
#     :rtype: :class:`ConfigDict`
# 
#     """
#     if not isinstance(filename, pathlib.Path):
#         raise TypeError(
#             'expected an instance of {0.__module__}.{0.__qualname__}'
#             ', not {1!r}'.format(pathlib.Path, filename)
#         )
#     if filename.suffix in ('.yml', '.yaml'):
#         return read_config_from_yaml(filename=filename)
#     if filename.suffix != '.py':
#         warnings.warn(
#             'the suffix of {0} represents niether Python (.py) nor '
#             'YAML (.yml/.yaml);  treat it as Python',
#             RuntimeWarning, stacklevel=2
#         )
#     return read_config_from_python(filename=filename)
# 
# Path: cliche/orm.py
# def make_repr(self):
# def get_alembic_config(engine):
# def initialize_database(engine):
# def get_database_revision(engine):
#     def get_revision(rev, context):
# def upgrade_database(engine, revision='head'):
#     def upgrade(rev, context):
#         def update_current_rev(old, new):
# def downgrade_database(engine, revision):
# def import_all_modules(dry_run=False):  # FIXME


# Path: cliche/celery.py
import os
import pathlib
from celery import Celery, current_app, current_task
from celery.loaders.base import BaseLoader
from celery.signals import celeryd_init, task_failure, task_postrun
from raven import Client
from raven.conf import setup_logging
from raven.handlers.logging import SentryHandler
from sqlalchemy.engine import Engine, create_engine
from .config import ConfigDict, read_config
from .orm import Session, import_all_modules

            'CELERY_CONFIG_MODULE',
            os.environ.get('CLICHE_CONFIG')
        )
        if config_path is not None:
            config = read_config(pathlib.Path(config_path))
        config['CELERY_IMPORTS'] = import_all_modules()
        config['CELERY_ACCEPT_CONTENT'] = ['pickle', 'json']
        return config


def get_database_engine() -> Engine:
    """Get a database engine.

    :returns: a database engine
    :rtype: :class:`sqlalchemy.engine.base.Engine`

    """
    config = current_app.conf
    if 'DATABASE_ENGINE' not in config:
        db_url = config['DATABASE_URL']
        config['DATABASE_ENGINE'] = create_engine(db_url)
        if 'BROKER_URL' not in config:
            config['BROKER_URL'] = 'sqla+' + db_url
        if 'CELERY_RESULT_BACKEND' not in config and \
                'CELERY_RESULT_DBURI' not in config:
            config['CELERY_RESULT_BACKEND'] = 'database'
            config['CELERY_RESULT_DBURI'] = db_url
    return config['DATABASE_ENGINE']



def get_session() -> Session: