<@ULVA73B9P> Has the API changed recently for pref...
# ask-marvin
m
@Marvin Has the API changed recently for prefect.blocks.system.Secret or prefect.runner.storage.GitRepository? We have a "Ty" check error popping up on a brand new project when trying to load a Secret from the prefect server. The code shown below previously worked fine, but is now giving this error: "ty check error[invalid-argument-type]: Invalid argument to key "access_token" with declared type
str | Secret[str]
on TypedDict
GitCredentials
--> deployment.py4521 | 43 | git_repo = GitRepository( 44 | url=ds.GIT_REPOSITORY, 45 | credentials={"access_token": Secret.load(ds.GIT_ACCESS_TOKEN_SECRET_NAME)}, | -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- | || | | || value of type
Unknown | Coroutine[Any, Any, Unknown]
| |key has declared type
str | Secret[str]
| TypedDict
GitCredentials
46 | branch=git_branch, 47 | ) | info: Item declaration --> .venv\Lib\site-packages\prefect\runner\storage.py815 | 79 | class GitCredentials(TypedDict, total=False): 80 | username: str 81 | access_token: str | Secret[str] | ------------------------------- Item declared here | info: rule
invalid-argument-type
is enabled by default" Code:
Copy code
from prefect.runner.storage import GitRepository
from prefect.blocks.system import Secret
git_repo = GitRepository(
    url=ds.GIT_REPOSITORY,
    credentials={"access_token": Secret.load(ds.GIT_ACCESS_TOKEN_SECRET_NAME)},
    branch=git_branch,
)
m
thought for 286.4 seconds
Short answer: there wasn’t an intentional breaking change to the runtime APIs for
prefect.blocks.system.Secret
or
prefect.runner.storage.GitRepository
. However, recent typing changes (part of “unifying sync and async client methods”) can make some type checkers think
Secret.load(...)
could be a coroutine, which triggers the error you’re seeing. What’s going on -
GitRepository
still accepts credentials like
{"access_token": str | Secret[str]}
. -
Secret.load(name)
still returns a Secret block at runtime, and
Secret.get()
returns the underlying string. - Recent typing changes (see “Unify sync and async client methods”) can cause static type checkers to infer
Unknown | Coroutine[...]
for
Secret.load(...)
, even though it works at runtime. References - Git repository storage source: https://github.com/PrefectHQ/prefect/blob/main/src/prefect/runner/storage.py - Secret block source: https://github.com/PrefectHQ/prefect/blob/main/src/prefect/blocks/system.py - Release notes mentioning the sync/async unification: https://github.com/PrefectHQ/prefect/pull/19217 and the latest changelog: https://github.com/PrefectHQ/prefect/compare/3.4.24...3.4.25 How to fix/work around the type check Pick one of these patterns based on your code being sync or async: - If you are in a synchronous context (most common):
Copy code
from typing import cast
from prefect.blocks.system import Secret
from prefect.runner.storage import GitRepository

token_block = cast(Secret[str], Secret.load(ds.GIT_ACCESS_TOKEN_SECRET_NAME))
git_repo = GitRepository(
    url=ds.GIT_REPOSITORY,
    credentials={"access_token": token_block},
    branch=git_branch,
)
- If you’re in an async function, await the load:
Copy code
from prefect.blocks.system import Secret
from prefect.runner.storage import GitRepository

async def make_repo():
    token_block = await Secret.load(ds.GIT_ACCESS_TOKEN_SECRET_NAME)
    return GitRepository(
        url=ds.GIT_REPOSITORY,
        credentials={"access_token": token_block},
        branch=git_branch,
    )
- Or pass a plain string token (also satisfies the type checker):
Copy code
from prefect.blocks.system import Secret
from prefect.runner.storage import GitRepository

token = Secret.load(ds.GIT_ACCESS_TOKEN_SECRET_NAME).get()
git_repo = GitRepository(
    url=ds.GIT_REPOSITORY,
    credentials={"access_token": token},
    branch=git_branch,
)
Notes - At runtime,
Secret.load(...)
is usable synchronously in Prefect 3.x; the error you’re seeing is strictly about static typing. - If the checker is still unhappy in sync code, the
typing.cast
is the least invasive fix. - If possible, confirm your Prefect version (
python -c "import prefect; print(prefect.__version__)"
). If you’re on a very recent 3.x (e.g., 3.4.25+), this typing behavior is expected due to the sync/async unification work. If you can share: - Your Prefect version - Which type checker (pyright/mypy/etc.) and its version - Whether this runs in a sync or async context …I can tailor the minimal change that will satisfy your checker without suppressions.
n
i would guess
ty
itself has changed recently, as i think its still in alpha?
looks like its related to sync_compatible though, github.com/prefecthq/prefect/issues/15008
m
Thanks @Nate. It looks like it is caused by ty being stricter in a newer version