# Buggy code
async def train_rasanlu(config, skills):
    """Train a Rasa NLU model based on the loaded skills."""
    _LOGGER.info(_("Starting Rasa NLU training."))
    intents = await _get_all_intents(skills)
    if intents is None:
        _LOGGER.warning(_("No intents found, skipping training."))
        return False

    config["model"] = await _get_intents_fingerprint(intents)
    if config["model"] in await _get_existing_models(config):
        _LOGGER.info(_("This model already exists, skipping training..."))
        await _init_model(config)
        return True

    async with aiohttp.ClientSession() as session:
        _LOGGER.info(_("Now training the model. This may take a while..."))

        url = await _build_training_url(config)

        try:
            training_start = arrow.now()
            resp = await session.post(url, data=intents)
        except aiohttp.client_exceptions.ClientConnectorError:
            _LOGGER.error(_("Unable to connect to Rasa NLU, training failed."))
            return False

        if resp.status == 200:
            result = await resp.json()
            if "info" in result and "new model trained" in result["info"]:
                time_taken = (arrow.now() - training_start).total_seconds()
                _LOGGER.info(
                    _("Rasa NLU training completed in %s seconds."), int(time_taken)
                )
                await _init_model(config)
                return True

            _LOGGER.debug(result)

        _LOGGER.error(_("Bad Rasa NLU response - %s"), await resp.text())
        _LOGGER.error(_("Rasa NLU training failed."))
        return False


# Traceback (AttributeError)
INFO opsdroid.parsers.rasanlu: Starting Rasa NLU training.
DEBUG asyncio: Using selector: KqueueSelector
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/__main__.py", line 206, in <module>
init()
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/__main__.py", line 203, in init
main()
File "/Users/IOBreaker/Developments/Bots/opsdroid/venv/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/Users/IOBreaker/Developments/Bots/opsdroid/venv/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/Users/IOBreaker/Developments/Bots/opsdroid/venv/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/IOBreaker/Developments/Bots/opsdroid/venv/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/__main__.py", line 196, in main
opsdroid.load()
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/core.py", line 152, in load
self.train_parsers(self.modules["skills"])
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/core.py", line 270, in train_parsers
asyncio.gather(*tasks, loop=self.eventloop))
File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 568, in run_until_complete
return future.result()
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/parsers/rasanlu.py", line 87, in train_rasanlu
intents = await _get_all_intents(skills)
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/parsers/rasanlu.py", line 19, in _get_all_intents
matchers = [matcher for skill in skills for matcher in skill.matchers]
File "/Users/IOBreaker/Developments/Bots/opsdroid/opsdroid/parsers/rasanlu.py", line 19, in <listcomp>
matchers = [matcher for skill in skills for matcher in skill.matchers]
AttributeError: 'dict' object has no attribute 'matchers'

# Fixed code
async def train_rasanlu(config, skills):
    """Train a Rasa NLU model based on the loaded skills."""
    _LOGGER.info(_("Starting Rasa NLU training."))
    intents = await _get_all_intents(skills)
    if intents is None:
        _LOGGER.warning(_("No intents found, skipping training."))
        return False

    config["model"] = await _get_intents_fingerprint(intents)
    if config["model"] in await _get_existing_models(config):
        _LOGGER.info(_("This model already exists, skipping training..."))
        await _init_model(config)
        return True

    async with aiohttp.ClientSession() as session:
        _LOGGER.info(_("Now training the model. This may take a while..."))

        url = await _build_training_url(config)

        # https://github.com/RasaHQ/rasa_nlu/blob/master/docs/http.rst#post-train
        # Note : The request should always be sent as
        # application/x-yml regardless of wether you use
        # json or md for the data format. Do not send json as
        # application/json for example.+
        headers = {"content-type": "application/x-yml"}

        try:
            training_start = arrow.now()
            resp = await session.post(url, data=intents, headers=headers)
        except aiohttp.client_exceptions.ClientConnectorError:
            _LOGGER.error(_("Unable to connect to Rasa NLU, training failed."))
            return False

        if resp.status == 200:
            result = await resp.json()
            if "info" in result and "new model trained" in result["info"]:
                time_taken = (arrow.now() - training_start).total_seconds()
                _LOGGER.info(
                    _("Rasa NLU training completed in %s seconds."), int(time_taken)
                )
                await _init_model(config)
                return True

            _LOGGER.debug(result)

        _LOGGER.error(_("Bad Rasa NLU response - %s"), await resp.text())
        _LOGGER.error(_("Rasa NLU training failed."))
        return False