添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

I’m in the process of migrating from a Prefect 1.0 cloud deployment to a 2.0 cloud deploying and I’m receiving the error “AttributeError: ‘coroutine’ object has no attribute ‘apply’” when trying to run the hi_deploy.py deployment code example.

hi_deploy.py:

from prefect import flow
from prefect.deployments import Deployment
@flow(log_prints=True)
def hi():
    print("Hi from Prefect!")
def deploy():
    deployment = Deployment.build_from_flow(
        flow=hi,
        name="prefect-example-deployment"
    deployment.apply()
if __name__ == "__main__":
    deploy()

full error context:

 File ~\Anaconda3\envs\prefect\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
    exec(code, globals, locals)
  File ~\untitled0.py:16
    deploy()
  File ~\untitled0.py:13 in deploy
    deployment.apply()
AttributeError: 'coroutine' object has no attribute 'apply'

I’m running the example in new conda environment on a windows 10 machine with the following packages installed:

aiosqlite==0.18.0
alabaster==0.7.12
alembic==1.10.2
anyio==3.6.2
apprise==1.3.0
arrow==1.2.3
asgi-lifespan==2.0.0
asn1crypto==1.5.1
astroid==2.11.7
asttokens==2.0.5
asyncpg==0.27.0
atomicwrites==1.4.0
attrs==22.2.0
autopep8==1.6.0
Babel==2.11.0
backcall==0.2.0
bcrypt==3.2.0
beautifulsoup4==4.12.0
binaryornot==0.4.4
black==22.6.0
bleach==4.1.0
boto3==1.24.28
botocore==1.27.59
Bottleneck==1.3.5
brotlipy==0.7.0
cachetools==5.3.0
certifi==2022.12.7
cffi==1.15.1
chardet==4.0.0
charset-normalizer==3.1.0
click==8.1.3
cloudpickle==2.2.1
colorama==0.4.6
comm==0.1.2
cookiecutter==1.7.3
coolname==2.2.0
croniter==1.3.8
cryptography==39.0.2
dateparser==1.1.7
debugpy==1.5.1
decorator==5.1.1
defusedxml==0.7.1
diff-match-patch==20200713
dill==0.3.6
docker==6.0.1
docstring-to-markdown==0.11
docutils==0.18.1
ecdsa==0.17.0
entrypoints==0.4
et-xmlfile==1.1.0
executing==0.8.3
fastapi==0.95.0
fastjsonschema==2.16.2
flake8==6.0.0
flit_core==3.6.0
fsspec==2023.1.0
google-auth==2.16.2
greenlet==2.0.2
griffe==0.25.5
h11==0.14.0
h2==4.1.0
hpack==4.0.0
httpcore==0.16.3
httpx==0.23.3
hyperframe==6.0.1
idna==3.4
imagesize==1.4.1
importlib-metadata==4.11.3
inflection==0.5.1
intervaltree==3.1.0
ipykernel==6.19.2
ipython==8.8.0
ipython-genutils==0.2.0
isort==5.9.3
jedi==0.18.1
jellyfish==0.9.0
Jinja2==3.1.2
jinja2-time==0.2.0
jmespath==0.10.0
jsonpatch==1.32
jsonpointer==2.3
jsonschema==4.17.3
jupyter_client==7.4.9
jupyter_core==5.1.1
jupyterlab-pygments==0.1.2
keyring==23.4.0
kubernetes==26.1.0
lazy-object-proxy==1.6.0
lxml==4.9.1
Mako==1.2.4
Markdown==3.4.1
markdown-it-py==2.2.0
MarkupSafe==2.1.2
matplotlib-inline==0.1.6
mccabe==0.7.0
mdurl==0.1.2
mistune==0.8.4
mkl-fft==1.3.1
mkl-random==1.2.2
mkl-service==2.4.0
mypy-extensions==0.4.3
nbclient==0.5.13
nbconvert==6.5.4
nbformat==5.7.0
nest-asyncio==1.5.6
numexpr==2.8.4
numpy==1.23.5
numpydoc==1.5.0
oauthlib==3.2.2
openpyxl==3.0.10
orjson==3.8.8
packaging==23.0
pandas==1.5.3
pandocfilters==1.5.0
paramiko==2.8.1
parso==0.8.3
pathspec==0.11.1
pendulum==2.1.2
pexpect==4.8.0
pickleshare==0.7.5
pip==23.0.1
platformdirs==2.5.2
plotly==5.9.0
pluggy==1.0.0
ply==3.11
poyo==0.5.0
prefect==2.8.6
prompt-toolkit==3.0.36
psutil==5.9.0
psycopg2==2.9.3
ptyprocess==0.7.0
pure-eval==0.2.2
pyarrow==8.0.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycodestyle==2.10.0
pycparser==2.21
pydantic==1.10.6
pydocstyle==6.3.0
pyflakes==3.0.1
Pygments==2.14.0
pylint==2.14.5
pylint-venv==2.3.0
pyls-spyder==0.4.0
PyNaCl==1.5.0
pyodbc==4.0.34
pyOpenSSL==23.0.0
PyQt5==5.15.7
PyQt5-sip==12.11.0
PyQtWebEngine==5.15.4
pyrsistent==0.19.3
PySocks==1.7.1
python-dateutil==2.8.2
python-dotenv==1.0.0
python-http-client==3.3.2
python-lsp-black==1.2.1
python-lsp-jsonrpc==1.0.0
python-lsp-server==1.7.1
python-slugify==8.0.1
pytoolconfig==0.0.0
pytz==2022.7.1
pytz-deprecation-shim==0.1.0.post0
pytzdata==2020.1
pywin32==305.1
pywin32-ctypes==0.2.0
PyYAML==6.0
pyzmq==23.2.0
QDarkStyle==3.0.2
qstylizer==0.2.2
QtAwesome==1.2.2
qtconsole==5.4.0
QtPy==2.2.0
readchar==4.0.5
redshift-connector==2.0.910
regex==2022.10.31
requests==2.28.2
requests-oauthlib==1.3.1
rfc3986==1.5.0
rich==13.3.2
rope==1.7.0
rsa==4.9
Rtree==1.0.1
s3transfer==0.6.0
scramp==1.4.4
sendgrid==6.7.1
setuptools==65.6.3
sip==6.6.2
six==1.16.0
sniffio==1.3.0
snowballstemmer==2.2.0
sortedcontainers==2.4.0
soupsieve==2.3.2.post1
Sphinx==5.0.2
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
spyder==5.4.2
spyder-kernels==2.4.2
SQLAlchemy==1.4.47
stack-data==0.2.0
starkbank-ecdsa==1.1.1
starlette==0.26.1
tenacity==8.0.1
text-unidecode==1.3
textdistance==4.2.1
three-merge==0.1.1
tinycss2==1.2.1
toml==0.10.2
tomli==2.0.1
tomlkit==0.11.1
tornado==6.2
traitlets==5.7.1
typer==0.7.0
typing_extensions==4.5.0
tzdata==2022.7
tzlocal==4.3
ujson==5.4.0
Unidecode==1.2.0
urllib3==1.26.15
uvicorn==0.21.1
watchdog==2.1.6
wcwidth==0.2.5
webencodings==0.5.1
websocket-client==1.5.1
websockets==10.4
Werkzeug==2.2.2
whatthepatch==1.0.2
wheel==0.38.4
win-inet-pton==1.1.0
wincertstore==0.2
wrapt==1.14.1
XlsxWriter==3.0.3
yapf==0.31.0
zipp==3.15.0
              

When inspecting the contents of the ~\Lib\site-packages\prefect\deployments.py file I can see that the apply attribute is definitely present in the Deployment Class

@experimental_field( "work_pool_name", group="work_pools", when=lambda x: x is not None and x != DEFAULT_AGENT_WORK_POOL_NAME, class Deployment(BaseModel): # ........................ truncated .......................... @sync_compatible async def apply( self, upload: bool = False, work_queue_concurrency: int = None ) -> UUID: Registers this deployment with the API and returns the deployment's ID. Args: upload: if True, deployment files are automatically uploaded to remote storage work_queue_concurrency: If provided, sets the concurrency limit on the deployment's work queue if not self.name or not self.flow_name: raise ValueError("Both a deployment name and flow name must be set.") async with get_client() as client: # prep IDs flow_id = await client.create_flow_from_name(self.flow_name) infrastructure_document_id = self.infrastructure._block_document_id if not infrastructure_document_id: # if not building off a block, will create an anonymous block self.infrastructure = self.infrastructure.copy() infrastructure_document_id = await self.infrastructure._save( is_anonymous=True, if upload: await self.upload_to_storage() if self.work_queue_name and work_queue_concurrency is not None: res = await client.create_work_queue( name=self.work_queue_name, work_pool_name=self.work_pool_name except ObjectAlreadyExists: res = await client.read_work_queue_by_name( name=self.work_queue_name, work_pool_name=self.work_pool_name await client.update_work_queue( res.id, concurrency_limit=work_queue_concurrency # we assume storage was already saved storage_document_id = getattr(self.storage, "_block_document_id", None) deployment_id = await client.create_deployment( flow_id=flow_id, name=self.name, work_queue_name=self.work_queue_name, work_pool_name=self.work_pool_name, version=self.version, schedule=self.schedule, is_schedule_active=self.is_schedule_active, parameters=self.parameters, description=self.description, tags=self.tags, manifest_path=self.manifest_path, # allows for backwards YAML compat path=self.path, entrypoint=self.entrypoint, infra_overrides=self.infra_overrides, storage_document_id=storage_document_id, infrastructure_document_id=infrastructure_document_id, parameter_openapi_schema=self.parameter_openapi_schema.dict(), return deployment_id # ........................ truncated .......................... if apply: await deployment.apply() return deployment

I think I found my issue, or at least a work around… It looks like the Prefect 2.0 deployment script will not run properly when trying to execute it in the Spyder IDE (version 5.4.2), as was possible when trying to register a flow with flow.register(project_name = “gather_shells”) in Prefect 1.0

I was able to run the deployment script and register the project from the CLI. It would be nice to be able to register the project directly from an IDE.