When I use aiohttp.web.run_app(. . ., port=0)
, I assume that it selects an arbitrary available port on which to serve. Is this correct? And if so, is there some way to figure out what port it's selected?
Asked
Active
Viewed 2,076 times
11

abingham
- 1,294
- 1
- 10
- 17
-
yes that assumption is correct – Corey Goldberg Jun 18 '17 at 00:38
-
If it works something like `flask`, It will chose a random port.... Starting flask with port 0 will choose random high port number. – Yuval Pruss Jun 18 '17 at 07:42
-
Right, but how do I know which? Is there an attribute on the app or loop? – abingham Jun 18 '17 at 07:49
-
1No way. But why do you need it? Starting server on random port isn't look very useful – Andrew Svetlov Jun 18 '17 at 09:42
-
1It's a refactoring server used by e.g. emacs. Users don't (and shouldn't normally) care which port it uses, but emacs needs to know how to talk to it after it starts. The current bottle-based version is able to print the port it chooses to stdout, and emacs parses that. I need something similar for aiohttp. – abingham Jun 18 '17 at 10:30
2 Answers
6
You use server.sockets
as in the following code:
@asyncio.coroutine
def status(request):
"""Check that the app is properly working"""
return web.json_response('OK')
app = web.Application() # pylint: disable=invalid-name
app.router.add_get('/api/status', status)
def main():
"""Starts the aiohttp process to serve the REST API"""
loop = asyncio.get_event_loop()
# continue server bootstraping
handler = app.make_handler()
coroutine = loop.create_server(handler, '0.0.0.0', 0)
server = loop.run_until_complete(coroutine)
print('Serving on http://%s:%s' % server.sockets[0].getsockname()) # HERE!
try:
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
server.close()
loop.run_until_complete(server.wait_closed())
loop.run_until_complete(handler.finish_connections(1.0))
loop.close()

amirouche
- 7,682
- 6
- 40
- 94
-
2make_handler() is now deprecated. Can someone suggest an alternative recipe? https://docs.aiohttp.org/en/stable/web_reference.html#aiohttp.web.Application.make_handler – Jason Jul 05 '21 at 13:58
-
1
When using application runners, you can pass in port 0 and access the selected port via the site object:
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, 'localhost', 0)
await site.start()
print('Serving on http://%s:%s' % site._server.sockets[0].getsockname())

Albert Peschar
- 521
- 3
- 4