Source code for nick_derobertis_site.api.routers.timeline

import datetime
from enum import Enum
from typing import List, Optional, Sequence, Union

from derobertis_cv.pldata.education import get_education
from derobertis_cv.pldata.education_model import EducationModel
from derobertis_cv.pldata.employment_model import (
    AcademicEmploymentModel,
    EmploymentModel,
)
from derobertis_cv.pldata.jobs import get_academic_jobs, get_professional_jobs
from fastapi import APIRouter
from pydantic import BaseModel

router = APIRouter()


[docs] class TimelineTypes(str, Enum): PROFESSIONAL_EMPLOYMENT = "professional employment" ACADEMIC_EMPLOYMENT = "academic employment" EDUCATION = "education"
[docs] class APITimelineModel(BaseModel): organization: str role: str location: str timeline_id: int item_type: TimelineTypes begin_date: datetime.date short_organization: str short_role: str end_date: Optional[datetime.date] = None description: Optional[Sequence[str]] = None
[docs] @classmethod def from_cv_employment( cls, model: EmploymentModel, timeline_id: int ) -> "APITimelineModel": if isinstance(model, AcademicEmploymentModel): item_type = TimelineTypes.ACADEMIC_EMPLOYMENT else: item_type = TimelineTypes.PROFESSIONAL_EMPLOYMENT return cls( organization=model.company_name, role=model.job_title, location=model.location, timeline_id=timeline_id, item_type=item_type, begin_date=model.begin_date, short_organization=model.company_short_name or model.company_name, short_role=model.short_job_title or model.job_title, end_date=model.end_date, description=model.description, )
[docs] @classmethod def from_cv_education( cls, model: EducationModel, timeline_id: int ) -> "APITimelineModel": return cls( organization=model.institution.title, role=model.degree_name, location=model.institution.location, timeline_id=timeline_id, item_type=TimelineTypes.EDUCATION, short_organization=model.institution.abbreviation or model.institution.title, short_role=model.short_degree_name or model.degree_name, begin_date=model.begin_date, end_date=model.end_date, )
[docs] @classmethod def list_from_cv_seq( cls, models: Sequence[Union[EmploymentModel, EducationModel]] ) -> List["APITimelineModel"]: api_models = [] for i, mod in enumerate(models): timeline_id = i + 1 if isinstance(mod, EducationModel): api_models.append(cls.from_cv_education(mod, timeline_id=timeline_id)) elif isinstance(mod, EmploymentModel): api_models.append(cls.from_cv_employment(mod, timeline_id=timeline_id)) else: raise ValueError( f"must pass models of type EducationModel or EmploymentModel, " f"got {mod} of type {type(mod)}" ) api_models.sort(key=lambda mod: mod.begin_date, reverse=True) return api_models
[docs] class APITimelineResponseModel(BaseModel): items: List[APITimelineModel]
[docs] class APITimelineStatisticsModel(BaseModel): count: int begin_date: datetime.date end_date: Optional[datetime.date] = None
[docs] @classmethod def from_api_timeline_models(cls, models: Sequence[APITimelineModel]): count = len(models) begin_date = min([mod.begin_date for mod in models]) end_dates = [mod.end_date for mod in models] if any([end_date is None for end_date in end_dates]): end_date = None else: end_date = max([mod.begin_date for mod in models]) return cls( count=count, begin_date=begin_date, end_date=end_date, )
[docs] class APITimelineStatisticsResponseModel(BaseModel): education: APITimelineStatisticsModel professional: APITimelineStatisticsModel academic: APITimelineStatisticsModel overall: APITimelineStatisticsModel
EDUCATION_CV_MODELS: List[EducationModel] = get_education() PROFESSIONAL_EMPLOYMENT_CV_MODELS: List[EmploymentModel] = get_professional_jobs() ACADEMIC_EMPLOYMENT_CV_MODELS: List[AcademicEmploymentModel] = get_academic_jobs() ALL_CV_MODELS = ( EDUCATION_CV_MODELS + PROFESSIONAL_EMPLOYMENT_CV_MODELS + ACADEMIC_EMPLOYMENT_CV_MODELS ) EDUCATION_TIMELINE_MODELS: List[APITimelineModel] = APITimelineModel.list_from_cv_seq( EDUCATION_CV_MODELS ) PROFESSIONAL_TIMELINE_MODELS: List[ APITimelineModel ] = APITimelineModel.list_from_cv_seq(PROFESSIONAL_EMPLOYMENT_CV_MODELS) ACADEMIC_TIMELINE_MODELS: List[APITimelineModel] = APITimelineModel.list_from_cv_seq( ACADEMIC_EMPLOYMENT_CV_MODELS ) ALL_TIMELINE_MODELS = ( EDUCATION_TIMELINE_MODELS + PROFESSIONAL_TIMELINE_MODELS + ACADEMIC_TIMELINE_MODELS ) ALL_TIMELINE_MODELS.sort(key=lambda mod: mod.begin_date, reverse=True) ALL_RESPONSE_MODEL = APITimelineResponseModel(items=ALL_TIMELINE_MODELS) STATS = APITimelineStatisticsResponseModel( education=APITimelineStatisticsModel.from_api_timeline_models( EDUCATION_TIMELINE_MODELS ), professional=APITimelineStatisticsModel.from_api_timeline_models( PROFESSIONAL_TIMELINE_MODELS ), academic=APITimelineStatisticsModel.from_api_timeline_models( ACADEMIC_TIMELINE_MODELS ), overall=APITimelineStatisticsModel.from_api_timeline_models(ALL_TIMELINE_MODELS), )
[docs] @router.get("/", tags=["timeline"], response_model=APITimelineResponseModel) async def read_all_research(): return ALL_RESPONSE_MODEL
[docs] @router.get( "/stats", tags=["timeline"], response_model=APITimelineStatisticsResponseModel, ) async def read_skill_stats(): return STATS