Search code examples
pythonpydanticpydantic-v2

How to restrict Pydantic URL validation to specific hosts or websites


I'm currently working with Pydantic's URL type for URL validation in my Python project. However, it seems that Pydantic does not currently provide a built-in mechanism for this. So what is the best approach to restrict a URL to a specific list of hosts in Pydantic?

I have a pydantic model called Media which has an url attribute. I want the url to be restricted to certain websites or hosts."

from pydantic import BaseModel, AnyUrl

class Media(BaseModel):
    url: AnyUrl # the url host should only be from x.com or y.com

Solution

  • As you already mentioned there is no built-in support for doing so. Here an AfterValidator can do the job:

    from typing import Annotated, TypeAlias
    
    from pydantic import AfterValidator, AnyUrl, BaseModel
    
    valid_hosts = {"www.google.com", "www.yahoo.com"}
    
    
    def check_specific_hosts(url: AnyUrl) -> AnyUrl:
        if url.host in valid_hosts:
            return url
        raise ValueError("It's not in the list of accepted hosts")
    
    
    AcceptedUrl: TypeAlias = Annotated[AnyUrl, AfterValidator(check_specific_hosts)]
    
    
    class Media(BaseModel):
        url: AcceptedUrl
    
    
    print(Media(url="http://www.google.com"))
    try:
        print(Media(url="http://www.facebook.com"))
    except ValueError as e:
        print(e)
    

    output:

    url=Url('http://www.google.com/')
    1 validation error for Media
    url
      Value error, It's not in the list of accepted hosts [type=value_error, input_value='http://www.facebook.com', input_type=str]
        For further information visit https://errors.pydantic.dev/2.6/v/value_error