Skip to content

social_network

available_social_networks = get_args(SocialNetworkName.__value__) module-attribute

url_dictionary = {'LinkedIn': 'https://linkedin.com/in/', 'GitHub': 'https://github.com/', 'GitLab': 'https://gitlab.com/', 'IMDB': 'https://imdb.com/name/', 'Instagram': 'https://instagram.com/', 'ORCID': 'https://orcid.org/', 'StackOverflow': 'https://stackoverflow.com/users/', 'ResearchGate': 'https://researchgate.net/profile/', 'YouTube': 'https://youtube.com/@', 'Google Scholar': 'https://scholar.google.com/citations?user=', 'Telegram': 'https://t.me/', 'WhatsApp': 'https://wa.me/', 'Leetcode': 'https://leetcode.com/u/', 'X': 'https://x.com/'} module-attribute

url_validator = pydantic.TypeAdapter(pydantic.HttpUrl) module-attribute

SocialNetworkName = Literal['LinkedIn', 'GitHub', 'GitLab', 'IMDB', 'Instagram', 'ORCID', 'Mastodon', 'StackOverflow', 'ResearchGate', 'YouTube', 'Google Scholar', 'Telegram', 'WhatsApp', 'Leetcode', 'X']

SocialNetwork

Bases: BaseModelWithoutExtraKeys

model_config = pydantic.ConfigDict(extra='forbid', validate_default=True) class-attribute instance-attribute

network = pydantic.Field() class-attribute instance-attribute

url cached property

Generate profile URL from network and username.

Why

Users provide network+username for brevity. Property generates full URLs with platform-specific logic (e.g., Mastodon domain extraction).

Returns:

  • str

    Complete profile URL.

username = pydantic.Field(examples=['john_doe', '@johndoe@mastodon.social', '12345/john-doe']) class-attribute instance-attribute

check_username(username, info) classmethod

Validate username format per network's requirements.

Why

Different platforms have specific username formats (e.g., Mastodon needs @user@domain, StackOverflow needs id/name). Early validation prevents broken URL generation.

Parameters:

  • username (str) –

    Username to validate.

  • info (ValidationInfo) –

    Validation context containing network field.

Returns:

  • str

    Validated username.

Source code in src/rendercv/schema/models/cv/social_network.py
@pydantic.field_validator("username")
@classmethod
def check_username(cls, username: str, info: pydantic.ValidationInfo) -> str:
    """Validate username format per network's requirements.

    Why:
        Different platforms have specific username formats (e.g., Mastodon needs
        @user@domain, StackOverflow needs id/name). Early validation prevents
        broken URL generation.

    Args:
        username: Username to validate.
        info: Validation context containing network field.

    Returns:
        Validated username.
    """
    if "network" not in info.data:
        # the network is either not provided or not one of the available social
        # networks. In this case, don't check the username, since Pydantic will
        # raise an error for the network.
        return username

    network = info.data["network"]

    match network:
        case "Mastodon":
            mastodon_username_pattern = r"@[^@]+@[^@]+"
            if not re.fullmatch(mastodon_username_pattern, username):
                raise pydantic_core.PydanticCustomError(
                    CustomPydanticErrorTypes.other.value,
                    'Mastodon username should be in the format "@username@domain".',
                )
        case "StackOverflow":
            stackoverflow_username_pattern = r"\d+\/[^\/]+"
            if not re.fullmatch(stackoverflow_username_pattern, username):
                raise pydantic_core.PydanticCustomError(
                    CustomPydanticErrorTypes.other.value,
                    "StackOverflow username should be in the format"
                    ' "user_id/username".',
                )
        case "YouTube":
            if username.startswith("@"):
                raise pydantic_core.PydanticCustomError(
                    CustomPydanticErrorTypes.other.value,
                    'YouTube username should not start with "@". Remove "@" from'
                    ' the beginning of the username."',
                )
        case "ORCID":
            orcid_username_pattern = r"\d{4}-\d{4}-\d{4}-\d{3}[\dX]"
            if not re.fullmatch(orcid_username_pattern, username):
                raise pydantic_core.PydanticCustomError(
                    CustomPydanticErrorTypes.other.value,
                    "ORCID username should be in the format 'XXXX-XXXX-XXXX-XXX'.",
                )
        case "IMDB":
            imdb_username_pattern = r"nm\d{7}"
            if not re.fullmatch(imdb_username_pattern, username):
                raise pydantic_core.PydanticCustomError(
                    CustomPydanticErrorTypes.other.value,
                    "IMDB name should be in the format 'nmXXXXXXX'.",
                )

        case "WhatsApp":
            phone_validator = pydantic.TypeAdapter(
                pydantic_phone_numbers.PhoneNumber
            )
            try:
                phone_validator.validate_python(username)
            except pydantic.ValidationError as e:
                raise pydantic_core.PydanticCustomError(
                    CustomPydanticErrorTypes.other.value,
                    "WhatsApp username should be your phone number with country"
                    " code in international format (e.g., +1 for USA, +44 for UK).",
                ) from e

    return username

validate_generated_url()

Validate generated URL is well-formed.

Why

URL generation from username might produce invalid URLs if username format is wrong. Post-validation check catches edge cases.

Returns:

Source code in src/rendercv/schema/models/cv/social_network.py
@pydantic.model_validator(mode="after")
def validate_generated_url(self) -> "SocialNetwork":
    """Validate generated URL is well-formed.

    Why:
        URL generation from username might produce invalid URLs if username
        format is wrong. Post-validation check catches edge cases.

    Returns:
        Validated social network instance.
    """
    url_validator.validate_strings(self.url)
    return self