Prefect blocks store configuration and provide an interface for interacting with external systems.
Blocks expose methods that provide functionality specific to the systems they interface with.
For example, blocks can be used to download data from or upload data to an S3 bucket, query data from or write data to a database, or send a message to a Slack channel.
Block types are Python classes with a handy UI webform for configuration.
Blocks are instantiation of these classes with specific values.
Configure blocks through Python code or via a form in the UI.
Access blocks for use in Python code.
Block values are stored in Prefect Cloud or your self-hosted Prefect server instance.
Blocks can be shared with other users in your Prefect Cloud workspace.
To see block types available for configuration, use prefect block type ls from the CLI or navigate to the Blocks page in the UI and click +.
Blocks and parameters
Blocks are useful for configuration that needs to be shared across flow runs and between flows.
For configuration that will change between flow runs, we recommend using parameters.
The S3, Azure, GCS, and GitHub blocks are deprecated in favor of the the corresponding S3Bucket, AzureBlobStorageCredentials, GCSBucket, and GitHubRepository blocks found in the Prefect integration libraries.
Some block types that appear in the UI can be created immediately, and then the corresponding integration library must be installed for use.
For example, an AWS Secret block can be created, but not used until the prefect-aws library is installed.
Block types can be created by anyone and optionally shared with the community.
You'll find block types available for consumption in many of the published Prefect integrations libraries.
If a block type is not available in the UI, you can register it via the CLI.
To create a custom block type, define a class that subclasses Block. The Block base class builds on Pydantic's BaseModel, so custom blocks can be declared in the same manner as a Pydantic model.
Here's a block that represents a cube and holds information about the length of each edge in inches:
You can include methods on a block to provide functionality. Here's the same cube block with methods to calculate the volume and surface area of the cube:
All block values are encrypted before being stored.
If you have values that you would not like visible in the UI or in logs, use the SecretStr field type provided by Pydantic to automatically obfuscate those values.
This functionality can be useful for fields that are used to store credentials such as passwords and API tokens.
Here's an example of an AWSCredentials block that uses SecretStr:
fromtypingimportOptionalfromprefect.blocks.coreimportBlockfrompydanticimportSecretStr# if pydantic version >= 2.0, use: from pydantic.v1 import SecretStrclassAWSCredentials(Block):aws_access_key_id:Optional[str]=Noneaws_secret_access_key:Optional[SecretStr]=Noneaws_session_token:Optional[str]=Noneprofile_name:Optional[str]=Noneregion_name:Optional[str]=None
Because aws_secret_access_key has the SecretStr type hint assigned to it, the value of that field will not be exposed if the object is logged:
Prefect's SecretDict field type allows you to add a dictionary field to your block that will have values at all levels automatically obfuscated in the UI or in logs.
This functionality is useful for blocks where typing or structure of secret fields is not known until configuration time.
Here's an example of a block that uses SecretDict:
Blocks are composable - a block can be used within other blocks.
You can create a block type that uses functionality from another block type by declaring it as an attribute.
Nestable blocks are loosely coupled, as configuration can be changed for each block independently. This allows configuration to be shared across multiple use cases.
To illustrate, here's a an expanded AWSCredentials block that includes the ability to get an authenticated session via the boto3 library:
Saving block values like this links the values of the two blocks so that any changes to the values stored for the AWSCredentials block with the name my_aws_credentials will be seen the next time that block values for the S3Bucket block named my_s3_bucket is loaded.
Values for nested blocks can also be hard coded by not first saving child blocks:
Let's add a bucket_folder field to your custom S3Bucket block that represents the default path to read and write objects from (this field exists on our implementation).
If you have any existing blocks of this type that were created before the update and you'd prefer to not re-create them, migrate them to the new version of your block type by adding the missing values:
# Bypass Pydantic validation to allow your local Block class to load the old block versionmy_s3_bucket_block=S3Bucket.load("my-s3-bucket",validate=False)# Set the new field to an appropriate valuemy_s3_bucket_block.bucket_path="my-default-bucket-path"# Overwrite the old block values and update the expected fields on the blockmy_s3_bucket_block.save("my-s3-bucket",overwrite=True)