diff --git a/cellpack/autopack/__init__.py b/cellpack/autopack/__init__.py index 2219525b3..ce06494dc 100755 --- a/cellpack/autopack/__init__.py +++ b/cellpack/autopack/__init__.py @@ -411,8 +411,17 @@ def read_text_file(filename, destination="", cache="collisionTrees", force=None) def load_file( - filename, destination="", cache="geometries", force=None, use_docker=False + filename, + destination="", + cache="geometries", + force=None, + use_docker=False, + json_recipe=None, ): + if json_recipe is not None: + composition = DBRecipeLoader.remove_empty(json_recipe.get("composition", {})) + json_recipe["composition"] = composition + return json_recipe, None, False if is_remote_path(filename): database_name, file_path = convert_db_shortname_to_url(filename) if database_name == DATABASE_IDS.GITHUB: diff --git a/cellpack/autopack/loaders/recipe_loader.py b/cellpack/autopack/loaders/recipe_loader.py index 84cd78ac0..cf87a10ca 100644 --- a/cellpack/autopack/loaders/recipe_loader.py +++ b/cellpack/autopack/loaders/recipe_loader.py @@ -30,7 +30,13 @@ class RecipeLoader(object): # TODO: add all default values here default_values = default_recipe_values.copy() - def __init__(self, input_file_path, save_converted_recipe=False, use_docker=False): + def __init__( + self, + input_file_path, + save_converted_recipe=False, + use_docker=False, + json_recipe=None, + ): _, file_extension = os.path.splitext(input_file_path) self.current_version = CURRENT_VERSION self.file_path = input_file_path @@ -38,6 +44,7 @@ def __init__(self, input_file_path, save_converted_recipe=False, use_docker=Fals self.ingredient_list = [] self.compartment_list = [] self.save_converted_recipe = save_converted_recipe + self.json_recipe = json_recipe # set CURRENT_RECIPE_PATH appropriately for remote(firebase) vs local recipes if autopack.is_remote_path(self.file_path): @@ -169,7 +176,10 @@ def _migrate_version(self, old_recipe): def _read(self, resolve_inheritance=True, use_docker=False): new_values, database_name, is_unnested_firebase = autopack.load_file( - self.file_path, cache="recipes", use_docker=use_docker + self.file_path, + cache="recipes", + use_docker=use_docker, + json_recipe=self.json_recipe, ) if database_name == "firebase": if is_unnested_firebase: diff --git a/cellpack/bin/pack.py b/cellpack/bin/pack.py index 9db539372..99186c9da 100644 --- a/cellpack/bin/pack.py +++ b/cellpack/bin/pack.py @@ -25,7 +25,12 @@ def pack( - recipe, config_path=None, analysis_config_path=None, docker=False, validate=True + recipe, + config_path=None, + analysis_config_path=None, + docker=False, + validate=True, + json_recipe=None, ): """ Initializes an autopack packing from the command line @@ -40,7 +45,7 @@ def pack( packing_config_data = ConfigLoader(config_path, docker).config recipe_loader = RecipeLoader( - recipe, packing_config_data["save_converted_recipe"], docker + recipe, packing_config_data["save_converted_recipe"], docker, json_recipe ) recipe_data = recipe_loader.recipe_data analysis_config_data = {} diff --git a/docker/Dockerfile.ecs b/docker/Dockerfile.ecs index 7a303c023..5ed89b7bd 100644 --- a/docker/Dockerfile.ecs +++ b/docker/Dockerfile.ecs @@ -4,7 +4,7 @@ WORKDIR /cellpack COPY . /cellpack RUN python -m pip install --upgrade pip --root-user-action=ignore -RUN python -m pip install . -r requirements/linux/requirements.txt --root-user-action=ignore +RUN python -m pip install . --root-user-action=ignore EXPOSE 80 diff --git a/docker/server.py b/docker/server.py index 581e0151d..ce6da7ee0 100644 --- a/docker/server.py +++ b/docker/server.py @@ -12,11 +12,11 @@ class CellpackServer: def __init__(self): self.packing_tasks = set() - async def run_packing(self, recipe, config, job_id): + async def run_packing(self, recipe, config, job_id, body=None): os.environ["AWS_BATCH_JOB_ID"] = job_id self.update_job_status(job_id, "RUNNING") try: - pack(recipe=recipe, config_path=config, docker=True) + pack(recipe=recipe, config_path=config, docker=True, json_recipe=body) except Exception as e: self.update_job_status(job_id, "FAILED", error_message=str(e)) @@ -37,8 +37,12 @@ async def health_check(self, request: web.Request) -> web.Response: return web.Response() async def pack_handler(self, request: web.Request) -> web.Response: - recipe = request.rel_url.query.get("recipe") - if recipe is None: + recipe = request.rel_url.query.get("recipe") or "" + if request.can_read_body: + body = await request.json() + else: + body = None + if not recipe and not body: raise web.HTTPBadRequest( "Pack requests must include recipe as a query param" ) @@ -46,7 +50,7 @@ async def pack_handler(self, request: web.Request) -> web.Response: job_id = str(uuid.uuid4()) # Initiate packing task to run in background - packing_task = asyncio.create_task(self.run_packing(recipe, config, job_id)) + packing_task = asyncio.create_task(self.run_packing(recipe, config, job_id, body)) # Keep track of task references to prevent them from being garbage # collected, then discard after task completion diff --git a/docs/DOCKER.md b/docs/DOCKER.md index a1214a335..48e4b6ddd 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -13,6 +13,6 @@ ## AWS ECS Docker Image 1. Build image, running `docker build -f docker/Dockerfile.ecs -t [CONTAINER-NAME] .` 2. Run packings in the container, running: `docker run -v ~/.aws:/root/.aws -p 80:80 [CONTAINER-NAME]` -3. Try hitting the test endpoint on the server, by navigating to `http://0.0.0.0:8443/hello` in your browser. -4. Try running a packing on the server, by hitting the `http://0.0.0.0:80/pack?recipe=firebase:recipes/one_sphere_v_1.0.0` in your browser. +3. Try hitting the test endpoint on the server, by navigating to `http://0.0.0.0:80/hello` in your browser. +4. Try running a packing on the server, by hitting the `http://0.0.0.0:80/start-packing?recipe=firebase:recipes/one_sphere_v_1.0.0` in your browser. 5. Verify that the packing result path was uploaded to the firebase results table, with the job id specified in the response from the request in step 4.The result simularium file can be found at the s3 path specified there. \ No newline at end of file