def test_missing_default_raises(self, ini):
        """Missing values without a default raise an MissingSecretError."""
        @environ.config
        class Cfg(object):
            pw = ini.secret()

        with pytest.raises(MissingSecretError):
            environ.to_config(Cfg, {})
    def test_missing(self):
        """If a var is missing, a human-readable MissingEnvValueError is
        raised."""
        @environ.config
        class Mandatory(object):
            x = environ.var()

        with pytest.raises(environ.MissingEnvValueError) as e:
            environ.to_config(Mandatory, environ={"y": "boring"})

        assert ("APP_X", ) == e.value.args
def test_default():
    """
    Class based `from_environ` without `environ` argument.
    """
    cfg = AppConfig.from_environ()

    assert cfg.host == "127.0.0.1"
    assert cfg.port == 5000

    assert environ.to_config(AppConfig) == AppConfig.from_environ()
    assert environ.to_config(ConfigRenamed) == ConfigRenamed.from_env()
def test_env():
    """
    Class based `from_environ`  with explicit `environ` argument.
    """
    env = {"APP_HOST": "0.0.0.0"}
    cfg = AppConfig.from_environ(environ=env)

    assert cfg.host == "0.0.0.0"
    assert cfg.port == 5000

    assert environ.to_config(
        AppConfig, environ=env) == AppConfig.from_environ(environ=env)

    assert environ.to_config(
        ConfigRenamed, environ=env) == ConfigRenamed.from_env(environ=env)
Beispiel #5
0
def get_app(extra_argv=None) -> Application:
    config = environ.to_config(Config)

    app = Application()
    app['config'] = config
    aiojobs.aiohttp.setup(app, limit=1)

    app.cleanup_ctx.extend((s3_ctx, mongo_ctx, keycloak_ctx))

    cors = aiohttp_cors.setup(app)
    resource = cors.add(
        app.router.add_resource("/graphql"), {
            "*":
            aiohttp_cors.ResourceOptions(expose_headers="*",
                                         allow_headers="*",
                                         allow_credentials=True,
                                         allow_methods=["POST", "PUT", "GET"]),
        })
    GraphQLView(schema=schema, graphiql=True, executor=AsyncioExecutor())
    resource.add_route(
        "*",
        GraphQLView(schema=schema, graphiql=True, executor=AsyncioExecutor()))
    app.router.add_get('/upload_callback/{id}',
                       upload_callback,
                       name='upload_callback')

    return app
Beispiel #6
0
    def test_frozen_child(self):
        """
        Frozen child groups are immutable.
        """
        @environ.config
        class Cfg(object):
            @environ.config(frozen=True)
            class Sub(object):
                z = environ.var()

            x = environ.var()
            y = environ.var()
            sub = environ.group(Sub)

        cfg = environ.to_config(Cfg, {
            "APP_X": "foo",
            "APP_Y": "bar",
            "APP_SUB_Z": "baz"
        })

        cfg.x = "next_foo"

        assert cfg.x == "next_foo"

        with pytest.raises(FrozenInstanceError):
            cfg.sub.z = "next_baz"

        assert cfg.sub.z == "baz"
Beispiel #7
0
    def test_ODBC_CONNECT_URL(self):
        with mock.patch.object(BigRaysConfig, 'ODBC_UID', 'foo'), \
                mock.patch.object(BigRaysConfig, 'ODBC_PWD', 'bar'), \
                mock.patch.object(BigRaysConfig, 'ODBC_DSN', 'baz'), \
                mock.patch.object(BigRaysConfig, 'ODBC_FLAVOR', 'itsmysql'), \
                mock.patch.object(BigRaysConfig, 'ODBC_CONNECT_PARAMS', ['ODBC_DSN', 'ODBC_UID', 'ODBC_PWD']), \
                mock.patch('bigrays.config.urllib.parse.quote_plus', lambda x: x):
            expected = 'itsmysql+pyodbc:///?odbc_connect=DSN=baz;UID=foo;PWD=bar'
            actual = BigRaysConfig.ODBC_CONNECT_URL
            self.assertEqual(actual, expected)

        with mock.patch.object(BigRaysConfig, 'ODBC_UID', 'foo'), \
                mock.patch.object(BigRaysConfig, 'ODBC_PWD', 'bar'), \
                mock.patch.object(BigRaysConfig, 'ODBC_SERVER', 'baz'), \
                mock.patch.object(BigRaysConfig, 'ODBC_CONNECT_PARAMS', ['ODBC_UID', 'ODBC_PWD', 'ODBC_SERVER']), \
                mock.patch.object(BigRaysConfig, 'ODBC_FLAVOR', 'itsmysql'), \
                mock.patch('bigrays.config.urllib.parse.quote_plus', lambda x: x):
            expected = 'itsmysql+pyodbc:///?odbc_connect=UID=foo;PWD=bar;SERVER=baz'
            actual = BigRaysConfig.ODBC_CONNECT_URL
            self.assertEqual(actual, expected)

        with mock.patch('bigrays.config.urllib.parse.quote_plus', lambda x: x):
            config = environ.to_config(
                Config, {
                    'BIGRAYS_ODBC_SERVER': 'foo.bar.com',
                    'BIGRAYS_ODBC_UID': 'me',
                    'BIGRAYS_ODBC_CONNECT_PARAMS': 'SERVER,UID',
                    'BIGRAYS_ODBC_FLAVOR': 'oracle'
                })
            actual = config.ODBC_CONNECT_URL
            expected = 'oracle+pyodbc:///?odbc_connect=SERVER=foo.bar.com;UID=me'
            self.assertEqual(actual, expected)
Beispiel #8
0
    def test_nested(self):
        """
        Nested config is extracted, prefix and vault_prefix are propagated.
        """
        env = {"APP_X": "nope", "XYZ_X": "foo", "XYZ_SUB_Y": "bar"}
        cfg = environ.to_config(Nested, environ=env)

        assert Nested(x="foo", sub=Nested.Sub(y="bar")) == cfg
Beispiel #9
0
    def test_optional_group_mixed_children_optional_present(self):
        """
        Optional groups are required if any optional child is present.
        """
        @environ.config(prefix="PARENT")
        class WithOptionalChild(object):
            @environ.config(prefix="CHILD")
            class Child(object):
                grandchild_a = environ.var()
                grandchild_b = environ.var("FOO")

            child = environ.group(Child, optional=True)

        with pytest.raises(environ.MissingEnvValueError) as e:
            environ.to_config(WithOptionalChild,
                              {"PARENT_CHILD_GRANDCHILD_B": "BAR"})
        assert ("PARENT_CHILD_GRANDCHILD_A", ) == e.value.args
    def test_name_overwrite(self, ini):
        """Passsing a specific key name is respected."""
        @environ.config
        class Cfg(object):
            pw = ini.secret(name="password")

        cfg = environ.to_config(Cfg, {})

        assert _SecretStr("foobar") == cfg.pw
Beispiel #11
0
    def test_required_group_required_child_missing(self):
        """
        Groups are required if any of their child elements are.
        """
        @environ.config(prefix="PARENT")
        class WithRequiredChild(object):
            @environ.config(prefix="CHILD")
            class Child(object):
                grandchild = environ.var()

            child = environ.group(Child)

        cfg = environ.to_config(WithRequiredChild,
                                {"PARENT_CHILD_GRANDCHILD": "FOO"})
        assert cfg.child.grandchild == "FOO"
        with pytest.raises(environ.MissingEnvValueError) as e:
            environ.to_config(WithRequiredChild, dict())
        assert ("PARENT_CHILD_GRANDCHILD", ) == e.value.args
    def test_empty(self):
        """Empty config is accepted."""
        @environ.config
        class Empty(object):
            pass

        cfg = environ.to_config(Empty)

        assert "Empty()" == repr(cfg)
Beispiel #13
0
def get_env() -> AppEnv:
    """Get the current environment instance.

    Returns:
        AppConfig:
            The current environment as read in by the :class:`~AppConfig`.
    """

    return environ.to_config(AppEnv, environ=os.environ)
    def test_default(self, ini):
        """Defaults are used iff the key is missing."""
        @environ.config
        class Cfg(object):
            password = ini.secret(default="not used")
            secret = ini.secret(default="used!")

        cfg = environ.to_config(Cfg, {})

        assert Cfg("foobar", "used!") == cfg
    def test_returns_secret_str(self, vault):
        """The returned strings are `_SecretStr`."""
        @environ.config
        class Cfg(object):
            x = vault.secret()

        cfg = environ.to_config(Cfg, {"SECRET_X": "foo"})

        assert isinstance(cfg.x, _SecretStr)
        assert "foo" == cfg.x
Beispiel #16
0
async def amain() -> int:
    config: Config = environ.to_config(Config)

    logging.basicConfig(level={
        0: logging.ERROR,
        1: logging.WARNING,
        2: logging.INFO,
    }.get(config.lib_log_level, logging.DEBUG), )
    logging.getLogger("authbot").setLevel({
        0: logging.ERROR,
        1: logging.WARNING,
        2: logging.INFO,
    }.get(config.log_level, logging.DEBUG))

    client = aioxmpp.PresenceManagedClient(
        config.address,
        aioxmpp.make_security_layer(config.password, ),
    )

    client.summon(aioxmpp.MUCClient)
    client.summon(aioxmpp.DiscoClient)

    stop_event = asyncio.Event()
    loop = asyncio.get_event_loop()
    loop.add_signal_handler(signal.SIGINT, stop_event.set)
    loop.add_signal_handler(signal.SIGTERM, stop_event.set)

    stop_future = asyncio.create_task(stop_event.wait())

    async with client.connected() as stream:
        logger.info("connected as %s", stream.local_jid)

        bot_task = asyncio.create_task(
            bot.run_in_room(
                client,
                config.room_address,
                config.room_nickname,
            ))

        done, pending = await asyncio.wait(
            [bot_task, stop_future],
            return_when=asyncio.FIRST_COMPLETED,
        )

        for fut in pending:
            fut.cancel()

        for fut in done:
            fut.result()

        for fut in pending:
            try:
                await fut
            except asyncio.CancelledError:
                pass
Beispiel #17
0
    def test_no_prefix(self, prefix):
        """
        If prefix is None or "", don't add a leading _ when adding namespaces.
        """
        @environ.config(prefix=prefix)
        class Cfg(object):
            x = environ.var()

        cfg = environ.to_config(Cfg, environ={"X": "foo"})

        assert Cfg("foo") == cfg
    def test_from_path_in_env_delayed(self, ini_file):
        """`from_path_in_env` prepares for loading but doesn't load until
        `to_config` runs."""
        secret = INISecrets.from_path_in_env("APP_SECRETS_INI").secret

        @environ.config
        class Cfg(object):
            password = secret()

        cfg = environ.to_config(Cfg, {"APP_SECRETS_INI": str(ini_file)})

        assert "foobar" == cfg.password
Beispiel #19
0
    def test_flat(self):
        """
        Flat config is extracted.
        """
        @environ.config(prefix="APP")
        class Flat(object):
            x = environ.var()
            y = environ.var()

        cfg = environ.to_config(Flat, environ={"APP_X": "foo", "APP_Y": "bar"})

        assert Flat(x="foo", y="bar") == cfg
Beispiel #20
0
    def test_default(self):
        """
        Default values are used iff the vars are missing.
        """
        @environ.config
        class Defaults(object):
            x = environ.var("foo")
            y = environ.var("qux")

        cfg = environ.to_config(Defaults, environ={"APP_Y": "bar"})

        assert Defaults(x="foo", y="bar") == cfg
    def test_overwrite_sections(self, ini):
        """The source section can be overwritten."""
        ini.section = "yet_another_section"

        @environ.config
        class Cfg(object):
            password = ini.secret(section="other_secrets")
            secret = ini.secret()

        cfg = environ.to_config(Cfg, {})

        assert _SecretStr("bar%foo") == cfg.password
Beispiel #22
0
    def test_tolerates_attribs(self):
        """
        Classes are allowed to have plain attr.ibs for e.g.
        __attrs_post_init__.
        """
        @environ.config
        class Cfg(object):
            e = environ.var()
            x = attr.ib(default=42)

        cfg = environ.to_config(Cfg, environ={"APP_E": "e"})

        assert Cfg("e", 42) == cfg
Beispiel #23
0
    def test_factory_default(self):
        """
        If the default value is an ``attr.Factory``,
        it used to generate the default value.
        """
        @environ.config
        class Defaults(object):
            x = environ.var(attr.Factory(list))
            y = environ.var(attr.Factory(list))

        cfg = environ.to_config(Defaults, environ={"APP_Y": "bar"})

        assert Defaults(x=[], y="bar") == cfg
    def test_nested(self, ini):
        """Prefix building works."""
        @environ.config
        class Cfg(object):
            @environ.config
            class DB(object):
                password = ini.secret()

            db = environ.group(DB)

        cfg = environ.to_config(Cfg, {})

        assert _SecretStr("nested!") == cfg.db.password
Beispiel #25
0
    def test_optional_group_required_child_missing(self):
        """
        Optional groups are set to `None` if a required child is missing.
        """
        @environ.config(prefix="PARENT")
        class WithOptionalChild(object):
            @environ.config(prefix="CHILD")
            class Child(object):
                grandchild = environ.var()

            child = environ.group(Child, optional=True)

        cfg = environ.to_config(WithOptionalChild, dict())
        assert cfg.child is None
Beispiel #26
0
    def test_optional_group_optional_child_missing(self):
        """
        Optional groups with an optional child is fully structured.
        """
        @environ.config(prefix="PARENT")
        class WithOptionalChild(object):
            @environ.config(prefix="CHILD")
            class Child(object):
                grandchild = environ.var("FOO")

            child = environ.group(Child, optional=True)

        cfg = environ.to_config(WithOptionalChild, dict())
        assert cfg.child.grandchild == "FOO"
Beispiel #27
0
    def test_overwrite_name(self, vault):
        """
        The variable name can be overwritten.
        """
        @environ.config
        class Cfg(object):
            password = vault.secret(name="not_password")

        cfg = environ.to_config(Cfg, {
            "SECRET_PASSWORD": "******",
            "not_password": "******"
        })

        assert "correct" == cfg.password
Beispiel #28
0
    def test_required_group_optional_child_missing(self):
        """
        Required groups are fully structured if the only child is optional.
        """
        @environ.config(prefix="PARENT")
        class WithRequiredChild(object):
            @environ.config(prefix="CHILD")
            class Child(object):
                grandchild = environ.var("FOO")

            child = environ.group(Child)

        cfg = environ.to_config(WithRequiredChild, dict())
        assert cfg.child.grandchild == "FOO"
Beispiel #29
0
    def test_frozen(self):
        """
        Frozen configurations are immutable.
        """
        @environ.config(frozen=True)
        class Cfg(object):
            x = environ.var()
            y = environ.var()

        cfg = environ.to_config(Cfg, {"APP_X": "foo", "APP_Y": "bar"})

        with pytest.raises(FrozenInstanceError):
            cfg.x = "next_foo"

        assert cfg.x == "foo"
Beispiel #30
0
    def test_default_factory(self, ini):
        """
        Defaults are used iff the key is missing.
        """
        def getpass():
            return "thesecret"

        @environ.config
        class Cfg(object):
            password = ini.secret(default=attr.Factory(getpass))
            secret = ini.secret(default=attr.Factory(getpass))

        cfg = environ.to_config(Cfg, {})

        assert Cfg("foobar", "thesecret") == cfg