<@ULVA73B9P> After updating the local Python packa...
# ask-marvin
t
@Marvin After updating the local Python package for prefect, the JSON package stopped working. How can I load JSON?
Copy code
In [52]: from prefect.blocks.system import JSON
    ...:
-----------------------------------------------------------------------
ImportError                           Traceback (most recent call last)
Cell In[52], line 1
----> 1 from prefect.blocks.system import JSON

ImportError: cannot import name 'JSON' from 'prefect.blocks.system' (/Users/****/Library/Caches/pypoetry/virtualenvs/project-f23tm-o6-py3.11/lib/python3.11/site-packages/prefect/blocks/system.py)
m
thought for 449.5 seconds
Thanks for sharing the traceback — this isn’t a bug in your environment. In Prefect 3.x the
JSON
system block was removed. That’s why
from prefect.blocks.system import JSON
now raises ImportError. How to load/store JSON now - For non-sensitive config, use Variables:
Copy code
from prefect.variables import Variable

# Save (one-time or when updating)
Variable.set("my-config", {"api_url": "<https://api.example.com>", "retries": 3}, overwrite=True)

# Load
config = Variable.get("my-config")
print(config["api_url"])
- For sensitive JSON (API keys, credentials), use the Secret block:
Copy code
from prefect.blocks.system import Secret

# Save (one-time)
Secret(value={"api_key": "sk-abc", "timeout": 30}).save("my-config-secret", overwrite=True)

# Load
secret = Secret.load("my-config-secret")
config = secret.get()  # returns the dict
print(config["api_key"])
Docs - Variables: Prefect Variables (v3) - Secrets: Store secrets with Secret block (v3) If you literally meant “how do I load JSON in Python,” you can still use the stdlib:
Copy code
import json
data = json.loads('{"a": 1}')
Would you like help migrating any existing
JSON
block values to Variables or a Secret?
t
@Marvin Does that mean data previously saved as JSON Blocks can no longer be loaded?
m
thought for 144.6 seconds
Short answer: you can still access the data, but you can’t instantiate the removed JSON block class. - Block documents you previously saved with type slug
json
still exist in the Prefect database. - What no longer works is
JSON.load(...)
or
Block.load("json/…")
, because the JSON block class was removed in Prefect 3.x. - You can fetch the raw block document (and its data) via the Prefect client, independent of the Python class, then migrate it to a Variable or a Secret. Example: read the old JSON block and migrate its value to a Variable
Copy code
from prefect.client.orchestration import get_client
from prefect.variables import Variable

async def migrate_old_json_block(name: str, new_variable_name: str | None = None):
    new_variable_name = new_variable_name or name
    async with get_client() as client:
        # Read by name and block type slug 'json'
        block_doc = await client.read_block_document_by_name(
            name=name,
            block_type_slug="json",
            include_secrets=True,  # include the stored value
        )
        # The block's stored fields are in block_doc.data
        # For the old JSON block, the payload is typically under 'value'
        value = block_doc.data.get("value")

        # Save into a Variable (use Secret block instead if sensitive)
        await Variable.aset(new_variable_name, value, overwrite=True)
        return value
If the data is sensitive, save it to a Secret instead:
Copy code
from prefect.blocks.system import Secret

async def migrate_to_secret(name: str, secret_name: str | None = None):
    secret_name = secret_name or name
    async with get_client() as client:
        block_doc = await client.read_block_document_by_name(
            name=name, block_type_slug="json", include_secrets=True
        )
        value = block_doc.data.get("value")
        await Secret(value=value).asave(secret_name, overwrite=True)
If you’d like, share the name(s) of the JSON blocks you need to migrate and whether the contents are sensitive, and I can tailor a snippet to extract and re-save them.
😇 1