From 59187a919683d933f88e925bdfb8211aabb51cb2 Mon Sep 17 00:00:00 2001 From: Arik Mitschang Date: Fri, 16 Sep 2022 10:41:34 -0400 Subject: [PATCH] Bug fixes: listen at base path for ping, use relative path for redirect And adding some more friendly responses in cases where no data path is given, data file is not found and when the loading times out (which is also increased). --- compat/cellxgene/nginx.conf | 6 +++ compat/cellxgene/starter.py | 94 +++++++++++++++++++++---------------- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/compat/cellxgene/nginx.conf b/compat/cellxgene/nginx.conf index d88a0b7..b3f9180 100644 --- a/compat/cellxgene/nginx.conf +++ b/compat/cellxgene/nginx.conf @@ -3,6 +3,12 @@ events {} http { server { listen 0.0.0.0:8888; + location <> { + proxy_pass http://127.0.0.1:8080/; + } + location <>/ { + proxy_pass http://127.0.0.1:8080/; + } location ~ ^<>/d/(.*) { proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080/d/$1; diff --git a/compat/cellxgene/starter.py b/compat/cellxgene/starter.py index c1fc23c..32a957e 100644 --- a/compat/cellxgene/starter.py +++ b/compat/cellxgene/starter.py @@ -9,7 +9,16 @@ app = FastAPI() port_maps = {'': {'port': 9000, 'proc': 0}} -timeout = 10 +timeout = 20 + +def html_msg(msg): + return f''' +
+
{msg}
+
+ ''' def get_annotations_file(): persistent = glob.glob('/home/idies/workspace/Storage/*/persistent') @@ -20,46 +29,43 @@ def get_annotations_file(): return f"{annotations_dir}/sciserver-cellxgene-annotations" def get_base_url(request): - root = request.scope.get('root_path', '') - proto = request.headers.get('X-Forwarded-Proto', request.url.scheme) - port = request.headers.get('X-Forwarded-Port', 8888) - host = request.headers.get('X-Forwarded-Host', request.url.hostname) - return f"{proto}://{host}:{port}{root}" + return request.scope.get('root_path', '/') + +@app.get("/") +@app.head("/") +async def root_page(): + return HTMLResponse(html_msg('cellxgene explorer - no file supplied')) @app.get("/d/{data:path}") async def main_page(request: Request, data: str): print('root path is', request.scope.get('root_path')) url = f"{get_base_url(request)}/load/{data}" return HTMLResponse(f''' - - - - - - -
-
loading cellxgene explorer...
-
- - -''', 200) + + + + + + + {html_msg("loading cellxgene explorer...")} + + + ''', 200) @app.get("/load/{data:path}") async def redirect_typer(request: Request, data: str): if not os.path.exists(data): data = f'/{data}' if not os.path.exists(data): - raise Exception(f'can not find data {data}') + return HTMLResponse(html_msg(f'can not find data {data}'), 400) print('loading', data) port = None if data in port_maps: @@ -68,15 +74,23 @@ async def redirect_typer(request: Request, data: str): if not port: port = max([i['port'] for i in port_maps.values()]) + 1 print('starting cellxgene at port', port) - p = Popen(['cellxgene', 'launch', '--port', str(port), '--host', '0.0.0.0', '--annotations-file', get_annotations_file(), '-v', data]) + p = Popen(['cellxgene', 'launch', '--port', str(port), '--host', '0.0.0.0', '--annotations-file', + get_annotations_file(), '-v', data]) port_maps[data] = {'port': port, 'proc': p} - for i in range(timeout): - time.sleep(1) - try: - r = requests.get(f'http://localhost:{port}') - if r.status_code == 200: - print('cellxgene started!') - break - except: - print('waiting on cellxgene') - return RedirectResponse(f"{get_base_url(request)}/cellxgene/{port}/") + loaded = False + for i in range(timeout): + time.sleep(1) + try: + r = requests.get(f'http://localhost:{port}') + if r.status_code == 200: + print('cellxgene started!') + loaded = True + break + except: + print('waiting on cellxgene') + if loaded: + return RedirectResponse(f"{get_base_url(request)}/cellxgene/{port}/") + else: + return HTMLResponse(html_msg(( + '

Timed out loading cellxgene explorer. Try reloading page, or check data integrity.

' + '

If you continue to experience problems please contact support

')))