<@ULVA73B9P> Besides UI, what are the ways to crea...
# marvin-ai
p
@Marvin Besides UI, what are the ways to create new blocks in prefect v3 ?
m
thought for 96.6 seconds
Here are the main ways you can create blocks in Prefect 3.x besides using the UI: 1. Using Python SDK (Most Common):
Copy code
python
from prefect.blocks.system import String

# Create and save a block
string_block = String(value="my-string-value")
string_block.save(name="my-string-block", overwrite=True)
2. Using CLI Commands: - Register blocks from a module:
Copy code
bash
prefect block register -m prefect.blocks.notifications
- List available blocks:
Copy code
bash
prefect block ls
3. Using PrefectClient:
Copy code
python
from prefect.client import get_client

async with get_client() as client:
    # Create a block document
    block_document = await client.create_block_document(
        block_type_slug="string",
        name="my-block",
        data={"value": "my-string-value"}
    )
4. Loading Existing Blocks:
Copy code
python
from prefect.blocks.system import String

# Load an existing block
my_block = String.load("my-string-block")
For more detailed information about blocks and their creation methods, you can refer to the Prefect Blocks documentation. A few important notes: - When saving blocks, using
overwrite=True
will update an existing block with the same name - Block names must be unique within their block type - Some blocks require additional configuration or credentials, which can be provided during creation - Custom block types can be created by extending the
Block
class and then registered using any of these methods Would you like me to elaborate on any of these methods or provide more specific examples for a particular block type?
p
@Marvin Is there a known issue where prefect 3.3.4 doesn't install all dependencies accordingly? I'm having a problem with referencing
m
thought for 20.2 seconds
Based on my research, there isn't a widely reported issue with Prefect 3.3.4 not installing dependencies correctly. However, to help diagnose your specific problem: 1. Could you share: - The exact error message you're seeing - How you installed Prefect (pip, conda, etc.) - What specific dependencies seem to be missing - Your Python version 2. Common troubleshooting steps you can try: - Install Prefect in a fresh virtual environment:
Copy code
bash
     python -m venv venv
     source venv/bin/activate  # or `venv\Scripts\activate` on Windows
     pip install prefect==3.3.4
- If you need specific extras, install them explicitly:
Copy code
bash
     pip install "prefect[aws]==3.3.4"  # for AWS dependencies
     pip install "prefect[kubernetes]==3.3.4"  # for Kubernetes dependencies
- Verify your installation:
Copy code
bash
     pip freeze | grep prefect
     python -c "import prefect; print(prefect.__version__)"
If you can provide more details about the specific reference issues you're encountering, I can give you more targeted assistance.
p
@Marvin
Copy code
Traceback (most recent call last):
  File "/home/runner/.local/bin/prefect", line 5, in <module>
    from prefect.cli import app
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/cli/__init__.py", line 24, in <module>
    import prefect.cli.server
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/cli/server.py", line 32, in <module>
    from prefect.server.services.base import Service
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/__init__.py", line 1, in <module>
    from . import models, orchestration, schemas, services
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/models/__init__.py", line 1, in <module>
    from . import (
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/models/artifacts.py", line 9, in <module>
    from prefect.server.database import PrefectDBInterface, db_injector, orm_models
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/database/__init__.py", line 6, in <module>
    from prefect.server.database.interface import PrefectDBInterface
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/database/interface.py", line 9, in <module>
    from prefect.server.database import orm_models
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/database/orm_models.py", line 26, in <module>
    from prefect.server.events.actions import ServerActionTypes
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/server/events/actions.py", line 85, in <module>
    from prefect.utilities.schema_tools.hydration import (
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/utilities/schema_tools/__init__.py", line 2, in <module>
    from .validation import (
  File "/home/runner/.local/lib/python3.12/site-packages/prefect/utilities/schema_tools/validation.py", line 9, in <module>
    from referencing.jsonschema import ObjectSchema, Schema
ModuleNotFoundError: No module named 'referencing'
Installed prefect with
pip install prefect==3.3.4
on a github ci/cd pipeline.
m
thought for 11.6 seconds
This is a known issue that was recently reported. The
referencing
package is a dependency that's required but not properly included in the installation requirements for Prefect 3.3.4. Here's how to fix it: 1. Add the missing dependency explicitly to your CI/CD pipeline:
Copy code
bash
pip install prefect==3.3.4 referencing
Or alternatively, you can create a
requirements.txt
file with:
Copy code
prefect==3.3.4
referencing>=0.30.0
The issue occurs because Prefect 3.3.4 uses the
referencing
package for JSON Schema handling but doesn't explicitly list it in its dependencies. This has been reported and should be fixed in future versions. For your CI/CD pipeline, I recommend pinning both versions to ensure reproducibility:
Copy code
bash
pip install prefect==3.3.4 referencing==0.30.2
Would you like me to provide any additional context about setting up Prefect in CI/CD environments or handling dependencies?
p
@Marvin Thank you. Is there a way to retrieve the list of existing secrets with python sdk?
m
thought for 40.6 seconds
Yes, you can list existing secrets using the Prefect Python SDK. Here's how to do it:
Copy code
python
from prefect.client import get_client

async with get_client() as client:
    # Get all block documents including secrets
    block_documents = await client.read_block_documents(
        block_type_slug="secret",
        include_secrets=True
    )
    
    # List the secret names
    secret_names = [doc.name for doc in block_documents]
If you need a synchronous version:
Copy code
python
import asyncio
from prefect.client import get_client

def get_secret_names():
    async def _get_secrets():
        async with get_client() as client:
            block_documents = await client.read_block_documents(
                block_type_slug="secret",
                include_secrets=True
            )
            return [doc.name for doc in block_documents]
    
    return asyncio.run(_get_secrets())

# Use it
secret_names = get_secret_names()
A few important notes: - The
include_secrets=True
parameter is important as it ensures secret blocks are included in the response - By default, this will return all secrets accessible to your current workspace - The actual secret values are not included in the response for security reasons - to access a specific secret's value, you'll need to load it separately using
Secret.load(name)
Would you like me to show you how to work with specific secrets once you have their names?
p
@Marvin And how can I delete a secret with python sdk?
m
thought for 115.5 seconds
You can delete a secret using the Prefect client's
delete_block_document
method. Here's how to do it:
Copy code
python
from prefect.client import get_client

async with get_client() as client:
    # Delete a secret by name
    await client.delete_block_document(
        block_type_slug="secret",
        name="your-secret-name"
    )
If you need a synchronous version:
Copy code
python
import asyncio
from prefect.client import get_client

def delete_secret(secret_name: str):
    async def _delete_secret():
        async with get_client() as client:
            await client.delete_block_document(
                block_type_slug="secret",
                name=secret_name
            )
    
    return asyncio.run(_delete_secret())

# Use it
delete_secret("your-secret-name")
Important notes: - Make sure you have the correct permissions to delete secrets in your workspace - The deletion is permanent and cannot be undone - If the secret doesn't exist, the operation will raise an exception - You might want to verify the secret exists before attempting to delete it Would you like me to show you how to combine this with the earlier code to verify a secret exists before deleting it?
p
@Marvin Actually that function needs the id of the secret. Is there a way to get the id if I have the name?
m
thought for 10.1 seconds
Yes, you can get the secret's ID using its name. Here's how:
Copy code
python
from prefect.client import get_client

async with get_client() as client:
    # Get block document by name
    block_documents = await client.read_block_documents(
        block_type_slug="secret",
        include_secrets=True,
        name="your-secret-name"  # Filter by name
    )
    
    if block_documents:
        secret_id = block_documents[0].id
        # Now delete using the ID
        await client.delete_block_document(
            block_document_id=secret_id
        )
Here's a complete synchronous version that handles both finding and deleting the secret:
Copy code
python
import asyncio
from prefect.client import get_client

def delete_secret_by_name(secret_name: str):
    async def _delete_secret():
        async with get_client() as client:
            # First get the secret's ID
            block_documents = await client.read_block_documents(
                block_type_slug="secret",
                include_secrets=True,
                name=secret_name
            )
            
            if not block_documents:
                raise ValueError(f"No secret found with name: {secret_name}")
            
            secret_id = block_documents[0].id
            
            # Delete using the ID
            await client.delete_block_document(
                block_document_id=secret_id
            )
            return True
    
    return asyncio.run(_delete_secret())

# Use it
try:
    delete_secret_by_name("your-secret-name")
    print("Secret deleted successfully")
except ValueError as e:
    print(f"Error: {e}")
This code will: 1. Look up the secret by name 2. Get its ID from the returned document 3. Use that ID to delete the secret 4. Raise a helpful error if the secret isn't found Would you like me to show you how to add any additional error handling or verification steps?