lodstorage.sample2 — pyLoDStorage documentation

# Source code for lodstorage.sample2

    """
    Created on 2024-01-21

    @author: wf
    """
    import json
    from dataclasses import field
    from datetime import date, datetime
    from typing import List, Optional
    from slugify import slugify
    from lodstorage.yamlable import DateConvert, lod_storable

    @lod_storable
    class Royal:
        """
        Represents a member of the royal family, with various personal details.

        Attributes:
            name (str): The full name of the royal member.
            wikidata_id (str): The Wikidata identifier associated with the royal member.
            number_in_line (Optional[int]): The number in line to succession, if applicable.
            born_iso_date (Optional[str]): The ISO date of birth.
            died_iso_date (Optional[str]): The ISO date of death, if deceased.
            last_modified_iso (str): ISO timestamp of the last modification.
            age (Optional[int]): The age of the royal member.
            of_age (Optional[bool]): Indicates whether the member is of legal age.
            wikidata_url (Optional[str]): URL to the Wikidata page of the member.
        """
        name: str
        wikidata_id: str
        number_in_line: Optional[int] = None
        born_iso_date: Optional[str] = None
        died_iso_date: Optional[str] = None
        last_modified_iso: str = field(init=False)
        age: Optional[int] = field(init=None)
        of_age: Optional[bool] = field(init=None)
        wikidata_url: Optional[str] = field(init=None)

        def __post_init__(self):
            """
            init calculated fields
            """
            self.lastmodified = datetime.utcnow()
            self.last_modified_iso = self.lastmodified.strftime("%Y-%m-%dT%H:%M:%SZ")
            end_date = self.died if self.died else date.today()
            self.age = int((end_date - self.born).days / 365.2425)
            self.of_age = self.age >= 18
            if self.wikidata_id:
                self.wikidata_url = f"https://www.wikidata.org/wiki/{self.wikidata_id}"

        @property
        def identifier(self)->str:
            """
            Generates a unique identifier for the Royal instance.
            The identifier is a combination of a slugified name and the Wikidata ID (if available).
            """
            slugified_name = slugify(self.name, lowercase=False, regex_pattern=r'[^\w\-]')
            if self.wikidata_id:
                return f"{slugified_name}-{self.wikidata_id}"
            return slugified_name

        @property
        def born(self) -> date:
            """Return the date of birth from the ISO date string."""
            born_date = DateConvert.iso_date_to_datetime(self.born_iso_date)
            return born_date

        @property
        def died(self) -> Optional[date]:
            """Return the date of death from the ISO date string, if available."""
            died_date = DateConvert.iso_date_to_datetime(self.died_iso_date)
            return died_date

    @lod_storable
    class Royals:
        """
        Represents a collection of Royal family members.

        Attributes:
            members (List[Royal]): A list of Royal family members.
        """

        members: List[Royal] = field(default_factory=list)

        @classmethod
        def get_samples(cls) -> dict[str, "Royals"]:
            """
            Returns a dictionary of named samples
            for 'specification by example' style
            requirements management.

            Returns:
                dict: A dictionary with keys as sample names and values as `Royals` instances.
            """
            samples = {
                "QE2 heirs up to number in line 5": Royals(
                    members=[
                        Royal(
                            name="Elizabeth Alexandra Mary Windsor",
                            born_iso_date="1926-04-21",
                            died_iso_date="2022-09-08",
                            wikidata_id="Q9682",
                        ),
                        Royal(
                            name="Charles III of the United Kingdom",
                            born_iso_date="1948-11-14",
                            number_in_line=0,
                            wikidata_id="Q43274",
                        ),
                        Royal(
                            name="William, Duke of Cambridge",
                            born_iso_date="1982-06-21",
                            number_in_line=1,
                            wikidata_id="Q36812",
                        ),
                        Royal(
                            name="Prince George of Wales",
                            born_iso_date="2013-07-22",
                            number_in_line=2,
                            wikidata_id="Q13590412",
                        ),
                        Royal(
                            name="Princess Charlotte of Wales",
                            born_iso_date="2015-05-02",
                            number_in_line=3,
                            wikidata_id="Q18002970",
                        ),
                        Royal(
                            name="Prince Louis of Wales",
                            born_iso_date="2018-04-23",
                            number_in_line=4,
                            wikidata_id="Q38668629",
                        ),
                        Royal(
                            name="Harry Duke of Sussex",
                            born_iso_date="1984-09-15",
                            number_in_line=5,
                            wikidata_id="Q152316",
                        ),
                    ]
                )
            }
            return samples

    @lod_storable
    class Country:
        """
        Represents a country with its details.

        Attributes:
            name (str): The name of the country.
            country_code (str): The country code.
            capital (Optional[str]): The capital city of the country.
            timezones (List[str]): List of timezones in the country.
            latlng (List[float]): Latitude and longitude of the country.
        """

        name: str
        country_code: str
        capital: Optional[str] = None
        timezones: List[str] = field(default_factory=list)
        latlng: List[float] = field(default_factory=list)

    @lod_storable
    class Countries:
        """
        Represents a collection of country instances.

        Attributes:
            countries (List[Country]): A list of Country instances.
        """

        countries: List[Country]

        @classmethod
        def get_countries_erdem(cls) -> "Countries":
            """
            get Erdem Ozkol's country list
            """
            countries_json_url = "https://gist.githubusercontent.com/erdem/8c7d26765831d0f9a8c62f02782ae00d/raw/248037cd701af0a4957cce340dabb0fd04e38f4c/countries.json"
            json_str = cls.read_from_url(countries_json_url)
            countries_list = json.loads(json_str)
            countries_dict = {"countries": countries_list}
            instance = cls.from_dict(countries_dict)
            return instance

        @classmethod
        def get_samples(cls) -> dict[str, "Countries"]:
            """
            Returns a dictionary of named samples
            for 'specification by example' style
            requirements management.

            Returns:
                dict: A dictionary with keys as sample names
                and values as `Countries` instances.
            """
            samples = {"country list provided by Erdem Ozkol": cls.get_countries_erdem()}
            return samples

    class Sample:
        """
        Sample dataset provider
        """

        @staticmethod
        def get(dataset_name: str):
            """
            Get the given sample dataset name
            """
            samples = None
            if dataset_name == "royals":
                samples = Royals.get_samples()
            elif dataset_name == "countries":
                samples = Countries.get_samples()
            else:
                raise ValueError("Unknown dataset name")
            return samples