-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement AnyscaleJob infrastructure (#15)
- Loading branch information
Showing
10 changed files
with
163 additions
and
74 deletions.
There are no files selected for viewing
This file contains 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 file contains 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 file was deleted.
Oops, something went wrong.
This file contains 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 file contains 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 file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
name: prefect-agent-10 | ||
entrypoint: pip install prefect && PREFECT_API_URL=$PREFECT_API_URL PREFECT_API_KEY=$PREFECT_API_KEY python start_anyscale_service.py --queue test | ||
entrypoint: pip install prefect-anyscale && PREFECT_API_URL=$PREFECT_API_URL PREFECT_API_KEY=$PREFECT_API_KEY python start_anyscale_service.py --queue test | ||
runtime_env: | ||
working_dir: https://github.com/anyscale/prefect-anyscale/archive/refs/tags/v0.0.6.zip | ||
working_dir: https://github.com/anyscale/prefect-anyscale/archive/refs/tags/v0.1.0.zip | ||
healthcheck_url: "/healthcheck" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from prefect_anyscale.infrastructure import AnyscaleJob | ||
|
||
__all__ = [ | ||
"AnyscaleJob" | ||
] |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import logging | ||
import os | ||
from typing import Dict, Union | ||
import subprocess | ||
import sys | ||
import tempfile | ||
|
||
from prefect.infrastructure.base import Infrastructure, InfrastructureResult | ||
from prefect.utilities.asyncutils import sync_compatible | ||
from pydantic import Field | ||
from typing_extensions import Literal | ||
|
||
|
||
class AnyscaleJob(Infrastructure): | ||
|
||
type: Literal["anyscale-job"] = Field( | ||
default="anyscale-job", description="The type of infrastructure." | ||
) | ||
|
||
compute_config: Union[None, str, Dict[str, str]] = Field( | ||
description="Compute config to use for the execution of the job.", | ||
default=None, | ||
) | ||
|
||
cluster_env: Union[None, str, Dict[str, str]] = Field( | ||
description="Cluster environment to use for the execution of the job." | ||
) | ||
|
||
_block_type_name = "Anyscale Job" | ||
|
||
def preview(self): | ||
return " \\\n".join( | ||
"compute_config = " + str(self.compute_config), | ||
"cluster_env = " + str(self.cluster_env), | ||
) | ||
|
||
@sync_compatible | ||
async def run( | ||
self, | ||
task_status = None, | ||
): | ||
env = self._get_environment_variables() | ||
api_url = env.get("PREFECT_API_URL") | ||
api_key = env.get("PREFECT_API_KEY") | ||
flow_run_id = env.get("PREFECT__FLOW_RUN_ID") | ||
|
||
cmd = "" | ||
if api_url: | ||
cmd += "PREFECT_API_URL={}".format(api_url) | ||
if api_key: | ||
cmd += " PREFECT_API_KEY={}".format(api_key) | ||
if flow_run_id: | ||
cmd += " PREFECT__FLOW_RUN_ID={}".format(flow_run_id) | ||
|
||
cmd += " /home/ray/anaconda3/bin/python -m prefect.engine" | ||
|
||
# Link the Job on the Anyscale UI with the prefect flow run | ||
job_name = "prefect-job-" + flow_run_id | ||
|
||
content = """ | ||
name: "{}" | ||
entrypoint: "{}" | ||
""".format(job_name, cmd) | ||
|
||
if self.compute_config: | ||
content += 'compute_config: "{}"\n'.format(self.compute_config) | ||
|
||
if self.cluster_env: | ||
content += 'cluster_env: "{}"\n'.format(self.cluster_env) | ||
|
||
with tempfile.NamedTemporaryFile(mode="w") as f: | ||
f.write(content) | ||
f.flush() | ||
logging.info(f"Submitting Anyscale Job with configuration '{content}'") | ||
returncode = subprocess.check_call(["anyscale", "job", "submit", f.name]) | ||
|
||
if task_status: | ||
task_status.started(job_name) | ||
|
||
return AnyscaleJobResult( | ||
status_code=returncode, identifier="" | ||
) | ||
|
||
def _get_environment_variables(self, include_os_environ: bool = True): | ||
os_environ = os.environ if include_os_environ else {} | ||
# The base environment must override the current environment or | ||
# the Prefect settings context may not be respected | ||
env = {**os_environ, **self._base_environment(), **self.env} | ||
|
||
# Drop null values allowing users to "unset" variables | ||
return {key: value for key, value in env.items() if value is not None} | ||
|
||
class AnyscaleJobResult(InfrastructureResult): | ||
"""Contains information about the final state of a completed process""" | ||
pass |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from setuptools import find_packages, setup | ||
|
||
setup( | ||
name="prefect-anyscale", | ||
version="0.1.0", | ||
description="Prefect integrations with Anyscale.", | ||
license="Apache License 2.0", | ||
author="Anyscale, Inc.", | ||
author_email="[email protected]", | ||
keywords="prefect", | ||
url="https://github.com/anyscale/prefect-anyscale", | ||
packages=find_packages(include=["prefect_anyscale"]), | ||
python_requires=">=3.7", | ||
install_requires = [ | ||
"prefect>=2.7.1", | ||
], | ||
classifiers=[ | ||
"Natural Language :: English", | ||
"Intended Audience :: Developers", | ||
"Intended Audience :: System Administrators", | ||
"License :: OSI Approved :: Apache Software License", | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Programming Language :: Python :: 3.7", | ||
"Programming Language :: Python :: 3.8", | ||
"Programming Language :: Python :: 3.9", | ||
"Programming Language :: Python :: 3.10", | ||
"Programming Language :: Python :: 3.11", | ||
"Topic :: Software Development :: Libraries", | ||
], | ||
) |
This file contains 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