File size: 4,453 Bytes
3b993c4 49b13c6 3b993c4 c1f8477 3b993c4 49b13c6 3b993c4 9347485 3b993c4 49b13c6 3b993c4 819725d 3b993c4 9347485 3b993c4 145d03b 9347485 145d03b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
from typing import Any, List
from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic.alias_generators import to_camel
class BaseSchema(BaseModel):
model_config = ConfigDict(
alias_generator=to_camel,
populate_by_name=True,
from_attributes=True,
)
class DateComponent(BaseSchema):
"""
Represents a date component with year, month, and day.
Attributes:
year (int | None): The year component of the date.
month (int | None): The month component of the date. Defaults to None.
day (int | None): The day component of the date. Defaults to None.
"""
year: int | None = None
month: int | None = None
day: int | None = None
model_config = {"frozen": True} # This makes the model immutable and hashable
@field_validator("year", "month", "day", mode="before")
@classmethod
def zero_to_none(cls, v: int | None) -> int | None:
return None if v == 0 else v
# Function to format date components
class StartEndMixin(BaseSchema):
"""
A mixin class for including start and end dates in other Pydantic models.
This class is designed to be inherited by other classes that require start and end date attributes.
"""
start: DateComponent | None = None
end: DateComponent | None = None
@field_validator("start", "end", mode="before")
@classmethod
def validate_date(cls, v: dict[str, str] | DateComponent) -> dict[str, str] | DateComponent | None:
if isinstance(v, DateComponent):
return v
if not v or v.get("year") is None:
return None
return v
class Geo(BaseSchema):
country: str | None = None
city: str | None = None
full: str | None = None
class Language(BaseSchema):
name: str | None = None
proficiency: str | None = None
class Education(StartEndMixin):
field_of_study: str | None = None
degree: str | None = None
grade: str | None = None
school_name: str | None = None
description: str | None = None
activities: str | None = None
model_config = {"frozen": True} # This makes the model immutable and hashable
class Position(StartEndMixin):
company_name: str | None = None
company_username: str | None = None
company_url: str | None = None
company_industry: str | None = None
company_description: str | None = None
company_staff_count_range: str | None = None
title: str | None = None
location: str | None = None
description: str | None = None
employment_type: str | None = None
model_config = {"frozen": True} # This makes the model immutable and hashable
class Skill(BaseSchema):
name: str | None = None
class Course(BaseSchema):
name: str | None = None
number: str | None = None
class CertificationCompany(BaseSchema):
name: str | None = None
universal_name: str | None = None
logo: str | None = None
class Certification(StartEndMixin):
name: str | None = None
authority: str | None = None
company: CertificationCompany | None = None
time_period: StartEndMixin | None = None
class LinkedinProfile(BaseSchema):
"""
Represents a comprehensive profile, encompassing various sections such as articles,
accomplishments, experiences, education, certifications, courses, test scores,
and more personal and professional details.
"""
first_name: str | None = None
last_name: str | None = None
is_open_to_work: bool | None = None
is_hiring: bool | None = None
profile_picture: str | None = None
summary: str | None = None
headline: str | None = None
geo: Geo | None = None
languages: List[Language] | None = []
educations: List[Education] = []
positions: List[Position] = Field(default=[], alias="position")
full_positions: List[Position] = Field(default=[])
skills: List[Skill] | None = []
courses: List[Course] | None = []
certifications: List[Certification] | None = []
@staticmethod
def profile_from_json(json: dict[str, Any]) -> "LinkedinProfile":
"""
Create a Profile instance from the given JSON data.
:param json: The JSON data to create a Profile instance from.
:return: A Profile instance created from the given JSON data.
"""
profile = LinkedinProfile.model_validate(json)
profile.positions = profile.full_positions
return profile
|