How can I determine whether a flow run has been executed ad-hoc or was running on schedule?

Prefect 2.0

You can check that using the auto_scheduled flag available in the flow run context. If this flag is True, then a flow run has been triggered via a regular schedule rather than ad-hoc.

import prefect
from prefect import task, flow

@task
def print_task_context():
    pass

@flow(name="autoscheduled_test")
def main_flow():
    print_task_context()
    print("Flow run scheduled through a deployment?")
    print(prefect.context.get_run_context().flow_run.auto_scheduled)

if __name__ == "__main__":
    main_flow()

Prefect 1.0

Similarly to Orion, Prefect 1.0 also provides the auto_scheduled flag recorded for each flow run. However, it is not available in the context and needs to be retrieved either through UI or GraphQL API. Example query:

query = """ 
query($id: uuid!) {
  flow_run(where: {id: {_eq: $id} }) {
    id
    auto_scheduled
  }
}
"""
client.graphql(query=query, variables=dict(id=prefect.context["flow_run_id"]))