We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
uvicorn 0.2 not compatible with django channels
daphe server for a project(avilpage) can be started with

```
daphne avilpage.asgi:application                                         
```

uvicorn fails with 

```
->uvicorn avilpage.asgi:application
Usage: uvicorn [OPTIONS] APP

Error: Error loading ASGI app. Could not import module "avilpage.asgi".
```

eventhough 

```
python -c 'import avilpage.asgi'                     
```
works fine without any errors.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `uvicorn/main.py`
Content:
```
1 from uvicorn.protocols.http import H11Protocol, HttpToolsProtocol
2 
3 import asyncio
4 import click
5 import importlib
6 import signal
7 import os
8 import logging
9 import sys
10 
11 
12 LOOP_CHOICES = click.Choice(["uvloop", "asyncio"])
13 LEVEL_CHOICES = click.Choice(["debug", "info", "warning", "error", "critical"])
14 HTTP_CHOICES = click.Choice(["httptools", "h11"])
15 LOG_LEVELS = {
16     "critical": logging.CRITICAL,
17     "error": logging.ERROR,
18     "warning": logging.WARNING,
19     "info": logging.INFO,
20     "debug": logging.DEBUG,
21 }
22 HTTP_PROTOCOLS = {"h11": H11Protocol, "httptools": HttpToolsProtocol}
23 
24 
25 @click.command()
26 @click.argument("app")
27 @click.option("--host", type=str, default="127.0.0.1", help="Host")
28 @click.option("--port", type=int, default=8000, help="Port")
29 @click.option("--loop", type=LOOP_CHOICES, default="uvloop", help="Event loop")
30 @click.option("--http", type=HTTP_CHOICES, default="httptools", help="HTTP Handler")
31 @click.option("--workers", type=int, default=1, help="Number of worker processes")
32 @click.option("--log-level", type=LEVEL_CHOICES, default="info", help="Log level")
33 def main(app, host: str, port: int, loop: str, http: str, workers: int, log_level: str):
34     log_level = LOG_LEVELS[log_level]
35     logging.basicConfig(format="%(levelname)s: %(message)s", level=log_level)
36 
37     app = load_app(app)
38     loop = get_event_loop(loop)
39     logger = logging.getLogger()
40     protocol_class = HTTP_PROTOCOLS[http]
41 
42     if workers != 1:
43         raise click.UsageError(
44             'Not yet available. For multiple worker processes, use gunicorn. '
45             'eg. "gunicorn -w 4 -k uvicorn.workers.UvicornWorker".'
46         )
47 
48     server = Server(app, host, port, loop, logger, protocol_class)
49     server.run()
50 
51 
52 def run(app, host="127.0.0.1", port=8000, log_level="info"):
53     log_level = LOG_LEVELS[log_level]
54     logging.basicConfig(format="%(levelname)s: %(message)s", level=log_level)
55 
56     loop = get_event_loop("uvloop")
57     logger = logging.getLogger()
58     protocol_class = HttpToolsProtocol
59 
60     server = Server(app, host, port, loop, logger, protocol_class)
61     server.run()
62 
63 
64 def load_app(app):
65     if not isinstance(app, str):
66         return app
67 
68     if ":" not in app:
69         message = 'Invalid app string "{app}". Must be in format "<module>:<app>".'
70         raise click.UsageError(message.format(app=app))
71 
72     module_str, _, attr = app.partition(":")
73     try:
74         module = importlib.import_module(module_str)
75     except ModuleNotFoundError:
76         message = 'Error loading ASGI app. Could not import module "{module_str}".'
77         raise click.UsageError(message.format(module_str=module_str))
78 
79     try:
80         return getattr(module, attr)
81     except AttributeError:
82         message = 'Error loading ASGI app. No attribute "{attr}" found in module "{module_str}".'
83         raise click.UsageError(message.format(attr=attr, module_str=module_str))
84 
85 
86 def get_event_loop(loop):
87     if loop == "uvloop":
88         import uvloop
89 
90         asyncio.get_event_loop().close()
91         asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
92     return asyncio.get_event_loop()
93 
94 
95 class Server:
96     def __init__(
97         self,
98         app,
99         host="127.0.0.1",
100         port=8000,
101         loop=None,
102         logger=None,
103         protocol_class=None,
104     ):
105         self.app = app
106         self.host = host
107         self.port = port
108         self.loop = loop or asyncio.get_event_loop()
109         self.logger = logger or logging.getLogger()
110         self.server = None
111         self.should_exit = False
112         self.pid = os.getpid()
113         self.protocol_class = protocol_class
114 
115     def set_signal_handlers(self):
116         handled = (signal.SIGQUIT, signal.SIGTERM, signal.SIGINT, signal.SIGABRT)
117         for sig in handled:
118             self.loop.add_signal_handler(sig, self.handle_exit, sig, None)
119 
120     def run(self):
121         self.set_signal_handlers()
122         self.loop.run_until_complete(self.create_server())
123         if self.server is not None:
124             message = "* Uvicorn running on http://%s:%d 🦄 (Press CTRL+C to quit)"
125             click.echo(message % (self.host, self.port))
126             self.logger.info("Started worker [{}]".format(self.pid))
127             self.loop.create_task(self.tick())
128             self.loop.run_forever()
129 
130     def handle_exit(self, sig, frame):
131         self.logger.warning("Received signal {}. Shutting down.".format(sig.name))
132         self.should_exit = True
133 
134     def create_protocol(self):
135         try:
136             return self.protocol_class(app=self.app, loop=self.loop, logger=self.logger)
137         except Exception as exc:
138             self.logger.error(exc)
139             self.should_exit = True
140 
141     async def create_server(self):
142         try:
143             self.server = await self.loop.create_server(
144                 self.create_protocol, host=self.host, port=self.port
145             )
146         except Exception as exc:
147             self.logger.error(exc)
148 
149     async def tick(self):
150         while not self.should_exit:
151             self.protocol_class.tick()
152             await asyncio.sleep(1)
153 
154         self.logger.info("Stopping worker [{}]".format(self.pid))
155         self.server.close()
156         await self.server.wait_closed()
157         self.loop.stop()
158 
159 
160 if __name__ == "__main__":
161     main()
162
```

Path: `uvicorn/__init__.py`
Content:
```
1 from uvicorn.main import main, run
2 
3 __version__ = "0.2.3"
4 __all__ = ["main", "run"]
5
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/uvicorn/__init__.py b/uvicorn/__init__.py
--- a/uvicorn/__init__.py
+++ b/uvicorn/__init__.py
@@ -1,4 +1,4 @@
 from uvicorn.main import main, run
 
-__version__ = "0.2.3"
+__version__ = "0.2.4"
 __all__ = ["main", "run"]
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -34,6 +34,7 @@
     log_level = LOG_LEVELS[log_level]
     logging.basicConfig(format="%(levelname)s: %(message)s", level=log_level)
 
+    sys.path.insert(0, ".")
     app = load_app(app)
     loop = get_event_loop(loop)
     logger = logging.getLogger()
@@ -69,7 +70,7 @@
         message = 'Invalid app string "{app}". Must be in format "<module>:<app>".'
         raise click.UsageError(message.format(app=app))
 
-    module_str, _, attr = app.partition(":")
+    module_str, attrs = app.split(":", 1)
     try:
         module = importlib.import_module(module_str)
     except ModuleNotFoundError:
@@ -77,10 +78,13 @@
         raise click.UsageError(message.format(module_str=module_str))
 
     try:
-        return getattr(module, attr)
+        for attr in attrs.split('.'):
+            asgi_app = getattr(module, attr)
     except AttributeError:
-        message = 'Error loading ASGI app. No attribute "{attr}" found in module "{module_str}".'
-        raise click.UsageError(message.format(attr=attr, module_str=module_str))
+        message = 'Error loading ASGI app. No app "{attrs}" found in module "{module_str}".'
+        raise click.UsageError(message.format(attrs=attrs, module_str=module_str))
+
+    return asgi_app
 
 
 def get_event_loop(loop):

{"golden_diff": "diff --git a/uvicorn/__init__.py b/uvicorn/__init__.py\n--- a/uvicorn/__init__.py\n+++ b/uvicorn/__init__.py\n@@ -1,4 +1,4 @@\n from uvicorn.main import main, run\n \n-__version__ = \"0.2.3\"\n+__version__ = \"0.2.4\"\n __all__ = [\"main\", \"run\"]\ndiff --git a/uvicorn/main.py b/uvicorn/main.py\n--- a/uvicorn/main.py\n+++ b/uvicorn/main.py\n@@ -34,6 +34,7 @@\n     log_level = LOG_LEVELS[log_level]\n     logging.basicConfig(format=\"%(levelname)s: %(message)s\", level=log_level)\n \n+    sys.path.insert(0, \".\")\n     app = load_app(app)\n     loop = get_event_loop(loop)\n     logger = logging.getLogger()\n@@ -69,7 +70,7 @@\n         message = 'Invalid app string \"{app}\". Must be in format \"<module>:<app>\".'\n         raise click.UsageError(message.format(app=app))\n \n-    module_str, _, attr = app.partition(\":\")\n+    module_str, attrs = app.split(\":\", 1)\n     try:\n         module = importlib.import_module(module_str)\n     except ModuleNotFoundError:\n@@ -77,10 +78,13 @@\n         raise click.UsageError(message.format(module_str=module_str))\n \n     try:\n-        return getattr(module, attr)\n+        for attr in attrs.split('.'):\n+            asgi_app = getattr(module, attr)\n     except AttributeError:\n-        message = 'Error loading ASGI app. No attribute \"{attr}\" found in module \"{module_str}\".'\n-        raise click.UsageError(message.format(attr=attr, module_str=module_str))\n+        message = 'Error loading ASGI app. No app \"{attrs}\" found in module \"{module_str}\".'\n+        raise click.UsageError(message.format(attrs=attrs, module_str=module_str))\n+\n+    return asgi_app\n \n \n def get_event_loop(loop):\n", "issue": "uvicorn 0.2 not compatible with django channels\ndaphe server for a project(avilpage) can be started with\r\n\r\n```\r\ndaphne avilpage.asgi:application                                         \r\n```\r\n\r\nuvicorn fails with \r\n\r\n```\r\n->uvicorn avilpage.asgi:application\r\nUsage: uvicorn [OPTIONS] APP\r\n\r\nError: Error loading ASGI app. Could not import module \"avilpage.asgi\".\r\n```\r\n\r\neventhough \r\n\r\n```\r\npython -c 'import avilpage.asgi'                     \r\n```\r\nworks fine without any errors.\r\n\n", "before_files": [{"content": "from uvicorn.protocols.http import H11Protocol, HttpToolsProtocol\n\nimport asyncio\nimport click\nimport importlib\nimport signal\nimport os\nimport logging\nimport sys\n\n\nLOOP_CHOICES = click.Choice([\"uvloop\", \"asyncio\"])\nLEVEL_CHOICES = click.Choice([\"debug\", \"info\", \"warning\", \"error\", \"critical\"])\nHTTP_CHOICES = click.Choice([\"httptools\", \"h11\"])\nLOG_LEVELS = {\n    \"critical\": logging.CRITICAL,\n    \"error\": logging.ERROR,\n    \"warning\": logging.WARNING,\n    \"info\": logging.INFO,\n    \"debug\": logging.DEBUG,\n}\nHTTP_PROTOCOLS = {\"h11\": H11Protocol, \"httptools\": HttpToolsProtocol}\n\n\n@click.command()\n@click.argument(\"app\")\n@click.option(\"--host\", type=str, default=\"127.0.0.1\", help=\"Host\")\n@click.option(\"--port\", type=int, default=8000, help=\"Port\")\n@click.option(\"--loop\", type=LOOP_CHOICES, default=\"uvloop\", help=\"Event loop\")\n@click.option(\"--http\", type=HTTP_CHOICES, default=\"httptools\", help=\"HTTP Handler\")\n@click.option(\"--workers\", type=int, default=1, help=\"Number of worker processes\")\n@click.option(\"--log-level\", type=LEVEL_CHOICES, default=\"info\", help=\"Log level\")\ndef main(app, host: str, port: int, loop: str, http: str, workers: int, log_level: str):\n    log_level = LOG_LEVELS[log_level]\n    logging.basicConfig(format=\"%(levelname)s: %(message)s\", level=log_level)\n\n    app = load_app(app)\n    loop = get_event_loop(loop)\n    logger = logging.getLogger()\n    protocol_class = HTTP_PROTOCOLS[http]\n\n    if workers != 1:\n        raise click.UsageError(\n            'Not yet available. For multiple worker processes, use gunicorn. '\n            'eg. \"gunicorn -w 4 -k uvicorn.workers.UvicornWorker\".'\n        )\n\n    server = Server(app, host, port, loop, logger, protocol_class)\n    server.run()\n\n\ndef run(app, host=\"127.0.0.1\", port=8000, log_level=\"info\"):\n    log_level = LOG_LEVELS[log_level]\n    logging.basicConfig(format=\"%(levelname)s: %(message)s\", level=log_level)\n\n    loop = get_event_loop(\"uvloop\")\n    logger = logging.getLogger()\n    protocol_class = HttpToolsProtocol\n\n    server = Server(app, host, port, loop, logger, protocol_class)\n    server.run()\n\n\ndef load_app(app):\n    if not isinstance(app, str):\n        return app\n\n    if \":\" not in app:\n        message = 'Invalid app string \"{app}\". Must be in format \"<module>:<app>\".'\n        raise click.UsageError(message.format(app=app))\n\n    module_str, _, attr = app.partition(\":\")\n    try:\n        module = importlib.import_module(module_str)\n    except ModuleNotFoundError:\n        message = 'Error loading ASGI app. Could not import module \"{module_str}\".'\n        raise click.UsageError(message.format(module_str=module_str))\n\n    try:\n        return getattr(module, attr)\n    except AttributeError:\n        message = 'Error loading ASGI app. No attribute \"{attr}\" found in module \"{module_str}\".'\n        raise click.UsageError(message.format(attr=attr, module_str=module_str))\n\n\ndef get_event_loop(loop):\n    if loop == \"uvloop\":\n        import uvloop\n\n        asyncio.get_event_loop().close()\n        asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n    return asyncio.get_event_loop()\n\n\nclass Server:\n    def __init__(\n        self,\n        app,\n        host=\"127.0.0.1\",\n        port=8000,\n        loop=None,\n        logger=None,\n        protocol_class=None,\n    ):\n        self.app = app\n        self.host = host\n        self.port = port\n        self.loop = loop or asyncio.get_event_loop()\n        self.logger = logger or logging.getLogger()\n        self.server = None\n        self.should_exit = False\n        self.pid = os.getpid()\n        self.protocol_class = protocol_class\n\n    def set_signal_handlers(self):\n        handled = (signal.SIGQUIT, signal.SIGTERM, signal.SIGINT, signal.SIGABRT)\n        for sig in handled:\n            self.loop.add_signal_handler(sig, self.handle_exit, sig, None)\n\n    def run(self):\n        self.set_signal_handlers()\n        self.loop.run_until_complete(self.create_server())\n        if self.server is not None:\n            message = \"* Uvicorn running on http://%s:%d \ud83e\udd84 (Press CTRL+C to quit)\"\n            click.echo(message % (self.host, self.port))\n            self.logger.info(\"Started worker [{}]\".format(self.pid))\n            self.loop.create_task(self.tick())\n            self.loop.run_forever()\n\n    def handle_exit(self, sig, frame):\n        self.logger.warning(\"Received signal {}. Shutting down.\".format(sig.name))\n        self.should_exit = True\n\n    def create_protocol(self):\n        try:\n            return self.protocol_class(app=self.app, loop=self.loop, logger=self.logger)\n        except Exception as exc:\n            self.logger.error(exc)\n            self.should_exit = True\n\n    async def create_server(self):\n        try:\n            self.server = await self.loop.create_server(\n                self.create_protocol, host=self.host, port=self.port\n            )\n        except Exception as exc:\n            self.logger.error(exc)\n\n    async def tick(self):\n        while not self.should_exit:\n            self.protocol_class.tick()\n            await asyncio.sleep(1)\n\n        self.logger.info(\"Stopping worker [{}]\".format(self.pid))\n        self.server.close()\n        await self.server.wait_closed()\n        self.loop.stop()\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "uvicorn/main.py"}, {"content": "from uvicorn.main import main, run\n\n__version__ = \"0.2.3\"\n__all__ = [\"main\", \"run\"]\n", "path": "uvicorn/__init__.py"}], "after_files": [{"content": "from uvicorn.protocols.http import H11Protocol, HttpToolsProtocol\n\nimport asyncio\nimport click\nimport importlib\nimport signal\nimport os\nimport logging\nimport sys\n\n\nLOOP_CHOICES = click.Choice([\"uvloop\", \"asyncio\"])\nLEVEL_CHOICES = click.Choice([\"debug\", \"info\", \"warning\", \"error\", \"critical\"])\nHTTP_CHOICES = click.Choice([\"httptools\", \"h11\"])\nLOG_LEVELS = {\n    \"critical\": logging.CRITICAL,\n    \"error\": logging.ERROR,\n    \"warning\": logging.WARNING,\n    \"info\": logging.INFO,\n    \"debug\": logging.DEBUG,\n}\nHTTP_PROTOCOLS = {\"h11\": H11Protocol, \"httptools\": HttpToolsProtocol}\n\n\n@click.command()\n@click.argument(\"app\")\n@click.option(\"--host\", type=str, default=\"127.0.0.1\", help=\"Host\")\n@click.option(\"--port\", type=int, default=8000, help=\"Port\")\n@click.option(\"--loop\", type=LOOP_CHOICES, default=\"uvloop\", help=\"Event loop\")\n@click.option(\"--http\", type=HTTP_CHOICES, default=\"httptools\", help=\"HTTP Handler\")\n@click.option(\"--workers\", type=int, default=1, help=\"Number of worker processes\")\n@click.option(\"--log-level\", type=LEVEL_CHOICES, default=\"info\", help=\"Log level\")\ndef main(app, host: str, port: int, loop: str, http: str, workers: int, log_level: str):\n    log_level = LOG_LEVELS[log_level]\n    logging.basicConfig(format=\"%(levelname)s: %(message)s\", level=log_level)\n\n    sys.path.insert(0, \".\")\n    app = load_app(app)\n    loop = get_event_loop(loop)\n    logger = logging.getLogger()\n    protocol_class = HTTP_PROTOCOLS[http]\n\n    if workers != 1:\n        raise click.UsageError(\n            'Not yet available. For multiple worker processes, use gunicorn. '\n            'eg. \"gunicorn -w 4 -k uvicorn.workers.UvicornWorker\".'\n        )\n\n    server = Server(app, host, port, loop, logger, protocol_class)\n    server.run()\n\n\ndef run(app, host=\"127.0.0.1\", port=8000, log_level=\"info\"):\n    log_level = LOG_LEVELS[log_level]\n    logging.basicConfig(format=\"%(levelname)s: %(message)s\", level=log_level)\n\n    loop = get_event_loop(\"uvloop\")\n    logger = logging.getLogger()\n    protocol_class = HttpToolsProtocol\n\n    server = Server(app, host, port, loop, logger, protocol_class)\n    server.run()\n\n\ndef load_app(app):\n    if not isinstance(app, str):\n        return app\n\n    if \":\" not in app:\n        message = 'Invalid app string \"{app}\". Must be in format \"<module>:<app>\".'\n        raise click.UsageError(message.format(app=app))\n\n    module_str, attrs = app.split(\":\", 1)\n    try:\n        module = importlib.import_module(module_str)\n    except ModuleNotFoundError:\n        message = 'Error loading ASGI app. Could not import module \"{module_str}\".'\n        raise click.UsageError(message.format(module_str=module_str))\n\n    try:\n        for attr in attrs.split('.'):\n            asgi_app = getattr(module, attr)\n    except AttributeError:\n        message = 'Error loading ASGI app. No app \"{attrs}\" found in module \"{module_str}\".'\n        raise click.UsageError(message.format(attrs=attrs, module_str=module_str))\n\n    return asgi_app\n\n\ndef get_event_loop(loop):\n    if loop == \"uvloop\":\n        import uvloop\n\n        asyncio.get_event_loop().close()\n        asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n    return asyncio.get_event_loop()\n\n\nclass Server:\n    def __init__(\n        self,\n        app,\n        host=\"127.0.0.1\",\n        port=8000,\n        loop=None,\n        logger=None,\n        protocol_class=None,\n    ):\n        self.app = app\n        self.host = host\n        self.port = port\n        self.loop = loop or asyncio.get_event_loop()\n        self.logger = logger or logging.getLogger()\n        self.server = None\n        self.should_exit = False\n        self.pid = os.getpid()\n        self.protocol_class = protocol_class\n\n    def set_signal_handlers(self):\n        handled = (signal.SIGQUIT, signal.SIGTERM, signal.SIGINT, signal.SIGABRT)\n        for sig in handled:\n            self.loop.add_signal_handler(sig, self.handle_exit, sig, None)\n\n    def run(self):\n        self.set_signal_handlers()\n        self.loop.run_until_complete(self.create_server())\n        if self.server is not None:\n            message = \"* Uvicorn running on http://%s:%d \ud83e\udd84 (Press CTRL+C to quit)\"\n            click.echo(message % (self.host, self.port))\n            self.logger.info(\"Started worker [{}]\".format(self.pid))\n            self.loop.create_task(self.tick())\n            self.loop.run_forever()\n\n    def handle_exit(self, sig, frame):\n        self.logger.warning(\"Received signal {}. Shutting down.\".format(sig.name))\n        self.should_exit = True\n\n    def create_protocol(self):\n        try:\n            return self.protocol_class(app=self.app, loop=self.loop, logger=self.logger)\n        except Exception as exc:\n            self.logger.error(exc)\n            self.should_exit = True\n\n    async def create_server(self):\n        try:\n            self.server = await self.loop.create_server(\n                self.create_protocol, host=self.host, port=self.port\n            )\n        except Exception as exc:\n            self.logger.error(exc)\n\n    async def tick(self):\n        while not self.should_exit:\n            self.protocol_class.tick()\n            await asyncio.sleep(1)\n\n        self.logger.info(\"Stopping worker [{}]\".format(self.pid))\n        self.server.close()\n        await self.server.wait_closed()\n        self.loop.stop()\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "uvicorn/main.py"}, {"content": "from uvicorn.main import main, run\n\n__version__ = \"0.2.4\"\n__all__ = [\"main\", \"run\"]\n", "path": "uvicorn/__init__.py"}]}