forked from flyteorg/flytekit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BUG] Open FlyteFile from remote path (flyteorg#2991)
* fix: Open FlyteFile from remote path Signed-off-by: JiaWei Jiang <[email protected]> * Add integration test Signed-off-by: JiaWei Jiang <[email protected]> * refactor: Use ctx as param instead of recreation Signed-off-by: JiaWei Jiang <[email protected]> * refactor: Clean test logic 1. Remove redundant prints 2. Use `mock.patch.dict` to setup `os.environ` for the current test fn * Avoid contaminating other tests running in the same process Signed-off-by: JiaWei Jiang <[email protected]> * refactor: Setup local path and downloader in constructor Signed-off-by: JiaWei Jiang <[email protected]> * refactor: Move SimpleFileTransfer to an utility file Signed-off-by: JiaWei Jiang <[email protected]> * Remove redundant env var setup Please refer to flyteorg#3001 Signed-off-by: JiaWei Jiang <[email protected]> * test: Add another ff use case Create ff in one task pod and read it in another task pod. Signed-off-by: JiaWei Jiang <[email protected]> --------- Signed-off-by: JiaWei Jiang <[email protected]> Signed-off-by: Shuying Liang <[email protected]>
- Loading branch information
1 parent
836e27f
commit ce04660
Showing
4 changed files
with
229 additions
and
9 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 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,98 @@ | ||
""" | ||
Common utilities for flyte remote runs in integration tests. | ||
""" | ||
import os | ||
import json | ||
import tempfile | ||
import pathlib | ||
|
||
import botocore.session | ||
from botocore.client import BaseClient | ||
from flytekit.configuration import Config | ||
from flytekit.remote.remote import FlyteRemote | ||
|
||
|
||
# Define constants | ||
CONFIG = os.environ.get("FLYTECTL_CONFIG", str(pathlib.Path.home() / ".flyte" / "config-sandbox.yaml")) | ||
PROJECT = "flytesnacks" | ||
DOMAIN = "development" | ||
|
||
|
||
class SimpleFileTransfer: | ||
"""Utilities for file transfer to minio s3 bucket. | ||
Mainly support single file uploading and automatic teardown. | ||
""" | ||
|
||
def __init__(self) -> None: | ||
self._remote = FlyteRemote( | ||
config=Config.auto(config_file=CONFIG), | ||
default_project=PROJECT, | ||
default_domain=DOMAIN | ||
) | ||
self._s3_client = self._get_minio_s3_client(self._remote) | ||
|
||
def _get_minio_s3_client(self, remote: FlyteRemote) -> BaseClient: | ||
"""Creat a botocore client.""" | ||
minio_s3_config = remote.file_access.data_config.s3 | ||
sess = botocore.session.get_session() | ||
|
||
return sess.create_client( | ||
"s3", | ||
endpoint_url=minio_s3_config.endpoint, | ||
aws_access_key_id=minio_s3_config.access_key_id, | ||
aws_secret_access_key=minio_s3_config.secret_access_key, | ||
) | ||
|
||
def upload_file(self, file_type: str) -> str: | ||
"""Upload a single file to minio s3 bucket. | ||
Args: | ||
file_type: File type. Support "txt" and "json". | ||
Returns: | ||
remote_file_path: Remote file path. | ||
""" | ||
with tempfile.TemporaryDirectory() as tmp_dir: | ||
local_file_path = self._dump_tmp_file(file_type, tmp_dir) | ||
|
||
# Upload to minio s3 bucket | ||
_, remote_file_path = self._remote.upload_file( | ||
to_upload=local_file_path, | ||
project=PROJECT, | ||
domain=DOMAIN, | ||
) | ||
|
||
return remote_file_path | ||
|
||
def _dump_tmp_file(self, file_type: str, tmp_dir: str) -> str: | ||
"""Generate and dump a temporary file locally. | ||
Args: | ||
file_type: File type. | ||
tmp_dir: Temporary directory. | ||
Returns: | ||
tmp_file_path: Temporary local file path. | ||
""" | ||
if file_type == "txt": | ||
tmp_file_path = pathlib.Path(tmp_dir) / "test.txt" | ||
with open(tmp_file_path, "w") as f: | ||
f.write("Hello World!") | ||
elif file_type == "json": | ||
d = {"name": "john", "height": 190} | ||
tmp_file_path = pathlib.Path(tmp_dir) / "test.json" | ||
with open(tmp_file_path, "w") as f: | ||
json.dump(d, f) | ||
|
||
return tmp_file_path | ||
|
||
def delete_file(self, bucket: str, key: str) -> None: | ||
"""Delete the remote file from minio s3 bucket to free the space. | ||
Args: | ||
bucket: s3 bucket name. | ||
key: Key name of the object. | ||
""" | ||
res = self._s3_client.delete_object(Bucket=bucket, Key=key) | ||
assert res["ResponseMetadata"]["HTTPStatusCode"] == 204 |
52 changes: 52 additions & 0 deletions
52
tests/flytekit/integration/remote/workflows/basic/flytefile.py
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,52 @@ | ||
from flytekit import task, workflow | ||
from flytekit.types.file import FlyteFile | ||
|
||
|
||
@task | ||
def create_ff(file_path: str) -> FlyteFile: | ||
"""Create a FlyteFile.""" | ||
return FlyteFile(path=file_path) | ||
|
||
|
||
@task | ||
def read_ff(ff: FlyteFile) -> None: | ||
"""Read input FlyteFile. | ||
This can be used in the case in which a FlyteFile is created | ||
in another task pod and read in this task pod. | ||
""" | ||
with open(ff, "r") as f: | ||
content = f.read() | ||
print(f"FILE CONTENT | {content}") | ||
|
||
|
||
@task | ||
def create_and_read_ff(file_path: str) -> FlyteFile: | ||
"""Create a FlyteFile and read it. | ||
Both FlyteFile creation and reading are done in this task pod. | ||
Args: | ||
file_path: File path. | ||
Returns: | ||
ff: FlyteFile object. | ||
""" | ||
ff = FlyteFile(path=file_path) | ||
with open(ff, "r") as f: | ||
content = f.read() | ||
print(f"FILE CONTENT | {content}") | ||
|
||
return ff | ||
|
||
|
||
@workflow | ||
def wf(remote_file_path: str) -> None: | ||
ff_1 = create_ff(file_path=remote_file_path) | ||
read_ff(ff=ff_1) | ||
ff_2 = create_and_read_ff(file_path=remote_file_path) | ||
read_ff(ff=ff_2) | ||
|
||
|
||
if __name__ == "__main__": | ||
wf() |