Write Unit/Integration Tests
sungchun12 opened this issue · comments
@desertaxle can you let me know your timeline to finish overall development?
I'm asking, so I can dedicate the right time and energy to help review PRs and contribute where you need help!
@sungchun12 I expect to finish the last two major development issues (#9 and #10) this week. I think next week will be a good time for review/QA to make sure that I've covered everything that you'd like to see in this collection.
Thanks Alex! I'll create time blocks in my calendar for next week.
@belasobral93 FYI so you can plan your time out next week for UX testing!
@sungchun12 @belasobral93 #9 and #10 have been completed, so prefect-dbt
should be ready for UX testing. Let me know if there's anything from me that you need to support UX testing. FYI, Prefect is having planning meetings Tuesday through Friday of this week, so my responses might be delayed.
Can you check off all the below? If there's anything funky, can you make a loom video to show why the UX is funky or is not working?
From there, Alex can make new PRs to fix the issues you find!
- Verify I can plug and play an API token, account id, job id into python code with minimal python knowledge
- Verify I can trigger a job async
- Verify I can trigger a job synchronously with polling
- Verify I can get any artifact such as
sources.json
,run_results.json
,catalog.json
,manifest.json
,example_sql.sql
- Verify I can create a dbt Cloud job using an arbitrary config with json
- Verify the prefect function docstrings are plainly understood from a data analyst perspective
- Verify I can send custom trigger options such a step override commands from a previous task dynamically
- Verify I get a dbt Cloud job to succeed with nice hyperlinks and logs
- Verify I get a dbt Cloud job to fail with helpful hyperlinks and logs
Allocated time to test this thursday : )
Checking in to see if there were any issues discovered during testing. We're back from our planning meetings so we should be able to quickly jump on any issues that are found.
Hi Alex,
I am running into issues in the installation (see error below after running pip install). I’m meeting with Sung this afternoon to see if I can get unblocked. If not, I’ll reach back out
Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x1067a8250>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known')': /simple/pip/
Hi there,
Thanks for the patience in getting feedback on testing. I was unable to get flows to show up locally in the UI, so the following is from the command line. I'm about halfway complete, will finish the rest today (July 20)
- Verify I can plug and play an API token, account id, job id into python code with minimal python knowledge
- Plug and play was simple enough - I would ask to do a quick review of all the function names and how they are referenced
in examples and import statements. I happened to choose trigger_dbt_cloud_job_run () and used the examples that
referenced it as trigger_job_run() so experienced an error.
- Plug and play was simple enough - I would ask to do a quick review of all the function names and how they are referenced
[❌] Verify I can trigger a job async (multi-threaded)
- I’m attempting to use DaskTaskRunner but am getting:
ImportError: cannot import name 'DaskTaskRunner' from 'prefect.task_runners'
Code:
import time
from prefect import task, flow
from prefect_dbt.cloud import DbtCloudCredentials
from prefect_dbt.cloud.jobs import trigger_dbt_cloud_job_run
@task
def call_api(job_id):
job = job_id
credentials = DbtCloudCredentials(api_key="d78e619a99c8acca50d691c4a9477d505756fec2", account_id=43799)
trigger_dbt_cloud_job_run(dbt_cloud_credentials=credentials, job = job)
from prefect.task_runners import DaskTaskRunner
@flow(task_runner=DaskTaskRunner())
def async_flow():
call_api(64242)
call_api(77213)
-
Verify I can trigger a job synchronously (sequentially, one after the other) with polling
- Yes. Created two flows, the first one with a while loop, and first flow completed before second flow was triggered
-
Verify I can get any artifact such as sources.json, run_results.json, catalog.json, manifest.json, example_sql.sql
- Yes all of the above
Thanks for the feedback @belasobral93!
We recently moved the Dask task runner out of the core library and into a seperate collection. To run Prefect with Dask, you'll need to install prefect-dask
and import the Dask task runner from there.
Let me know if you run into any other issues and I'll be happy to help!
Thanks @desertaxle . In trying to execute jobs asynchronously, I'm coming across a runtime warning in using trigger_dbt_cloud_job_run_and_wait_for_completion(). I'm also not seeing any logs indicating the flow was triggered.
error:
/Users/belaloaner/Desktop/prefect-dbt-cloud/dbt_cloud_example.py:7: RuntimeWarning: coroutine 'create_then_begin_flow_run' was never awaited
trigger_dbt_cloud_job_run_and_wait_for_completion(
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
code:
import asyncio
from prefect_dbt.cloud import DbtCloudCredentials
from prefect_dbt.cloud.jobs import trigger_dbt_cloud_job_run_and_wait_for_completion
async def main():
trigger_dbt_cloud_job_run_and_wait_for_completion(
dbt_cloud_credentials=DbtCloudCredentials(
api_key="d78e619a99c8acca50d691c4a9477d505756fec2",
account_id=43799
),
job_id=77213
)
asyncio.run(main())
-
Verify I can plug and play an API token, account id, job id into python code with minimal python knowledge
-
Verify the prefect function docstrings are plainly understood from a data analyst perspective
- @desertaxle I can’t see docstrings in VSCode. Does it have to do with in the import statements I’m seeing text such as: “Import prefect cannot be resolved”? I'm on Python 3.10.4
-
Verify I can trigger a job synchronously with polling
-
Verify I can get any artifact such as sources.json, run_results.json, catalog.json, manifest.json, example_sql.sql
-
Verify I can send custom trigger options such a step override commands from a previous task dynamically
- yes using TriggerJobOptions()
-
[❌] Verify I can trigger a job async
- Attempted to do so but would see first task completed before second task started. Also used await asyncio.sleep but that resulted in each task only beginning once the prior task completed. Is this user error?
code:
@task
async def trigger_dbt_cloud_job_run(job_id):
await asyncio.sleep(5)
return
@flow(task_runner=DaskTaskRunner())
def async_flow():
print("job 1 called")
trigger_dbt_cloud_job_run(64242)
print("job 2 called")
trigger_dbt_cloud_job_run(77213)
print("job 3 called")
trigger_dbt_cloud_job_run(77213)
print("job 4 called")
trigger_dbt_cloud_job_run(77213)
if __name__ == "__main__":
async_flow()
-
[❌] Verify I can create a dbt Cloud job using an arbitrary config with json
- @sungchun12 can you explain this one to me?
-
[❌] Verify I get a dbt Cloud job to succeed with nice hyperlinks and logs
- Please see above issue comment
-
[❌] Verify I get a dbt Cloud job to fail with helpful hyperlinks and logs
- Please see above issue comment
@belasobral93 "Verify I can create a dbt Cloud job using an arbitrary config with json"
Can you verify that code like this can work to create a brand new dbt cloud job?
I took this from the docstring in this codebase: https://github.com/PrefectHQ/prefect-dbt/blob/main/prefect_dbt/cloud/utils.py#L77
from prefect import flow
from prefect_dbt.cloud import DbtCloudCredentials
from prefect_dbt.cloud.utils import call_dbt_cloud_administrative_api_endpoint
@flow
def create_job_flow():
credentials = DbtCloudCredentials(api_key="my_api_key", account_id=123456789)
future = call_dbt_cloud_administrative_api_endpoint(
dbt_cloud_credentials=credentials,
path="/jobs/",
http_method="POST",
json={
"account_id": 123456789,
"project_id": 100,
"environment_id": 10,
"name": "Nightly run",
"dbt_version": "0.17.1",
"triggers": {"github_webhook": True, "schedule": True},
"execute_steps": ["dbt run", "dbt test", "dbt source snapshot-freshness"],
"settings": {"threads": 4, "target_name": "prod"},
"state": 1,
"schedule": {
"date": {"type": "every_day"},
"time": {"type": "every_hour", "interval": 1},
},
},
)
return future.result()["data"]
@desertaxle I noticed after I updated prefect to prefect==2.0b9, that my orion server isn't working correctly anymore.
It doesn't show any of my flows that I verified work correctly.
Bela ran into the same issues yesterday too even after several fresh git clones using this example repo: https://github.com/sungchun12/prefect-dbt-cloud
~/prefect-dbt-cloud │ main !1 python data_pipeline_demo.py ✔ │ 49s │ prefect-dbt-cloud Py
15:08:57.139 | INFO | prefect.engine - Created flow run 'neat-beagle' for flow 'Full Data Pipeline'
15:08:57.139 | INFO | Flow run 'neat-beagle' - Using task runner 'ConcurrentTaskRunner'
15:08:57.184 | WARNING | Flow run 'neat-beagle' - No default storage is configured on the server. Results from this flow run will be stored in a temporary directory in its runtime environment.
15:08:57.322 | INFO | Flow run 'neat-beagle' - Created task run 'Extract-bb1266fe-0' for task 'Extract'
15:08:57.411 | INFO | Flow run 'neat-beagle' - Extract Raw Data
15:08:57.455 | INFO | Task run 'Extract-bb1266fe-0' - Finished in state Completed()
15:08:57.501 | INFO | Flow run 'neat-beagle' - Created task run 'Load-60b30268-0' for task 'Load'
15:08:57.560 | INFO | Flow run 'neat-beagle' - Load Raw Data
15:08:57.595 | INFO | Task run 'Load-60b30268-0' - Finished in state Completed()
15:08:57.630 | INFO | Flow run 'neat-beagle' - Created task run 'Transform-a7d916b4-0' for task 'Transform'
15:08:57.677 | INFO | Flow run 'neat-beagle' - Transform Raw Data
15:08:57.757 | INFO | Task run 'Transform-a7d916b4-0' - Finished in state Completed()
15:08:57.823 | INFO | Flow run 'neat-beagle' - Created task run 'Predict-f915ca64-0' for task 'Predict'
15:08:57.875 | INFO | Flow run 'neat-beagle' - Predict results on transformed data
15:08:57.905 | INFO | Task run 'Predict-f915ca64-0' - Finished in state Completed()
15:08:57.950 | INFO | Flow run 'neat-beagle' - Finished in state Completed('All states completed.')
@sungchun12 can you verify that
prefect config set PREFECT_API_URL=http://127.0.0.1:4200/api
and rerun?
I use the following code:
from prefect import flow, task
@task
def shout(number):
print(f"#{number}")
@flow
def count_to(highest_number):
for number in range(1, highest_number + 1):
if number % 2:
shout.submit(number)
else:
shout(number)
if __name__ == "__main__":
count_to(5)
Outputs:
15:22:23.856 | INFO | prefect.engine - Created flow run 'adept-pegasus' for flow 'count-to'
15:22:23.856 | INFO | Flow run 'adept-pegasus' - Using task runner 'ConcurrentTaskRunner'
15:22:23.866 | WARNING | Flow run 'adept-pegasus' - No default storage is configured on the server. Results from this flow run will be stored in a temporary directory in its runtime environment.
15:22:23.903 | INFO | Flow run 'adept-pegasus' - Created task run 'shout-58a68b34-0' for task 'shout'
15:22:23.922 | INFO | Flow run 'adept-pegasus' - Created task run 'shout-58a68b34-1' for task 'shout'
#1
#2
15:22:23.944 | INFO | Task run 'shout-58a68b34-0' - Finished in state Completed()
15:22:23.950 | INFO | Task run 'shout-58a68b34-1' - Finished in state Completed()
15:22:23.962 | INFO | Flow run 'adept-pegasus' - Created task run 'shout-58a68b34-2' for task 'shout'
15:22:23.979 | INFO | Flow run 'adept-pegasus' - Created task run 'shout-58a68b34-3' for task 'shout'
#3
#4
15:22:24.000 | INFO | Task run 'shout-58a68b34-2' - Finished in state Completed()
15:22:24.008 | INFO | Task run 'shout-58a68b34-3' - Finished in state Completed()
15:22:24.018 | INFO | Flow run 'adept-pegasus' - Created task run 'shout-58a68b34-4' for task 'shout'
#5
15:22:24.043 | INFO | Task run 'shout-58a68b34-4' - Finished in state Completed()
15:22:24.057 | INFO | Flow run 'adept-pegasus' - Finished in state Completed('All states completed.')
Also can you try updating pip install -U "prefect>=2.0b"
Try this for async (add await
and submit()
)
import asyncio
from prefect import task, flow
@task
async def trigger_dbt_cloud_job_run(job_id):
await asyncio.sleep(2)
return
@flow()
async def async_flow():
print("job 1 called")
await trigger_dbt_cloud_job_run.submit(64242)
print("job 2 called")
await trigger_dbt_cloud_job_run.submit(77213)
print("job 3 called")
await trigger_dbt_cloud_job_run.submit(77213)
print("job 4 called")
await trigger_dbt_cloud_job_run.submit(77213)
if __name__ == "__main__":
asyncio.run(async_flow())
Should yield some async output
`@flow(name='my_unique_name', ...)`
warnings.warn(
17:01:33.645 | INFO | prefect.engine - Created flow run 'dramatic-partridge' for flow 'async-flow'
17:01:33.645 | INFO | Flow run 'dramatic-partridge' - Using task runner 'ConcurrentTaskRunner'
17:01:33.657 | WARNING | Flow run 'dramatic-partridge' - No default storage is configured on the server. Results from this flow run will be stored in a temporary directory in its runtime environment.
17:01:33.707 | INFO | Flow run 'dramatic-partridge' - Created task run 'trigger_dbt_cloud_job_run-b91f6471-0' for task 'trigger_dbt_cloud_job_run'
17:01:33.741 | INFO | Flow run 'dramatic-partridge' - Created task run 'trigger_dbt_cloud_job_run-b91f6471-1' for task 'trigger_dbt_cloud_job_run'
17:01:33.781 | INFO | Flow run 'dramatic-partridge' - Created task run 'trigger_dbt_cloud_job_run-b91f6471-2' for task 'trigger_dbt_cloud_job_run'
17:01:33.798 | INFO | Flow run 'dramatic-partridge' - Created task run 'trigger_dbt_cloud_job_run-b91f6471-3' for task 'trigger_dbt_cloud_job_run'
job 1 called
job 2 called
job 3 called
job 4 called
17:01:35.821 | INFO | Task run 'trigger_dbt_cloud_job_run-b91f6471-1' - Finished in state Completed()
17:01:35.826 | INFO | Task run 'trigger_dbt_cloud_job_run-b91f6471-0' - Finished in state Completed()
17:01:35.830 | INFO | Task run 'trigger_dbt_cloud_job_run-b91f6471-2' - Finished in state Completed()
17:01:35.834 | INFO | Task run 'trigger_dbt_cloud_job_run-b91f6471-3' - Finished in state Completed()
17:01:35.851 | INFO | Flow run 'dramatic-partridge' - Finished in state Completed('All states completed.')
Getting different errors now after your suggestions.
Can you try running this example repo? https://github.com/sungchun12/prefect-dbt-cloud
Setup instructions are in the REAMDE
~/prefect-dbt-cloud │ main !1 python basic_flow.py 1 х │ 4s │ prefect-dbt-cloud Py
Traceback (most recent call last):
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/anyio/_core/_sockets.py", line 164, in try_connect
stream = await asynclib.connect_tcp(remote_host, remote_port, local_address)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 1691, in connect_tcp
await get_running_loop().create_connection(
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/base_events.py", line 1025, in create_connection
raise exceptions[0]
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/base_events.py", line 1010, in create_connection
sock = await self._connect_sock(
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/base_events.py", line 924, in _connect_sock
await self.sock_connect(sock, address)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/selector_events.py", line 496, in sock_connect
return await fut
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/selector_events.py", line 528, in _sock_connect_cb
raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 61] Connect call failed ('127.0.0.1', 4200)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_exceptions.py", line 8, in map_exceptions
yield
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/backends/asyncio.py", line 109, in connect_tcp
stream: anyio.abc.ByteStream = await anyio.connect_tcp(
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/anyio/_core/_sockets.py", line 222, in connect_tcp
raise OSError("All connection attempts failed") from cause
OSError: All connection attempts failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_transports/default.py", line 60, in map_httpcore_exceptions
yield
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_transports/default.py", line 353, in handle_async_request
resp = await self._pool.handle_async_request(req)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_async/connection_pool.py", line 253, in handle_async_request
raise exc
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_async/connection_pool.py", line 237, in handle_async_request
response = await connection.handle_async_request(request)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_async/connection.py", line 86, in handle_async_request
raise exc
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_async/connection.py", line 63, in handle_async_request
stream = await self._connect(request)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_async/connection.py", line 111, in _connect
stream = await self._network_backend.connect_tcp(**kwargs)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/backends/auto.py", line 29, in connect_tcp
return await self._backend.connect_tcp(
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/backends/asyncio.py", line 109, in connect_tcp
stream: anyio.abc.ByteStream = await anyio.connect_tcp(
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
raise to_exc(exc)
httpcore.ConnectError: All connection attempts failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/prefect/client.py", line 374, in api_healthcheck
await self._client.get("/health")
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_client.py", line 1751, in get
return await self.request(
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_client.py", line 1527, in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/prefect/client.py", line 256, in send
await super().send(*args, **kwargs)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_client.py", line 1614, in send
response = await self._send_handling_auth(
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_client.py", line 1642, in _send_handling_auth
response = await self._send_handling_redirects(
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_client.py", line 1679, in _send_handling_redirects
response = await self._send_single_request(request)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_client.py", line 1716, in _send_single_request
response = await transport.handle_async_request(request)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_transports/default.py", line 353, in handle_async_request
resp = await self._pool.handle_async_request(req)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/httpx/_transports/default.py", line 77, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.ConnectError: All connection attempts failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "basic_flow.py", line 19, in <module>
count_to(5)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/prefect/flows.py", line 367, in __call__
return enter_flow_run_engine_from_flow_call(
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/prefect/engine.py", line 139, in enter_flow_run_engine_from_flow_call
return anyio.run(begin_run)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/anyio/_core/_eventloop.py", line 70, in run
return asynclib.run(func, *args, **backend_options)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 292, in run
return native_run(wrapper(), debug=debug)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 287, in wrapper
return await func(*args)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/prefect/client.py", line 105, in with_injected_client
return await fn(*args, **kwargs)
File "/Users/sung/prefect-dbt-cloud/env/lib/python3.8/site-packages/prefect/engine.py", line 179, in create_then_begin_flow_run
raise RuntimeError(
RuntimeError: Cannot create flow run. Failed to reach API at http://127.0.0.1:4200/api/.
~/prefect-dbt-cloud │ main !1 prefect orion start ✔ │ 6s │ prefect-dbt-cloud Py
Starting...
___ ___ ___ ___ ___ ___ _____ ___ ___ ___ ___ _ _
| _ \ _ \ __| __| __/ __|_ _| / _ \| _ \_ _/ _ \| \| |
| _/ / _|| _|| _| (__ | | | (_) | /| | (_) | .` |
|_| |_|_\___|_| |___\___| |_| \___/|_|_\___\___/|_|\_|
Configure Prefect to communicate with the server with:
prefect config set PREFECT_API_URL=http://127.0.0.1:4200/api
Check out the dashboard at http://127.0.0.1:4200
INFO: Started server process [82513]
INFO: Waiting for application startup.
ERROR: Traceback (most recent call last):
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/base.py", line 227, in _catch_revision_errors
yield
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/base.py", line 439, in _upgrade_revs
for script in reversed(list(revs))
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 789, in iterate_revisions
revisions, heads = fn(
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 1416, in _collect_upgrade_revisions
current_revisions = self.get_revisions(lower)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 525, in get_revisions
return sum([self.get_revisions(id_elem) for id_elem in id_], ())
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 525, in <listcomp>
return sum([self.get_revisions(id_elem) for id_elem in id_], ())
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 549, in get_revisions
return tuple(
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 550, in <genexpr>
self._revision_for_ident(rev_id, branch_label)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/revision.py", line 619, in _revision_for_ident
raise ResolutionError(
alembic.script.revision.ResolutionError: No such revision or branch '628a873f0d1a'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/starlette/routing.py", line 635, in lifespan
async with self.lifespan_context(app):
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/starlette/routing.py", line 530, in __aenter__
await self._router.startup()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/starlette/routing.py", line 612, in startup
await handler()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/api/server.py", line 259, in run_migrations
await db.create_db()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/database/interface.py", line 53, in create_db
await self.run_migrations_upgrade()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/database/interface.py", line 61, in run_migrations_upgrade
await run_sync_in_worker_thread(alembic_upgrade)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/utilities/asyncio.py", line 54, in run_sync_in_worker_thread
return await anyio.to_thread.run_sync(call, cancellable=True)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/anyio/to_thread.py", line 31, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
return await future
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 867, in run
result = context.run(func, *args)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/database/alembic_commands.py", line 29, in alembic_upgrade
alembic.command.upgrade(alembic_config(), revision, sql=dry_run)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/command.py", line 320, in upgrade
script.run_env()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/base.py", line 563, in run_env
util.load_python_file(self.dir, "env.py")
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/util/pyfiles.py", line 92, in load_python_file
module = load_module_py(module_id, path)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/util/pyfiles.py", line 108, in load_module_py
spec.loader.exec_module(module) # type: ignore
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/database/migrations/env.py", line 98, in <module>
apply_migrations()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/utilities/asyncio.py", line 118, in wrapper
return run_async_from_worker_thread(async_fn, *args, **kwargs)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/utilities/asyncio.py", line 65, in run_async_from_worker_thread
return anyio.from_thread.run(call)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/anyio/from_thread.py", line 49, in run
return asynclib.run_async_from_thread(func, *args)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 970, in run_async_from_thread
return f.result()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/concurrent/futures/_base.py", line 444, in result
return self.__get_result()
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result
raise self._exception
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/database/migrations/env.py", line 92, in apply_migrations
await connection.run_sync(do_run_migrations)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/sqlalchemy/ext/asyncio/engine.py", line 546, in run_sync
return await greenlet_spawn(fn, conn, *arg, **kw)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 128, in greenlet_spawn
result = context.switch(value)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/prefect/orion/database/migrations/env.py", line 80, in do_run_migrations
context.run_migrations()
File "<string>", line 8, in run_migrations
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/runtime/environment.py", line 851, in run_migrations
self.get_context().run_migrations(**kw)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/runtime/migration.py", line 608, in run_migrations
for step in self._migrations_fn(heads, self):
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/command.py", line 309, in upgrade
return script._upgrade_revs(revision, rev)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/base.py", line 435, in _upgrade_revs
return [
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/contextlib.py", line 131, in __exit__
self.gen.throw(type, value, traceback)
File "/Users/sung/.pyenv/versions/3.8.9/lib/python3.8/site-packages/alembic/script/base.py", line 259, in _catch_revision_errors
raise util.CommandError(resolution) from re
alembic.util.exc.CommandError: Can't locate revision identified by '628a873f0d1a'
ERROR: Application startup failed. Exiting.
Orion stopped!
alembic.util.exc.CommandError: Can't locate revision identified by '628a873f0d1a'
I think there was a breaking change in the database; the easiest way to migrate is to delete ~/.prefect/orion.db
@ahuang11 Still getting the same errors with the same error message after deleting this multiple times: ~/.prefect/orion.db
Can you try updating pip install "prefect>=2.0b"
?
@sungchun12 I ran into a similar issue recently and I fixed it by recreating my virtual environment. We can also hop on a call together if that would help resolve issues more quickly.
@desertaxle Thanks for the offer. Let's hope on a quick call: https://calendly.com/d/dvr-zt7-psg/30-minute-meeting
@sungchun12 The earliest available time I saw was Tuesday morning so that's when I booked time, but let me know if you'd like to meet sooner.
@desertaxle saw the meeting invite come through, Tuesday will have to do thanks!
@ahuang11 @desertaxle Looks like there may be something wrong with the create_flow_run() that impacts trigger_dbt_cloud_job_run(). Running the example flow from docs produces the following (same 422 error when I try the async code):
Code
from prefect import flow
@flow(name="Hello Flow")
def hello_world(name="world"):
print(f"Hello {name}!")
hello_world("Marvin")
Logs
Traceback (most recent call last):
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/async_flow.py", line 17, in <module>
hello_world("Marvin")
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/flows.py", line 367, in __call__
return enter_flow_run_engine_from_flow_call(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 134, in enter_flow_run_engine_from_flow_call
return anyio.run(begin_run)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_core/_eventloop.py", line 70, in run
return asynclib.run(func, *args, **backend_options)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 292, in run
return native_run(wrapper(), debug=debug)
File "/Users/belaloaner/.pyenv/versions/3.10.4/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/belaloaner/.pyenv/versions/3.10.4/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 287, in wrapper
return await func(*args)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/client.py", line 107, in with_injected_client
return await fn(*args, **kwargs)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 188, in create_then_begin_flow_run
flow_run = await client.create_flow_run(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/client.py", line 604, in create_flow_run
response = await self._client.post("/flow_runs/", json=flow_run_create_json)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/httpx/_client.py", line 1842, in post
return await self.request(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/httpx/_client.py", line 1527, in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/client.py", line 280, in send
response.raise_for_status()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/client.py", line 226, in raise_for_status
raise PrefectHTTPStatusError.from_httpx_error(exc) from exc.__cause__
prefect.exceptions.PrefectHTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://api-beta.prefect.io/api/accounts/6941ed01-3570-4537-92b5-79296385f7c0/workspaces/3674ba46-c9af-4827-858c-9fedbf830913/flow_runs/'
Response: {'exception_message': 'Invalid request received.', 'exception_detail': [{'loc': ['body', 'flow_runner'], 'msg': 'extra fields not permitted', 'type': 'value_error.extra'}], 'request_body': {'name': 'nocturnal-bullfinch', 'flow_id': 'f10f715f-512b-4226-b177-680f13805858', 'deployment_id': None, 'flow_version': '6c3a0e3ef179a52c083eb85997507207', 'parameters': {'name': 'Marvin'}, 'idempotency_key': None, 'context': {}, 'empirical_policy': {'max_retries': 0, 'retry_delay_seconds': 0.0}, 'tags': [], 'parent_task_run_id': None, 'flow_runner': None, 'state': {'type': 'PENDING', 'name': 'Pending', 'message': None, 'data': None, 'state_details': {'flow_run_id': None, 'task_run_id': None, 'child_flow_run_id': None, 'scheduled_time': None, 'cache_key': None, 'cache_expiration': None}}}}
For more information check: https://httpstatuses.com/422
@belasobral93 Can you try upgrading prefect with pip install "prefect>=2.0b12"
?
thanks @ahuang11 that worked and I see async behavior. I have a question - how can I call the same prefect task with different conditions? Do they need to be in sub-flows?
For example, I want to call trigger_dbt_cloud_job_run() for 2 different jobs, but I want each of them to have different delays (sleep(5), sleep(2). I can't create different tasks for each one, because I can't call a task within a task. So is my only option to put these tasks inside flows? Or can I somehow give these tasks aliases?
I want to set different delays for the following task:
@task
async def trigger_dbt_cloud_job_run(job_id):
await asyncio.sleep(5)
return
-
Verify I can plug and play an API token, account id, job id into python code with minimal python knowledge
-
Verify the prefect function docstrings are plainly understood from a data analyst perspective
-
Verify I can trigger a job synchronously with polling
-
Verify I can get any artifact such as sources.json, run_results.json, catalog.json, manifest.json, example_sql.sql
-
Verify I can send custom trigger options such a step override commands from a previous task dynamically
-
Verify I can trigger a job async
[👩🏽💻] Verify I can create a dbt Cloud job using an arbitrary config with json
[❌] Verify I get a dbt Cloud job to succeed with nice hyperlinks and logs
- @ahuang11 @desertaxle Need the final status saying the job has status SUCCESS & run data returned from dbt's api like trigger_dbt_cloud_job_run() does.
4:15:02.165 | INFO | Flow run 'eccentric-urchin' - dbt Cloud job run with ID 70820362 has status RUNNING. Waiting for 5 seconds.
14:15:07.358 | INFO | Flow run 'eccentric-urchin' - Created task run 'Get dbt Cloud job run details-46ef67b7-12' for task 'Get dbt Cloud job run details'
14:15:07.358 | INFO | Flow run 'eccentric-urchin' - Executing 'Get dbt Cloud job run details-46ef67b7-12' immediately...
14:15:08.521 | INFO | Task run 'Get dbt Cloud job run details-46ef67b7-12' - Finished in state Completed()
14:15:08.770 | INFO | Flow run 'eccentric-urchin' - Created task run 'List dbt Cloud job artifacts-fabe6c19-0' for task 'List dbt Cloud job artifacts'
14:15:08.771 | INFO | Flow run 'eccentric-urchin' - Executing 'List dbt Cloud job artifacts-fabe6c19-0' immediately...
14:15:10.253 | INFO | Task run 'List dbt Cloud job artifacts-fabe6c19-0' - Finished in state Completed()
14:15:10.414 | INFO | Flow run 'eccentric-urchin' - Finished in state Completed()
(env) belaloaner@bela-loaner prefect-dbt-cloud_2 %
- Verify I get a dbt Cloud job to fail with helpful hyperlinks and logs
- logs clearly show that flow failed due to an error in a specific dbt cloud run - run is hyperlinked.
@belasobral93 I don't quite understand, but here's what I think!
@task
async def trigger_dbt_cloud_job_run_one(job_id):
await asyncio.sleep(5)
return
@task
async def trigger_dbt_cloud_job_run_two(job_id):
await asyncio.sleep(2)
return
@flow
async def trigger_flow():
task_one = trigger_dbt_cloud_job_run_one()
task_two = trigger_dbt_cloud_job_run_two()
Or if you must call task within task
@task
async def trigger_dbt_cloud_job_runs():
trigger_dbt_cloud_job_run.fn() # call the underlying Python function so it's not a task
trigger_dbt_cloud_job_run.fn() # call the underlying Python function so it's not a task
You can also rename tasks like
trigger_dbt_cloud_job_run.with_options(name="trigger_one")
@task
async def trigger_dbt_cloud_job_runs():
trigger_dbt_cloud_job_run.fn() # call the underlying Python function so it's not a task
trigger_dbt_cloud_job_run.fn() # call the underlying Python function so it's not a task
^^ Is what I was looking for. If I call trigger_dbt_cloud_job_run_one() it won't know that I want to call trigger_dbt_cloud_job_run() specifically.
If I use (name="trigger_one") does that mean I could then call it like this?
@task
async def trigger_one():
If I use (name="trigger_one") does that mean I could then call it like this?
No I don't think so; it just shows up in the UI/terminal with that name, e.g. https://discourse.prefect.io/t/how-to-display-more-descriptive-task-run-names-in-the-radar-view-ui/1146
You could certainly wrap it inside another python function, but I don't quite understand the goal.
[❌] Verify I can create a dbt Cloud job using an arbitrary config with json
Getting an error using docstrings example.
To try and resolve I did the following (was not successful in resolving):
- removed the trailing comma after the schedule object (I believe trailing commas not allowed in json?)
- Compared and validated body structure + included all elements listed in our postman collection for POST Create Job
14:55:27.498 | ERROR | Flow run 'upbeat-moose' - Finished in state Failed('Flow run encountered an exception.')
Traceback (most recent call last):
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/arbitrary.py", line 54, in <module>
create_job_flow()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/flows.py", line 367, in __call__
return enter_flow_run_engine_from_flow_call(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 150, in enter_flow_run_engine_from_flow_call
return anyio.run(begin_run)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_core/_eventloop.py", line 70, in run
return asynclib.run(func, *args, **backend_options)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 292, in run
return native_run(wrapper(), debug=debug)
File "/Users/belaloaner/.pyenv/versions/3.10.4/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/belaloaner/.pyenv/versions/3.10.4/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 287, in wrapper
return await func(*args)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/client.py", line 104, in with_injected_client
return await fn(*args, **kwargs)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 226, in create_then_begin_flow_run
return state.result()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/orion/schemas/states.py", line 145, in result
raise data
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 559, in orchestrate_flow_run
result = await run_sync(flow_call)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/utilities/asyncutils.py", line 56, in run_sync_in_worker_thread
return await anyio.to_thread.run_sync(call, cancellable=True)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/to_thread.py", line 31, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
return await future
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 867, in run
result = context.run(func, *args)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/arbitrary.py", line 14, in create_job_flow
future = call_dbt_cloud_administrative_api_endpoint(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/tasks.py", line 282, in __call__
return enter_task_run_engine(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 688, in enter_task_run_engine
return run_async_from_worker_thread(begin_run)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/utilities/asyncutils.py", line 136, in run_async_from_worker_thread
return anyio.from_thread.run(call)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/from_thread.py", line 49, in run
return asynclib.run_async_from_thread(func, *args)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 970, in run_async_from_thread
return f.result()
File "/Users/belaloaner/.pyenv/versions/3.10.4/lib/python3.10/concurrent/futures/_base.py", line 446, in result
return self.__get_result()
File "/Users/belaloaner/.pyenv/versions/3.10.4/lib/python3.10/concurrent/futures/_base.py", line 391, in __get_result
raise self._exception
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 803, in create_task_run_then_submit
return await future._result()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/futures.py", line 220, in _result
return final_state.result(raise_on_failure=raise_on_failure)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/orion/schemas/states.py", line 145, in result
raise data
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect/engine.py", line 1039, in orchestrate_task_run
result = await task.fn(*args, **kwargs)
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect_dbt/cloud/utils.py", line 113, in call_dbt_cloud_administrative_api_endpoint
response = await client.call_endpoint(
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/prefect_dbt/cloud/clients.py", line 56, in call_endpoint
response.raise_for_status()
File "/Users/belaloaner/Desktop/prefect-dbt-cloud_2/env/lib/python3.10/site-packages/httpx/_models.py", line 736, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://cloud.getdbt.com/api/v2/accounts/43799/jobs/'
For more information check: https://httpstatuses.com/400
@belasobral93 For the prefect Orion UI, Alex and I were able to make it work but through non-repeatable means because prefect 2.0 is still in flux. Once prefect 2.0 is GA tomorrow, the UI errors should decrease.
With that in mind, once all the mechanical pieces above are done, we'll have prefect GA this integration tomorrow so that broader adoption can happen and fix further bugs.
@belasobral93 I updated the create job example in #37 and it should be working now. Also, trigger_dbt_cloud_job_run_and_wait_for_completion
returns the result of the job run along with the artifacts. If you print out the return value from the flow, you can inspect it to make sure that it has all of the fields that you are expecting. Here's an output that I got:
{
"id":71164019,
"trigger_id":71879132,
"account_id":36394,
"environment_id":97658,
"project_id":118320,
"job_definition_id":97588,
"status":10,
"dbt_version":"1.1.0-latest",
"git_branch":"demo-sung",
"git_sha":"6b86c1e47900b3caa37a2af840770faa1c4ef2b2",
"status_message":"None",
"owner_thread_id":"None",
"executed_by_thread_id":"dbt-run-71164019",
"deferring_run_id":"None",
"artifacts_saved":true,
"artifact_s3_path":"prod/runs/71164019/artifacts/target",
"has_docs_generated":true,
"has_sources_generated":true,
"notifications_sent":true,
"blocked_by":[
],
"scribe_enabled":true,
"created_at":"2022-07-27 12:30:03.850957+00:00",
"updated_at":"2022-07-27 12:32:03.363227+00:00",
"dequeued_at":"2022-07-27 12:30:05.318124+00:00",
"started_at":"2022-07-27 12:30:11.271817+00:00",
"finished_at":"2022-07-27 12:32:02.950524+00:00",
"last_checked_at":"2022-07-27 12:32:03.251493+00:00",
"last_heartbeat_at":"2022-07-27 12:31:41.302098+00:00",
"should_start_at":"2022-07-27 12:30:03.850957+00:00",
"trigger":"None",
"job":"None",
"environment":"None",
"run_steps":[
],
"status_humanized":"Success",
"in_progress":false,
"is_complete":true,
"is_success":true,
"is_error":false,
"is_cancelled":false,
"href":"https://cloud.getdbt.com/#/accounts/36394/projects/118320/runs/71164019/",
"duration":"00:01:59",
"queued_duration":"00:00:07",
"run_duration":"00:01:51",
"duration_humanized":"1 minute, 59 seconds",
"queued_duration_humanized":"7 seconds",
"run_duration_humanized":"1 minute, 51 seconds",
"created_at_humanized":"2 minutes, 5 seconds ago",
"finished_at_humanized":"6 seconds ago",
"job_id":97588,
"is_running":"None",
"artifact_paths":[
...
]
}
I truncated artifact_paths
for readability, but is that what you're expecting to see?
(checkboxes for CLI, will do for UI)
-
Verify I can plug and play an API token, account id, job id into python code with minimal python knowledge
-
Verify the prefect function docstrings are plainly understood from a data analyst perspective
-
Verify I can trigger a job synchronously with polling
-
Verify I can get any artifact such as sources.json, run_results.json, catalog.json, manifest.json, example_sql.sql
-
Verify I can send custom trigger options such a step override commands from a previous task dynamically
-
Verify I can trigger a job async
-
Verify I can create a dbt Cloud job using an arbitrary config with json
-
Verify I get a dbt Cloud job to fail with helpful hyperlinks and logs
-
Verify I get a dbt Cloud job to succeed with nice hyperlinks and logs
@desertaxle great, that data response is what I was looking for. Can we get also get a cloud job run status printed to log when a run is successful?
@desertaxle @belasobral93 What's left to get this officially released? Just that missing checkbox in the previous comment?
@sungchun12 yep! Nothing left on my end other than that ask
I opened #40 to add a log message letting the user know that a run was successful. @belasobral93 can you confirm that this fulfills the last requirement? If so, we should be able to get #40 merged and release prefect-dbt
today!
@desertaxle it does, thank you. We're good to go @sungchun12
Thanks for the progress on this. I’m honestly so excited to brag about how fun and meaningful this work has been together. I already said this a couple times in candid conversations, but this is a great role model for what open source, async partnership can look and feel like. And it feels quite splendid!
@belasobral93 you should make a quick and fun “QuickStart” tutorial this week in loom! I’ll share it with pride :)
@sungchun12 on it!
I'm going to close this issue since it sounds like we've finished QA. I've opened #41 to prepare for the first release of prefect-dbt
, so we can discuss anything that's needed prior to release there!