Exemple #1
0
def _get_inventory(site: dict) -> Optional[List[location.Vaccine]]:
    name = site["name"]

    inventory = []

    pfizer = re.search("pfizer", name, re.IGNORECASE)
    moderna = re.search("moderna", name, re.IGNORECASE)
    johnson = re.search("janssen|johnson.*johnson|j&j", name, re.IGNORECASE)

    # The source only seems to list locations that have available appointment
    # times, so they most likely have stock available.
    if pfizer:
        inventory.append(
            location.Vaccine(
                vaccine=location.VaccineType.PFIZER_BIONTECH,
                supply_level=location.VaccineSupply.IN_STOCK,
            ))
    if moderna:
        inventory.append(
            location.Vaccine(
                vaccine=location.VaccineType.MODERNA,
                supply_level=location.VaccineSupply.IN_STOCK,
            ))
    if johnson:
        inventory.append(
            location.Vaccine(
                vaccine=location.VaccineType.JOHNSON_JOHNSON_JANSSEN,
                supply_level=location.VaccineSupply.IN_STOCK,
            ))

    if len(inventory) == 0:
        return None

    return inventory
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    vaccines_field = site["attributes"]["USER_VaxType"].lower().split(",")

    potentials = {
        "pfizer-biontech covid-19 vaccine": schema.Vaccine(vaccine="pfizer_biontech"),
        "moderna covid-19 vaccine": schema.Vaccine(vaccine="moderna"),
        "janssen": schema.Vaccine(vaccine="johnson_johnson_janssen"),
        "jjj": schema.Vaccine(vaccine="johnson_johnson_janssen"),
        "janssen (johnson & johnson) covid-19 vaccine": schema.Vaccine(
            vaccine="johnson_johnson_janssen"
        ),
    }

    inventory = []

    for vf in vaccines_field:
        try:
            if vf != "-" and vf != "\x08":  # "-" is listed when no data given
                inventory.append(potentials[vf])
        except KeyError as e:
            logger.error("Unexpected vaccine type: %s", e)

    if len(inventory) > 0:
        return inventory

    return None
Exemple #3
0
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    # Though the data source includes attributes for each possible vaccine, they
    # do not appear to be used every time (rather this string is typically set)
    inventory_str = site["attributes"]["vaccine_manufacturer"]

    inventory = []

    pfizer = re.search("pfizer", inventory_str, re.IGNORECASE)
    moderna = re.search("moderna", inventory_str, re.IGNORECASE)
    johnson = re.search("janssen|johnson.*johnson|j&j|j_j", inventory_str,
                        re.IGNORECASE)

    if pfizer:
        inventory.append(
            schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH))
    if moderna:
        inventory.append(schema.Vaccine(vaccine=schema.VaccineType.MODERNA))
    if johnson:
        inventory.append(
            schema.Vaccine(vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN))

    if len(inventory) == 0:
        logger.warning("No vaccines found in inventory: %s", inventory_str)
        return None

    return inventory
Exemple #4
0
def _get_inventories(site: dict) -> List[schema.Vaccine]:
    ret = []
    if "Moderna" in _get_vaccine_description(site):
        ret.append(schema.Vaccine(vaccine="moderna"))
    if "Pfizer" in _get_vaccine_description(site):
        ret.append(schema.Vaccine(vaccine="pfizer_biontech"))
    if "J&J" in _get_vaccine_description(site):
        ret.append(schema.Vaccine(vaccine="johnson_johnson_janssen"))
    return ret
Exemple #5
0
def _get_inventories(site: dict) -> List[location.Vaccine]:
    ret = []
    if "vaccine_manufacturer" in site:
        if "Moderna" in site["vaccine_manufacturer"]:
            ret.append(location.Vaccine(vaccine="moderna"))
        if "Pfizer" in site["vaccine_manufacturer"]:
            ret.append(location.Vaccine(vaccine="pfizer_biontech"))
        if "Johnson & Johnson" in site["vaccine_manufacturer"]:
            ret.append(location.Vaccine(vaccine="johnson_johnson_janssen"))
    return ret
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    inventory_str = site["attributes"]["vaccine_manufacturer"]
    inventory = (inventory_str.split(";")
                 if ";" in inventory_str else inventory_str.split(","))

    return [{
        "Pfizer_BioNTech": schema.Vaccine(vaccine="pfizer_biontech"),
        "Pfizer-BioNTech": schema.Vaccine(vaccine="pfizer_biontech"),
        "Pfizer": schema.Vaccine(vaccine="pfizer_biontech"),
        "Moderna": schema.Vaccine(vaccine="moderna"),
        "J_J": schema.Vaccine(vaccine="johnson_johnson_janssen"),
    }[vaccine.lstrip("\u200b").strip()] for vaccine in inventory]
def _get_inventories(site: dict) -> List[schema.Vaccine]:
    ret = []
    if "vaccineType" in site and site["vaccineType"]:
        if "Moderna" in site["vaccineType"]:
            ret.append(schema.Vaccine(vaccine=schema.VaccineType.MODERNA))
        if "Pfizer" in site["vaccineType"]:
            ret.append(schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH))
        if "Janssen" in site["vaccineType"]:
            ret.append(
                schema.Vaccine(vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN)
            )
    return ret
def _get_inventory(site: dict) -> List[schema.Vaccine]:
    vaccines = []

    if site["attributes"]["ServiceType_JohnsonAndJohnson"] == "Yes":
        vaccines.append(schema.Vaccine(vaccine="johnson_johnson_janssen"))

    if site["attributes"]["ServiceType_Moderna"] == "Yes":
        vaccines.append(schema.Vaccine(vaccine="moderna"))

    if site["attributes"]["ServiceType_Pfizer"] == "Yes":
        vaccines.append(schema.Vaccine(vaccine="pfizer_biontech"))

    return vaccines
Exemple #9
0
def _get_inventory(raw: str) -> Optional[List[schema.Vaccine]]:
    # we've only seen "Pfizer", but no reason not to use the rest of the
    # potentials from `ak/arcgis/normalize.py`
    potentials = {
        "pfizer": schema.Vaccine(vaccine="pfizer_biontech"),
        "moderna": schema.Vaccine(vaccine="moderna"),
        "janssen": schema.Vaccine(vaccine="johnson_johnson_janssen"),
        "jjj": schema.Vaccine(vaccine="johnson_johnson_janssen"),
    }
    try:
        return [potentials[raw.lower()]]
    except KeyError:
        logger.error(f"Unexpected vaccine brand: {raw}")
        return None
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    inventory = []
    # one site has different vaccines on different days, so we need to check
    # the hours field as well as the vaccine field
    for field in ("Vaccine", "Normal Days / Hours"):
        if re.search("pfizer", field, re.I):
            inventory.append(
                schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH))
        elif re.search("moderna", field, re.I):
            inventory.append(
                schema.Vaccine(vaccine=schema.VaccineType.MODERNA))
        elif re.search("johnson & johnson", field, re.I):
            inventory.append(
                schema.Vaccine(
                    vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN))
    return inventory or None
Exemple #11
0
def normalize(site: dict, timestamp: str) -> dict:
    links = [
        schema.Link(authority="ct_gov", id=site["_id"]),
        schema.Link(authority="ct_gov_network_id", id=site["networkId"]),
    ]

    parent_organization = schema.Organization(name=site["networks"][0]["name"])

    parsed_provider_link = provider_id_from_name(site["name"])
    if parsed_provider_link is not None:
        links.append(
            schema.Link(authority=parsed_provider_link[0], id=parsed_provider_link[1])
        )

        parent_organization.id = parsed_provider_link[0]

    return schema.NormalizedLocation(
        id=f"ct_gov:{site['_id']}",
        name=site["displayName"],
        address=schema.Address(
            street1=site["addressLine1"],
            street2=site["addressLine2"],
            city=site["city"],
            state="CT",
            zip=site["zip"],
        ),
        location=_get_lat_lng(site),
        contact=[
            schema.Contact(
                contact_type="booking", phone=site["phone"], website=site["link"]
            ),
        ],
        languages=None,
        opening_dates=None,
        opening_hours=None,
        availability=schema.Availability(
            appointments=site["availability"],
        ),
        inventory=[
            schema.Vaccine(vaccine=vaccine["name"])
            for vaccine in site["providerVaccines"]
        ],
        access=schema.Access(
            drive=site["isDriveThru"],
        ),
        parent_organization=parent_organization,
        links=links,
        notes=None,
        active=None,
        source=schema.Source(
            source="covidvaccinefinder_gov",
            id=site["_id"],
            fetched_from_uri="https://covidvaccinefinder.ct.gov/api/HttpTriggerGetProvider",  # noqa: E501
            fetched_at=timestamp,
            published_at=site["lastModified"],
            data=site,
        ),
    ).dict()
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    if site["attributes"]["V_Manufacturer"]:
        vaccines_field = map(
            lambda str: str.strip(),
            site["attributes"]["V_Manufacturer"].lower().split(","),
        )

        potentials = {
            "pzr": schema.Vaccine(vaccine="pfizer_biontech"),
            "pfr": schema.Vaccine(vaccine="pfizer_biontech"),
            "pfizer": schema.Vaccine(vaccine="pfizer_biontech"),
            "mod": schema.Vaccine(vaccine="moderna"),
            "moderna": schema.Vaccine(vaccine="moderna"),
            "jj": schema.Vaccine(vaccine="johnson_johnson_janssen"),
            "jjj": schema.Vaccine(vaccine="johnson_johnson_janssen"),
        }

        inventory = []

        for vf in vaccines_field:
            try:
                inventory.append(potentials[vf])
            except KeyError as e:
                logger.error("Unexpected vaccine type: %s", e)

        if len(inventory) > 0:
            return inventory

    return None
def _get_inventory(site: dict) -> List[schema.Vaccine]:
    vaccines = []

    for vaccine_blob in site["providerVaccines"]:
        vaccine = vaccine_blob["name"]
        if vaccine.lower() == "moderna":
            vaccines.append(
                schema.Vaccine(vaccine="moderna", supply_level="in_stock"))
        if vaccine.lower() == "pfizer":
            vaccines.append(
                schema.Vaccine(vaccine="pfizer_biontech",
                               supply_level="in_stock"))
        if vaccine.lower() == "johnson & johnson":
            vaccines.append(
                schema.Vaccine(vaccine="johnson_johnson_janssen",
                               supply_level="in_stock"))

    return vaccines
Exemple #14
0
def _get_vaccine(site: dict) -> List[schema.Vaccine]:
    vaccine_string = site["vaccine"].lower()

    vaccines = []

    if "moderna" in vaccine_string:
        vaccines.append(schema.Vaccine(vaccine=schema.VaccineType.MODERNA))
    if "pfizer" in vaccine_string:
        vaccines.append(
            schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH))
    if "johnson" in vaccine_string:
        vaccines.append(
            schema.Vaccine(vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN))
    if "oxford" in vaccine_string:
        vaccines.append(
            schema.Vaccine(vaccine=schema.VaccineType.OXFORD_ASTRAZENECA))

    return vaccines
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    # This is just a guess.
    vaccines = []

    if "j" in site["vaccines"]:
        vaccines.append(
            schema.Vaccine(vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN))

    if "m" in site["vaccines"]:
        vaccines.append(schema.Vaccine(vaccine=schema.VaccineType.MODERNA))

    if "p" in site["vaccines"]:
        vaccines.append(
            schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH))

    if len(vaccines) > 0:
        return vaccines

    return None
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    vaccines = site["attributes"]["Vaccine_Type"]

    inventory = []

    pfizer = re.search("pfizer", vaccines, re.IGNORECASE)
    moderna = re.search("moderna", vaccines, re.IGNORECASE)
    johnson = re.search("janssen", vaccines, re.IGNORECASE) or re.search(
        "johnson", vaccines, re.IGNORECASE)

    if pfizer:
        inventory.append(schema.Vaccine(vaccine="pfizer_biontech"))
    if moderna:
        inventory.append(schema.Vaccine(vaccine="moderna"))
    if johnson:
        inventory.append(schema.Vaccine(vaccine="johnson_johnson_janssen"))

    if len(inventory) == 0:
        return None

    return inventory
Exemple #17
0
def _get_inventory(site: dict) -> List[schema.Vaccine]:
    name = site["Title"]

    inventory = []

    pfizer = re.search("pfizer", name, re.IGNORECASE)
    moderna = re.search("moderna", name, re.IGNORECASE)
    johnson = re.search("janssen", name, re.IGNORECASE) or re.search(
        "johnson", name, re.IGNORECASE)

    if pfizer:
        inventory.append(schema.Vaccine(vaccine="pfizer_biontech"))
    elif moderna:
        inventory.append(schema.Vaccine(vaccine="moderna"))
    elif johnson:
        inventory.append(schema.Vaccine(vaccine="johnson_johnson_janssen"))

    if len(inventory) == 0:
        return None

    return inventory
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    vaccines = []

    if "ExtendedData" in site:
        have_moderna = site["_folder_name"] == "Moderna"
        have_pfizer = site["_folder_name"] == "Pfizer"
        for field in ["Description", "Mapped Description", "unnamed (1)"]:
            if field in site["ExtendedData"]:
                if "moderna" in site["ExtendedData"][field].lower():
                    have_moderna = True
                if "pfizer" in site["ExtendedData"][field].lower():
                    have_pfizer = True
        if have_moderna:
            vaccines.append(schema.Vaccine(vaccine=schema.VaccineType.MODERNA))
        if have_pfizer:
            vaccines.append(
                schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH))

    if len(vaccines) > 0:
        return vaccines

    return None
Exemple #19
0
def _get_inventory(site: dict) -> Optional[List[schema.Vaccine]]:
    vaccine_names = [
        ("pfizer", schema.VaccineType.PFIZER_BIONTECH),
        ("moderna", schema.VaccineType.MODERNA),
        ("jjj", schema.VaccineType.JOHNSON_JOHNSON_JANSSEN),
    ]

    ret = []
    for their_name, our_name in vaccine_names:
        if their_name in site["attributes"]["flu_vaccinations"]:
            ret.append(schema.Vaccine(vaccine=our_name))

    return ret
def _get_inventory(site: dict) -> List[schema.Vaccine]:
    vaccines = site["vaccines"]

    inventory = []

    pfizer = re.search("pfizer", vaccines, re.IGNORECASE)
    moderna = re.search("moderna", vaccines, re.IGNORECASE)
    johnson = re.search("janssen", vaccines, re.IGNORECASE) or re.search(
        "johnson", vaccines, re.IGNORECASE)

    # some clinics specified all 3 vaccines but stated that they'll be given based on what's available.
    if pfizer:
        inventory.append(schema.Vaccine(vaccine="pfizer_biontech"))
    if moderna:
        inventory.append(schema.Vaccine(vaccine="moderna"))
    if johnson:
        inventory.append(schema.Vaccine(vaccine="johnson_johnson_janssen"))

    if len(inventory) == 0:
        return None

    return inventory
Exemple #21
0
def normalize(site: dict, timestamp: str) -> schema.NormalizedLocation:
    source_name = SOURCE_NAME

    # NOTE: we use `get` where the field is optional in our data source, and
    # ["key'] access where it is not.
    return schema.NormalizedLocation(
        id=f"{source_name}:{_get_id(site)}",
        name=site["locationName"],
        address=schema.Address(
            street1=site.get("addressLine1"),
            street2=site.get("addressLine2"),
            city=site.get("city"),
            state=_get_state(site),
            zip=_get_good_zip(site),
        ),
        location=schema.LatLng(latitude=site["latitude"], longitude=site["longitude"]),
        contact=_get_contacts(site),
        notes=site.get("description"),
        # Since this could be nullable we make sure to only provide it if it's True or False
        availability=schema.Availability(drop_in=site.get("walkIn"))
        if site.get("walkIn") is not None
        else None,
        access=schema.Access(
            walk=site.get("walkupSite"),
            drive=site.get("driveupSite"),
            wheelchair=_get_wheelchair(site),
        ),
        # IF supply_level is UNKNOWN, don't say anything about it
        inventory=[
            schema.Vaccine(
                vaccine=_get_vaccine_type(vaccine), supply_level=_get_supply_level(site)
            )
            for vaccine in site["vaccineTypes"]
            if _get_vaccine_type(vaccine) is not None
        ]
        if _get_supply_level(site)
        else None,
        parent_organization=schema.Organization(
            id=site.get("providerId"), name=site.get("providerName")
        ),
        source=schema.Source(
            source=source_name,
            id=site["locationId"],
            fetched_from_uri="https://apim-vaccs-prod.azure-api.net/web/graphql",
            fetched_at=timestamp,
            published_at=site["updatedAt"],
            data=site,
        ),
    )
Exemple #22
0
def _get_inventories(site: dict):
    ret = []
    if site["Moderna"] == "Y":
        ret.append(schema.Vaccine(vaccine="moderna", supply_level="in_stock"))
    if site["Pfizer"] == "Y":
        ret.append(
            schema.Vaccine(vaccine="pfizer_biontech", supply_level="in_stock"))
    if site["Janssen"] == "Y":
        ret.append(
            schema.Vaccine(vaccine="johnson_johnson_janssen",
                           supply_level="in_stock"))
    if site["Moderna"] == "N":
        ret.append(
            schema.Vaccine(vaccine="moderna", supply_level="out_of_stock"))
    if site["Pfizer"] == "N":
        ret.append(
            schema.Vaccine(vaccine="pfizer_biontech",
                           supply_level="out_of_stock"))
    if site["Janssen"] == "N":
        ret.append(
            schema.Vaccine(vaccine="johnson_johnson_janssen",
                           supply_level="out_of_stock"))
    return ret
def test_valid_location():
    # Minimal record
    assert location.NormalizedLocation(
        id="source:id",
        source=location.Source(
            source="source",
            id="id",
            data={"id": "id"},
        ),
    )

    # Full record with str enums
    full_loc = location.NormalizedLocation(
        id="source:id",
        name="name",
        address=location.Address(
            street1="1991 Mountain Boulevard",
            street2="#1",
            city="Oakland",
            state="CA",
            zip="94611",
        ),
        location=location.LatLng(
            latitude=37.8273167,
            longitude=-122.2105179,
        ),
        contact=[
            location.Contact(
                contact_type="booking",
                phone="(916) 445-2841",
            )
        ],
        languages=["en"],
        opening_dates=[
            location.OpenDate(
                opens="2021-04-01",
                closes="2021-04-01",
            ),
        ],
        opening_hours=[
            location.OpenHour(
                day="monday",
                opens="08:00",
                closes="14:00",
            ),
        ],
        availability=location.Availability(
            drop_in=False,
            appointments=True,
        ),
        inventory=[
            location.Vaccine(
                vaccine="moderna",
                supply_level="in_stock",
            ),
        ],
        access=location.Access(
            walk=True,
            drive=False,
            wheelchair="partial",
        ),
        parent_organization=location.Organization(
            id="rite_aid",
            name="Rite Aid",
        ),
        links=[
            location.Link(
                authority="google_places",
                id="abc123",
            ),
        ],
        notes=["note"],
        active=True,
        source=location.Source(
            source="source",
            id="id",
            fetched_from_uri="https://example.org",
            fetched_at="2020-04-04T04:04:04.4444",
            published_at="2020-04-04T04:04:04.4444",
            data={"id": "id"},
        ),
    )
    assert full_loc

    # Verify dict serde
    full_loc_dict = full_loc.dict()
    assert full_loc_dict

    parsed_full_loc = location.NormalizedLocation.parse_obj(full_loc_dict)
    assert parsed_full_loc

    assert parsed_full_loc == full_loc

    # Verify json serde
    full_loc_json = full_loc.json()
    assert full_loc_json

    parsed_full_loc = location.NormalizedLocation.parse_raw(full_loc_json)
    assert parsed_full_loc

    assert parsed_full_loc == full_loc

    # Verify dict->json serde
    full_loc_json_dumps = json.dumps(full_loc_dict)
    assert full_loc_json_dumps

    assert full_loc_json_dumps == full_loc_json

    parsed_full_loc = location.NormalizedLocation.parse_raw(
        full_loc_json_dumps)
    assert parsed_full_loc

    assert parsed_full_loc == full_loc
Exemple #24
0
def full_location():
    return location.NormalizedLocation(
        id="source:dad13365-2202-4dea-9b37-535288b524fe",
        name="Rite Aid Pharmacy 5952",
        address=location.Address(
            street1="1991 Mountain Boulevard",
            city="Oakland",
            state="CA",
            zip="94611",
        ),
        location=location.LatLng(
            latitude=37.8273167,
            longitude=-122.2105179,
        ),
        contact=[
            location.Contact(
                contact_type=location.ContactType.BOOKING,
                phone="(916) 445-2841",
            ),
            location.Contact(
                contact_type=location.ContactType.GENERAL,
                phone="(510) 339-2215",
            ),
        ],
        languages=["en"],
        opening_dates=[
            location.OpenDate(
                opens="2021-04-01",
                closes="2021-04-01",
            ),
        ],
        opening_hours=[
            location.OpenHour(
                day=location.DayOfWeek.MONDAY,
                opens="08:00",
                closes="14:00",
            ),
        ],
        availability=location.Availability(
            drop_in=False,
            appointments=True,
        ),
        inventory=[
            location.Vaccine(
                vaccine=location.VaccineType.MODERNA,
                supply_level=location.VaccineSupply.IN_STOCK,
            ),
        ],
        access=location.Access(
            walk=True,
            drive=False,
            wheelchair=location.WheelchairAccessLevel.PARTIAL,
        ),
        parent_organization=location.Organization(
            id=location.VaccineProvider.RITE_AID,
            name="Rite Aid Pharmacy",
        ),
        links=[
            location.Link(
                authority=location.LocationAuthority.GOOGLE_PLACES,
                id="ChIJA0MOOYWHj4ARW8M-vrC9yGA",
            ),
        ],
        notes=["long note goes here"],
        active=True,
        source=location.Source(
            source="source",
            id="dad13365-2202-4dea-9b37-535288b524fe",
            fetched_from_uri="https://example.org",
            fetched_at="2020-04-04T04:04:04.4444",
            published_at="2020-04-04T04:04:04.4444",
            data={"id": "dad13365-2202-4dea-9b37-535288b524fe"},
        ),
    )
Exemple #25
0
import re
import sys
from typing import List, Optional

from vaccine_feed_ingest_schema import location as schema

from vaccine_feed_ingest.utils.log import getLogger
from vaccine_feed_ingest.utils.normalize import normalize_phone

logger = getLogger(__file__)

SOURCE_NAME = "tx_arcgis"

VACCINES_FIELD = {
    "JJ_AVAILABLE":
    schema.Vaccine(vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN),
    "JJ_AVAILABLE2":
    schema.Vaccine(vaccine=schema.VaccineType.JOHNSON_JOHNSON_JANSSEN),
    "MODERNA_AVAILABLE":
    schema.Vaccine(vaccine=schema.VaccineType.MODERNA),
    "MODERNA_AVAILABLE2":
    schema.Vaccine(vaccine=schema.VaccineType.MODERNA),
    "PFIZER_AVAILABLE":
    schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH),
    "PFIZER_AVAILABLE2":
    schema.Vaccine(vaccine=schema.VaccineType.PFIZER_BIONTECH),
}


def _get_availability(site: dict) -> schema.Availability:
    for field in VACCINES_FIELD.keys():
def _get_inventory(loc: GMVLocation) -> Optional[List[location.Vaccine]]:
    if not loc.availability:
        return None

    vaccines = set()
    for product in loc.availability.products or []:
        if vaccine_type := VACCINE_MAPPING.get(product):
            vaccines.add(vaccine_type)
        else:
            logger.info("Unrecognized vaccine for product %s", product)

    if not vaccines:
        return None

    return [location.Vaccine(vaccine=vaccine) for vaccine in vaccines]


def _get_parent_organization(
        loc: GMVLocation) -> Optional[location.Organization]:
    provider = PROVIDER_MAPPING.get(loc.provider)

    if not provider:
        return None

    return location.Organization(id=provider)


def _get_links(loc: GMVLocation) -> Optional[List[location.Link]]:
    if not loc.external_ids:
        return None