Del
12/09/2025, 4:06 PMMarvin
12/09/2025, 4:06 PMMarvin
12/09/2025, 4:14 PMfrom __future__ import annotations
import json
import tempfile
from prefect import flow, task
from prefect.artifacts import create_link_artifact
from prefect_aws.s3 import S3Bucket, get_s3_client
@task
def build_json() -> dict:
# Your result here
return {"status": "ok", "items": [1, 2, 3]}
@task
def upload_json_to_s3(data: dict, s3_block_name: str, key: str, expires_seconds: int = 3600) -> str:
# Save to a temp file
with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False) as f:
json.dump(data, f)
f.flush()
tmp_path = f.name
# Upload using a Prefect block
bucket = S3Bucket.load(s3_block_name)
bucket.upload_from_path(from_path=tmp_path, to_path=key)
# Generate a presigned URL for download
s3 = get_s3_client()
url = s3.generate_presigned_url(
"get_object",
Params={"Bucket": bucket.bucket_name, "Key": key},
ExpiresIn=expires_seconds,
)
return url
@flow
def create_downloadable_result(s3_block_name: str = "my-s3-bucket-block"):
data = build_json()
key = "reports/my_result.json"
url = upload_json_to_s3(data, s3_block_name, key)
# Create a clickable artifact on the flow run page
create_link_artifact(
key="flow-output-json",
link=url,
link_text="Download JSON result",
description="Flow output as a JSON file"
)
return data # Optional: you can still return the dict as the flow result
if __name__ == "__main__":
create_downloadable_result()
Notes
- If you prefer GCS or Azure, use the corresponding Prefect block to upload and create a signed URL, then create a link artifact the same way.
- You can also persist the flow’s return value using Prefect’s result storage, but for a user-friendly “download” experience in the UI, link artifacts are the best approach.
- For very small JSON, you can make it visible inline:
from prefect.artifacts import create_markdown_artifact
create_markdown_artifact(markdown=f"```json\n{json.dumps(data, indent=2)}\n```")
Docs
- Artifacts overview and how-to: Artifacts concepts and Create artifacts
- AWS S3 integration: prefect-aws and S3 reference S3Bucket
- GCP GCS integration: prefect-gcp and GCS reference GcsBucket
Question for you
- Which storage backend do you use (S3/GCS/Azure/local)? Do you need public links or expiring signed URLs? I can tailor the snippet accordingly.