Mohit Singhal
04/23/2024, 11:08 AMarbitrary_types_allowed
in Config
we are managing our dependencies using pypoetry.tomlMarvin
04/23/2024, 11:08 AMRuntimeError
encountered with Pydantic and the arbitrary_types_allowed
configuration when using Prefect 2.14.20 and Pydantic 2.7.0. However, I will try searching for more specific issues regarding Prefect's compatibility with Pydantic on GitHub to see if this is a known issue. Please wait while I perform the search.
It seems there are a couple of relevant issues and discussions on GitHub regarding Prefect and Pydantic that might be related to the problem you are encountering:
1. There is an issue related to the SecretStr
type from Pydantic where using Pydantic version 2 causes a RuntimeError
with the message "no validator found for <class 'pydantic.types.SecretStr'>, see arbitrary_types_allowed in Config"
. The suggested change is to use from pydantic.v1 import SecretStr
when Pydantic version 2 or greater is in use.
2. Another pull request mentions a change to Prefect's validation configuration to include arbitrary_types_allowed
, to allow non-Pydantic classes to be used as type annotations without raising a RuntimeError
.
It appears that some issues arise when using Python types as type hints with newer versions of Pydantic and the Prefect library. The solutions generally point towards fine-tuning Pydantic configuration to work around these validation-related errors.
For now, you might want to consider checking your Pydantic usage within Prefect flows and tasks and adjust it according to the above suggestions. For long-term compatibility, you may need to keep track of updates and fixes to these issues in the Prefect repository. Meanwhile, ensure that your pyproject.toml
reflects the correct dependency versions to avoid unexpected upgrades with tools like poetry
or pip
.Alexander Azzam
04/23/2024, 11:40 AMfrom pydantic.v1 import SecretStr
@Mohit SinghalMohit Singhal
04/23/2024, 11:40 AMMohit Singhal
04/23/2024, 11:41 AMAlexander Azzam
04/23/2024, 11:41 AMMohit Singhal
04/23/2024, 11:41 AMAlexander Azzam
04/23/2024, 11:41 AMMohit Singhal
04/23/2024, 11:41 AMAlexander Azzam
04/23/2024, 11:42 AMMohit Singhal
04/23/2024, 11:42 AMAlexander Azzam
04/23/2024, 11:45 AMMohit Singhal
04/23/2024, 11:58 AMAlexander Azzam
04/23/2024, 12:17 PMMohit Singhal
04/23/2024, 12:20 PMMohit Singhal
04/23/2024, 12:20 PMNate
04/23/2024, 12:21 PMMohit Singhal
04/23/2024, 12:21 PMarbitrary_types_allowed
in Config')
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see arbitrary_types_allowed
in ConfigNate
04/23/2024, 12:21 PMMohit Singhal
04/23/2024, 12:22 PMMohit Singhal
04/23/2024, 12:22 PMarbitrary_types_allowed
in Config')
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see arbitrary_types_allowed
in ConfigMohit Singhal
04/23/2024, 12:27 PMNate
04/23/2024, 12:27 PMSecretStr
on a pydantic v1 BaseModel
are you subclassing SlackCredentials
?Mohit Singhal
04/23/2024, 12:32 PMMohit Singhal
04/23/2024, 12:32 PMAlexander Azzam
04/23/2024, 12:34 PMMohit Singhal
04/23/2024, 12:38 PMMohit Singhal
04/23/2024, 12:39 PMAlexander Azzam
04/23/2024, 12:39 PMMohit Singhal
04/23/2024, 12:39 PMMohit Singhal
04/23/2024, 12:40 PMAlexander Azzam
04/23/2024, 12:40 PMMohit Singhal
04/23/2024, 12:41 PMMohit Singhal
04/23/2024, 12:48 PMMohit Singhal
04/23/2024, 12:48 PMMohit Singhal
04/23/2024, 12:49 PMMohit Singhal
04/23/2024, 12:50 PMMohit Singhal
04/23/2024, 12:51 PMMohit Singhal
04/23/2024, 12:53 PMAlexander Azzam
04/23/2024, 12:54 PMRan Tibi
07/07/2024, 1:33 PMfrom motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
from prefect.blocks.core import Block
from pydantic import SecretStr, Field
from typing import Optional
class MongoDBConnection(Block):
host: str = Field(default="localhost", description="MongoDB host")
port: int = Field(default=27017, description="MongoDB port")
username: Optional[str] = Field(default=None, description="MongoDB username")
password: Optional[SecretStr] = Field(default=None, description="MongoDB password")
database: str = Field(..., description="MongoDB database name")
auth_source: Optional[str] = Field(default="admin", description="Authentication database")
tls: bool = Field(default=False, description="Use TLS/SSL for connection")
def get_client(self) -> AsyncIOMotorDatabase:
# Construct the connection URI
if self.username and self.password:
uri = f"mongodb://{self.username}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}"
else:
uri = f"mongodb://{self.host}:{self.port}/{self.database}"
# Add additional options
uri += f"?authSource={self.auth_source}"
if self.tls:
uri += "&tls=true"
# Create the client
client = AsyncIOMotorClient(uri)
return client.get_database(self.database)
class Config:
block_type_name = "MongoDB Connection"
block_schema_capabilities = ["connection"]
And then to register it this way:
prefect block register --file blocks/mongodb_block.py
But I am getting the same error as in this thread:
Script at 'blocks/mongodb_block.py' encountered an exception: RuntimeError("no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config")
Traceback (most recent call last):
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/Users/ran/medorion/prefect_poc/prefect_flows/blocks/mongodb_block.py", line 7, in <module>
class MongoDBConnection(Block):
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/main.py", line 197, in __new__
fields = ModelField.infer(
^^^^^^^^^^^^^^^^^
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 504, in infer
return cls(
^^^^
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 434, in __init__
self.prepare()
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 555, in prepare
self.populate_validators()
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 829, in populate_validators
*(get_validators() if get_validators else list(find_validators(self.type_, self.model_config))),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/validators.py", line 765, in find_validators
raise RuntimeError(f'no validator found for {type_}, see `arbitrary_types_allowed` in Config')
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config
Unable to load file at blocks/mongodb_block.py. Please make sure the file path is correct and the file contains valid Python.
(venv) ran@MedOrion-Rans-MacBook-Pro-2 prefect_flows % prefect block register --file blocks/mongodb_block.py
Script at 'blocks/mongodb_block.py' encountered an exception: RuntimeError("no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config")
Traceback (most recent call last):
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/Users/ran/medorion/prefect_poc/prefect_flows/blocks/mongodb_block.py", line 7, in <module>
class MongoDBConnection(Block):
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/main.py", line 197, in __new__
fields = ModelField.infer(
^^^^^^^^^^^^^^^^^
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 504, in infer
return cls(
^^^^
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 434, in __init__
self.prepare()
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 555, in prepare
self.populate_validators()
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/fields.py", line 829, in populate_validators
*(get_validators() if get_validators else list(find_validators(self.type_, self.model_config))),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/validators.py", line 765, in find_validators
raise RuntimeError(f'no validator found for {type_}, see `arbitrary_types_allowed` in Config')
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config
Marvin
07/07/2024, 1:33 PMIs there anything new with this thread?I tried to create the following custom block: ```from motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient from prefect.blocks.core import Block from pydantic import SecretStr, Field from typing import Optional class MongoDBConnection(Block): host: str = Field(default="localhost", description="MongoDB host") port: int = Field(default=27017, description="MongoDB port") username: Optional[str] = Field(default=None, description="MongoDB username") password: Optional[SecretStr] = Field(default=None, description="MongoDB password") database: str = Field(..., description="MongoDB database name") auth_source: Optional[str] = Field(default="admin", description="Authentication database") tls: bool = Field(default=False, description="Use TLS/SSL for connection") def get_client(self) -> AsyncIOMotorDatabase: # Construct the connection URI if self.username and self.password: uri = f"mongodb//{self.username}{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}" else: uri = f"mongodb//{self.host}{self.port}/{self.database}" # Add additional options uri += f"?authSource={self.auth_source}" if self.tls: uri += "&tls=true" # Create the
Ran Tibi
07/07/2024, 1:35 PMfrom motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
from prefect.blocks.core import Block
from pydantic import SecretStr, Field
from typing import Optional
class MongoDBConnection(Block):
host: str = Field(default="localhost", description="MongoDB host")
port: int = Field(default=27017, description="MongoDB port")
username: Optional[str] = Field(default=None, description="MongoDB username")
password: Optional[SecretStr] = Field(default=None, description="MongoDB password")
database: str = Field(..., description="MongoDB database name")
auth_source: Optional[str] = Field(default="admin", description="Authentication database")
tls: bool = Field(default=False, description="Use TLS/SSL for connection")
def get_client(self) -> AsyncIOMotorDatabase:
# Construct the connection URI
if self.username and self.password:
uri = f"mongodb://{self.username}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}"
else:
uri = f"mongodb://{self.host}:{self.port}/{self.database}"
# Add additional options
uri += f"?authSource={self.auth_source}"
if self.tls:
uri += "&tls=true"
# Create the client
client = AsyncIOMotorClient(uri)
return client.get_database(self.database)
class Config:
block_type_name = "MongoDB Connection"
block_schema_capabilities = ["connection"]
And then to register it this way:
prefect block register --file blocks/mongodb_block.py
But I am getting the same error as in this thread:
File "/Users/ran/medorion/prefect_poc/venv/lib/python3.11/site-packages/pydantic/v1/validators.py", line 765, in find_validators
raise RuntimeError(f'no validator found for {type_}, see `arbitrary_types_allowed` in Config')
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config
Marvin
07/07/2024, 1:35 PMIs there anything new with this thread?I tried to create the following custom block: ```from motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient from prefect.blocks.core import Block from pydantic import SecretStr, Field from typing import Optional class MongoDBConnection(Block): host: str = Field(default="localhost", description="MongoDB host") port: int = Field(default=27017, description="MongoDB port") username: Optional[str] = Field(default=None, description="MongoDB username") password: Optional[SecretStr] = Field(default=None, description="MongoDB password") database: str = Field(..., description="MongoDB database name") auth_source: Optional[str] = Field(default="admin", description="Authentication database") tls: bool = Field(default=False, description="Use TLS/SSL for connection") def get_client(self) -> AsyncIOMotorDatabase: # Construct the connection URI if self.username and self.password: uri = f"mongodb//{self.username}{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}" else: uri = f"mongodb//{self.host}{self.port}/{self.database}" # Add additional options uri += f"?authSource={self.auth_source}" if self.tls: uri += "&tls=true" # Create the
Ran Tibi
07/07/2024, 1:38 PMfrom motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
from prefect.blocks.core import Block
from pydantic import SecretStr, Field
from typing import Optional
class MongoDBConnection(Block):
host: str = Field()
port: int = Field()
username: Optional[str] = Field()
password: Optional[SecretStr] = Field()
database: str = Field()
auth_source: Optional[str] = Field()
def get_client(self) -> AsyncIOMotorDatabase:
if self.username and self.password:
uri = f"mongodb://{self.username}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}"
else:
uri = f"mongodb://{self.host}:{self.port}/{self.database}"
uri += f"?authSource={self.auth_source}"
client = AsyncIOMotorClient(uri)
return client.get_database(self.database)
class Config:
block_type_name = "MongoDB Connection"
block_schema_capabilities = ["connection"]
And then :
prefect block register --file blocks/mongodb_block.py
But I am getting the same error as in this thread:
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config
Marvin
07/07/2024, 1:38 PMIs there anything new with this thread?I tried to create the following custom block:
from motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
from prefect.blocks.core import Block
from pydantic import SecretStr, Field
from typing import Optional
class MongoDBConnection(Block):
host: str = Field()
port: int = Field()
username: Optional[str] = Field()
password: Optional[SecretStr] = Field()
database: str = Field()
auth_source: Optional[str] = Field()
def get_client(self) -> AsyncIOMotorDatabase:
if self.username and self.password:
uri = f"mongodb://{self.username}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}"
else:
uri = f"mongodb://{self.host}:{self.port}/{self.database}"
uri += f"?authSource={self.auth_source}"
client = AsyncIOMotorClient(uri)
return client.get_database(self.database)
class Config:
block_type_name = "MongoDB Connection"
block_schema_capabilities = ["connection"]
And then :
prefect block register --file blocks/mongodb_block.py
But I am getting the same error as in this thread:
```RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_typesRan Tibi
07/07/2024, 1:39 PMfrom motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
from prefect.blocks.core import Block
from pydantic import SecretStr, Field
from typing import Optional
class MongoDBConnection(Block):
host: str = Field()
port: int = Field()
username: Optional[str] = Field()
password: Optional[SecretStr] = Field()
database: str = Field()
auth_source: Optional[str] = Field()
def get_client(self) -> AsyncIOMotorDatabase:
if self.username and self.password:
uri = f"mongodb://{self.username}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}"
else:
uri = f"mongodb://{self.host}:{self.port}/{self.database}"
uri += f"?authSource={self.auth_source}"
client = AsyncIOMotorClient(uri)
return client.get_database(self.database)
class Config:
block_type_name = "MongoDB Connection"
block_schema_capabilities = ["connection"]
then:
prefect block register --file blocks/mongodb_block.py
I am getting the same error:
RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see `arbitrary_types_allowed` in Config
Marvin
07/07/2024, 1:39 PMRuntimeError
due to SecretStr
in Pydantic v2 has been identified and discussed in the Prefect community. Here are the key points and suggestions:
1. Issue with SecretStr
in Pydantic v2:
- The problem stems from Pydantic v2, where importing SecretStr
directly as from pydantic import SecretStr
leads to the error RuntimeError: no validator found for <class 'pydantic.types.SecretStr'>, see arbitrary_types_allowed in Config
.
- Suggested fix: Use from pydantic.v1 import SecretStr
when using Pydantic version >= 2.
2. Adjusting the Pydantic Configuration:
- Prefect has discussed this issue and suggested ensuring the Pydantic configuration includes arbitrary_types_allowed
to handle arbitrary types without causing validation errors.
To resolve the issue in your block definition, you should modify your import statement for SecretStr
when using Pydantic v2. Here’s an updated version of your MongoDBConnection block:
python
from motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
from prefect.blocks.core import Block
from pydantic.v1 import SecretStr, Field # Updated import for SecretStr
from typing import Optional
class MongoDBConnection(Block):
host: str = Field()
port: int = Field()
username: Optional[str] = Field()
password: Optional[SecretStr] = Field()
database: str = Field()
auth_source: Optional[str] = Field()
def get_client(self) -> AsyncIOMotorDatabase:
if self.username and self.password:
uri = f"mongodb://{self.username}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.database}"
else:
uri = f"mongodb://{self.host}:{self.port}/{self.database}"
if self.auth_source:
uri += f"?authSource={self.auth_source}"
client = AsyncIOMotorClient(uri)
return client.get_database(self.database)
class Config:
block_type_name = "MongoDB Connection"
block_schema_capabilities = ["connection"]
# Register the updated block
prefect block register --file blocks/mongodb_block.py
By updating the import statement to from pydantic.v1 import SecretStr
, you can avoid the validator error. Ensure that Pydantic v1 compatibility is available when using Pydantic v2 in your project.
Let me know if this resolves your issue or if you need further assistance.