<@ULVA73B9P> I am writing a flow that tries to cre...
# ask-marvin
n
@Marvin I am writing a flow that tries to create a prefect artifact. But for some reason the artifact is not getting created. Note that I am running this flow locally.
Copy code
def _build_artifact_markdown(plan_year):
  return f"## Sample artifact\n Received: {plan_year}"

@flow
async def my_flow(plan_year):
    # do some work
    # ...
    # Create Prefect artifact
    environment = os.environ.get('FLASK_ENV', 'prod')
    artifact_key = f'{environment}-cms-plan-validation-{plan_year}'
    markdown = _build_artifact_markdown(plan_year)
    create_markdown_artifact(
        key=artifact_key,
        markdown=markdown,
        description=f'CMS plan validation report for {plan_year}',
    )
    <http://logger.info|logger.info>(f'Created artifact with key: {artifact_key}')
m
thought for 204.1 seconds
Thanks for the snippet! A few things to check about artifacts when running locally in Prefect 3.x: Key points - Artifacts are persisted via the Prefect API (Cloud or a local server). When you “just run” a script locally, Prefect will usually auto-start an ephemeral API so the call works—but those artifacts are temporary and there’s no UI for them by default. - If you want to see artifacts in a UI or keep them, point your run at Prefect Cloud or a locally started Prefect server. -
create_markdown_artifact
is the correct function and import, and you do not need to await it even in an async flow. It returns a UUID you can log. What to verify in your code - Import and usage:
Copy code
from prefect import flow
from prefect.artifacts import create_markdown_artifact

def _build_artifact_markdown(plan_year):
    return f"## Sample artifact\n Received: {plan_year}"

@flow
async def my_flow(plan_year: int):
    environment = os.environ.get("FLASK_ENV", "prod")
    artifact_key = f"{environment}-cms-plan-validation-{plan_year}"
    markdown = _build_artifact_markdown(plan_year)

    artifact_id = create_markdown_artifact(
        key=artifact_key,
        markdown=markdown,
        description=f"CMS plan validation report for {plan_year}",
    )
    <http://logger.info|logger.info>(f"Created artifact with id={artifact_id} key={artifact_key}")
- Don’t add
await
to
create_markdown_artifact
(it’s sync with async-dispatch under the hood). If you’re not seeing the artifact, it’s usually one of these: 1) You’re on ephemeral mode (default) and there’s no UI - The artifact is likely created in the ephemeral API but you can’t view it anywhere. - To confirm creation, set
PREFECT_LOGGING_LEVEL=DEBUG
and re-run; you’ll see Prefect start an ephemeral server and the artifact POST. - To see artifacts in a UI locally: - Start a local server:
prefect server start
- Point your run to it: - macOS/Linux:
Copy code
export PREFECT_API_URL=<http://127.0.0.1:4200/api>
- Windows PowerShell:
Copy code
$env:PREFECT_API_URL = "<http://127.0.0.1:4200/api>"
- Run your flow again, then open http://127.0.0.1:4200 and check the flow run’s Artifacts tab. 2) Ephemeral API is disabled or API isn’t reachable - Ensure you did not set
PREFECT_SERVER_EPHEMERAL_ENABLED=false
. - If using Prefect Cloud, make sure both
PREFECT_API_URL
(your workspace URL) and
PREFECT_API_KEY
are set; otherwise the client call will fail silently or log a warning. - Look for warnings like “Could not reach Prefect API” in your logs. 3) Expectation mismatch about where the artifact should appear - In Prefect Cloud: you’ll see it on the flow run page under the Artifacts tab. - In local ephemeral mode: there’s no UI; use a local server if you want to view it. Helpful links - Artifacts concepts - How to produce artifacts - Server and ephemeral settings A couple of quick questions to help pinpoint this: - Where are you expecting to see the artifact (Cloud UI, local UI, or just logs)? - Which Prefect version are you on? - Do your logs show any warnings about the API or ephemeral server? If you can share those lines, I can interpret them.
n
My local run is not ephemeral and it is connected to the prefect cloud. I added prefect debug logging and it had this log line:
Copy code
/Users/nikhiljain/Code/artemis/server/flows/auto_qa/cms_plan_validation_flow.py:149: RuntimeWarning: coroutine 'acreate_markdown_artifact' was never awaited
  create_markdown_artifact(
This indicates that calling
create_markdown_artifact()
does not work in an async flow? I changed it to
await acreate_markdown_artifact()
and now I can see the markdown created. Is this not the correct usage though? Can I directly call
await create_markdown_artifact()
? @Marvin
m
thought for 114.0 seconds
Great debug find — and thanks for the details. Short answer - In an async flow/task, you must await artifact creation. - Both of these are correct in an async flow: -
artifact_id = await create_markdown_artifact(...)
-
artifact_id = await acreate_markdown_artifact(...)
- In a sync flow/task, call the sync name without await: -
artifact_id = create_markdown_artifact(...)
Why you saw “coroutine was never awaited” -
create_markdown_artifact
is decorated with an async-dispatch wrapper. In an async context (like your
@flow async def ...
), it returns a coroutine that you need to await. If you don’t, you’ll get exactly the warning you saw. - In a sync context, it runs synchronously and returns a UUID directly. Examples - Async flow:
Copy code
from prefect import flow
from prefect.artifacts import create_markdown_artifact  # or acreate_markdown_artifact

@flow
async def my_flow(plan_year: int):
    artifact_id = await create_markdown_artifact(
        key=f"prod-cms-plan-validation-{plan_year}",
        markdown=f"## Sample artifact\n Received: {plan_year}",
        description=f"CMS plan validation report for {plan_year}",
    )
    <http://logger.info|logger.info>(f"Created artifact {artifact_id}")
- Sync flow:
Copy code
from prefect import flow
from prefect.artifacts import create_markdown_artifact

@flow
def my_flow(plan_year: int):
    artifact_id = create_markdown_artifact(
        key=f"prod-cms-plan-validation-{plan_year}",
        markdown=f"## Sample artifact\n Received: {plan_year}",
        description=f"CMS plan validation report for {plan_year}",
    )
    <http://logger.info|logger.info>(f"Created artifact {artifact_id}")
References - How to produce artifacts - Artifacts module source - Async-dispatch implementation Since you’re connected to Prefect Cloud (non-ephemeral), you should see the artifact on your flow run page’s Artifacts tab after awaiting the call. If you want a single import that works in both sync and async code, prefer
create_markdown_artifact
and: - await it in async code - call it normally in sync code