Last active
February 8, 2021 17:37
-
-
Save gwbischof/bef2882fd31977ca7e08b920234115cc to your computer and use it in GitHub Desktop.
BlueskyDatabrokerPackServer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| This builds and serves databroker-pack files | |
| """ | |
| import asyncio | |
| import os | |
| import pathlib | |
| import subprocess | |
| import tempfile | |
| import zipfile | |
| from fastapi import FastAPI, status | |
| from fastapi.responses import FileResponse | |
| import databroker.tutorial_utils | |
| HOST = '0.0.0.0' | |
| PORT = 9090 | |
| catalog_name = os.environ.get("PACK_CATALOG", | |
| 'bluesky-tutorial-BMM') | |
| pack_directory = os.environ.get("PACK_DIRECTORY", | |
| os.path.join(pathlib.Path.home(), "packs")) | |
| available_packs = set() | |
| currently_packing = dict() | |
| app = FastAPI() | |
| def zipdir(path, ziph): | |
| # https://stackoverflow.com/a/1855118/6513183 | |
| # ziph is zipfile handle | |
| for root, dirs, files in os.walk(path): | |
| for file in files: | |
| ziph.write(os.path.join(root, file), | |
| os.path.relpath(os.path.join(root, file), | |
| os.path.join(path, '..'))) | |
| def initialize(pack_directory): | |
| global available_packs | |
| os.makedirs(pack_directory, exist_ok=True) | |
| available_packs = {filename.split('.')[0] for | |
| filename in os.listdir(pack_directory)} | |
| databroker.tutorial_utils.fetch_BMM_example() | |
| def authorized_run(token, run_uid): | |
| return True | |
| def authorized_file(token, file_name): | |
| return True | |
| def eta(process): | |
| return '?' | |
| async def pack(run_uid): | |
| global available_packs | |
| global currently_packing | |
| if run_uid in currently_packing.keys(): | |
| return "Already Packing" | |
| with open(pack_directory + '/' + run_uid + ".txt", "w+") as f: | |
| f.write(run_uid) | |
| process = asyncio.create_subprocess_exec( | |
| 'databroker-pack', | |
| *f'{catalog_name} --uids {pack_directory + "/" + run_uid + ".txt"} {pack_directory + "/" + run_uid}'.split()) | |
| currently_packing[run_uid] = lambda: '?' #eta(process) | |
| asyncio.create_task(finish_packing(process, run_uid)) | |
| return process | |
| async def finish_packing(process, run_uid): | |
| global currently_packing | |
| global available_packs | |
| print("Packing Started!", run_uid) | |
| try: | |
| await process | |
| zipf = zipfile.ZipFile(os.path.join(pack_directory, run_uid + '.tar.gz'), | |
| 'w', zipfile.ZIP_DEFLATED) | |
| zipdir(os.path.join(pack_directory, run_uid), zipf) | |
| zipf.close() | |
| except Exception as e: | |
| print("Packing failed :(", run_uid) | |
| currently_packing.pop(run_uid) | |
| raise e | |
| currently_packing.pop(run_uid, None) | |
| available_packs.add(run_uid) | |
| print("Packing Complete!", run_uid) | |
| @app.get("/pack/{run_uid}") | |
| async def get_pack(run_uid: str, token=None): | |
| global currently_packing | |
| pack_path = os.path.join(pack_directory, run_uid + '.tar.gz') | |
| if not authorized_run(token, run_uid): | |
| return "Authentication Failed" | |
| if run_uid in available_packs: | |
| return FileResponse(pack_path) | |
| await pack(run_uid) | |
| return {"status": "queued", "eta": currently_packing[run_uid]()} | |
| @app.get("/file/") | |
| async def get_file(filename: str, token=None): | |
| if not os.path.exists(filename): | |
| return "File not found" | |
| if not authorized_file(token, filename): | |
| return "Authentication Failed" | |
| return FileResponse(filename) | |
| @app.on_event("startup") | |
| def startup(): | |
| print('Starting BlueskyPackServer') | |
| initialize(pack_directory) | |
| @app.on_event("shutdown") | |
| def shutdown(): | |
| print('Stopping BlueskyPackServer') | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run('BlueskyDatabrokerPackServer:app', host=HOST, port=PORT, | |
| log_level='info', reload=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment