From 5779e3e50f3b5cf852b9d9e0fba913c9d9b8c630 Mon Sep 17 00:00:00 2001 From: Marc Kelechava Date: Tue, 18 Nov 2025 14:50:34 -0800 Subject: [PATCH] Create a carousel to move Cookbook Templates onto Discover Page (#4023) --- .../routes/discover/WorkflowTemplateCard.tsx | 2 +- .../src/routes/discover/WorkflowTemplates.tsx | 53 ++- skyvern/schemas/proxy_locations.py | 264 ------------ skyvern/schemas/runs.py | 380 ++++++------------ 4 files changed, 168 insertions(+), 531 deletions(-) delete mode 100644 skyvern/schemas/proxy_locations.py diff --git a/skyvern-frontend/src/routes/discover/WorkflowTemplateCard.tsx b/skyvern-frontend/src/routes/discover/WorkflowTemplateCard.tsx index de26e809..a7eb0de7 100644 --- a/skyvern-frontend/src/routes/discover/WorkflowTemplateCard.tsx +++ b/skyvern-frontend/src/routes/discover/WorkflowTemplateCard.tsx @@ -6,7 +6,7 @@ type Props = { function WorkflowTemplateCard({ title, image, onClick }: Props) { return ( -
+
{title}
diff --git a/skyvern-frontend/src/routes/discover/WorkflowTemplates.tsx b/skyvern-frontend/src/routes/discover/WorkflowTemplates.tsx index 409e4f02..83e432f3 100644 --- a/skyvern-frontend/src/routes/discover/WorkflowTemplates.tsx +++ b/skyvern-frontend/src/routes/discover/WorkflowTemplates.tsx @@ -4,6 +4,13 @@ import { useNavigate } from "react-router-dom"; import { WorkflowTemplateCard } from "./WorkflowTemplateCard"; import testImg from "@/assets/promptBoxBg.png"; import { TEMPORARY_TEMPLATE_IMAGES } from "./TemporaryTemplateImages"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel"; function WorkflowTemplates() { const { data: workflowTemplates, isLoading } = useGlobalWorkflowsQuery(); @@ -26,23 +33,37 @@ function WorkflowTemplates() { return (

Explore Workflows

-
- {workflowTemplates.map((workflow) => { - return ( - + + {workflowTemplates.map((workflow) => ( + { - navigate(`/workflows/${workflow.workflow_permanent_id}/debug`); - }} - /> - ); - })} -
+ className="basis-1/5 pl-6" + > + { + navigate( + `/workflows/${workflow.workflow_permanent_id}/debug`, + ); + }} + /> + + ))} + + + +
); } diff --git a/skyvern/schemas/proxy_locations.py b/skyvern/schemas/proxy_locations.py deleted file mode 100644 index 1d9ab2ab..00000000 --- a/skyvern/schemas/proxy_locations.py +++ /dev/null @@ -1,264 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING -from zoneinfo import ZoneInfo - -if TYPE_CHECKING: - from skyvern.schemas.runs import ProxyLocation - - -# Mapping derived from the IANA tz database (zone.tab). For multi-timezone -# countries we choose the primary commercial hub; Kosovo falls back to Europe/Belgrade. -RESIDENTIAL_COUNTRY_TIMEZONES: dict[str, str] = { - "AD": "Europe/Andorra", - "AE": "Asia/Dubai", - "AF": "Asia/Kabul", - "AG": "America/Antigua", - "AI": "America/Anguilla", - "AL": "Europe/Tirane", - "AM": "Asia/Yerevan", - "AO": "Africa/Luanda", - "AR": "America/Argentina/Buenos_Aires", - "AS": "Pacific/Pago_Pago", - "AT": "Europe/Vienna", - "AU": "Australia/Sydney", - "AW": "America/Aruba", - "AX": "Europe/Mariehamn", - "AZ": "Asia/Baku", - "BA": "Europe/Sarajevo", - "BB": "America/Barbados", - "BD": "Asia/Dhaka", - "BE": "Europe/Brussels", - "BF": "Africa/Ouagadougou", - "BG": "Europe/Sofia", - "BH": "Asia/Bahrain", - "BI": "Africa/Bujumbura", - "BJ": "Africa/Porto-Novo", - "BM": "Atlantic/Bermuda", - "BN": "Asia/Brunei", - "BO": "America/La_Paz", - "BQ": "America/Kralendijk", - "BR": "America/Sao_Paulo", - "BS": "America/Nassau", - "BT": "Asia/Thimphu", - "BW": "Africa/Gaborone", - "BY": "Europe/Minsk", - "BZ": "America/Belize", - "CA": "America/Toronto", - "CD": "Africa/Kinshasa", - "CF": "Africa/Bangui", - "CG": "Africa/Brazzaville", - "CH": "Europe/Zurich", - "CI": "Africa/Abidjan", - "CK": "Pacific/Rarotonga", - "CL": "America/Santiago", - "CM": "Africa/Douala", - "CN": "Asia/Shanghai", - "CO": "America/Bogota", - "CR": "America/Costa_Rica", - "CU": "America/Havana", - "CV": "Atlantic/Cape_Verde", - "CW": "America/Curacao", - "CY": "Asia/Nicosia", - "CZ": "Europe/Prague", - "DE": "Europe/Berlin", - "DJ": "Africa/Djibouti", - "DK": "Europe/Copenhagen", - "DM": "America/Dominica", - "DO": "America/Santo_Domingo", - "DZ": "Africa/Algiers", - "EC": "America/Guayaquil", - "EE": "Europe/Tallinn", - "EG": "Africa/Cairo", - "ES": "Europe/Madrid", - "ET": "Africa/Addis_Ababa", - "FI": "Europe/Helsinki", - "FJ": "Pacific/Fiji", - "FK": "Atlantic/Stanley", - "FM": "Pacific/Pohnpei", - "FO": "Atlantic/Faroe", - "FR": "Europe/Paris", - "GA": "Africa/Libreville", - "GB": "Europe/London", - "GD": "America/Grenada", - "GE": "Asia/Tbilisi", - "GF": "America/Cayenne", - "GG": "Europe/Guernsey", - "GH": "Africa/Accra", - "GI": "Europe/Gibraltar", - "GL": "America/Nuuk", - "GM": "Africa/Banjul", - "GN": "Africa/Conakry", - "GP": "America/Guadeloupe", - "GQ": "Africa/Malabo", - "GR": "Europe/Athens", - "GT": "America/Guatemala", - "GU": "Pacific/Guam", - "GW": "Africa/Bissau", - "GY": "America/Guyana", - "HK": "Asia/Hong_Kong", - "HN": "America/Tegucigalpa", - "HR": "Europe/Zagreb", - "HT": "America/Port-au-Prince", - "HU": "Europe/Budapest", - "ID": "Asia/Jakarta", - "IE": "Europe/Dublin", - "IL": "Asia/Jerusalem", - "IM": "Europe/Isle_of_Man", - "IN": "Asia/Kolkata", - "IO": "Indian/Chagos", - "IQ": "Asia/Baghdad", - "IR": "Asia/Tehran", - "IS": "Atlantic/Reykjavik", - "IT": "Europe/Rome", - "JE": "Europe/Jersey", - "JM": "America/Jamaica", - "JO": "Asia/Amman", - "JP": "Asia/Tokyo", - "KE": "Africa/Nairobi", - "KG": "Asia/Bishkek", - "KH": "Asia/Phnom_Penh", - "KI": "Pacific/Tarawa", - "KM": "Indian/Comoro", - "KN": "America/St_Kitts", - "KR": "Asia/Seoul", - "KW": "Asia/Kuwait", - "KY": "America/Cayman", - "KZ": "Asia/Almaty", - "LA": "Asia/Vientiane", - "LB": "Asia/Beirut", - "LC": "America/St_Lucia", - "LI": "Europe/Vaduz", - "LK": "Asia/Colombo", - "LR": "Africa/Monrovia", - "LS": "Africa/Maseru", - "LT": "Europe/Vilnius", - "LU": "Europe/Luxembourg", - "LV": "Europe/Riga", - "LY": "Africa/Tripoli", - "MA": "Africa/Casablanca", - "MC": "Europe/Monaco", - "MD": "Europe/Chisinau", - "ME": "Europe/Podgorica", - "MF": "America/Marigot", - "MG": "Indian/Antananarivo", - "MK": "Europe/Skopje", - "ML": "Africa/Bamako", - "MM": "Asia/Yangon", - "MN": "Asia/Ulaanbaatar", - "MO": "Asia/Macau", - "MP": "Pacific/Saipan", - "MQ": "America/Martinique", - "MR": "Africa/Nouakchott", - "MS": "America/Montserrat", - "MT": "Europe/Malta", - "MU": "Indian/Mauritius", - "MV": "Indian/Maldives", - "MW": "Africa/Blantyre", - "MX": "America/Mexico_City", - "MY": "Asia/Kuala_Lumpur", - "MZ": "Africa/Maputo", - "NA": "Africa/Windhoek", - "NC": "Pacific/Noumea", - "NE": "Africa/Niamey", - "NG": "Africa/Lagos", - "NI": "America/Managua", - "NL": "Europe/Amsterdam", - "NO": "Europe/Oslo", - "NP": "Asia/Kathmandu", - "NZ": "Pacific/Auckland", - "OM": "Asia/Muscat", - "PA": "America/Panama", - "PE": "America/Lima", - "PF": "Pacific/Tahiti", - "PG": "Pacific/Port_Moresby", - "PH": "Asia/Manila", - "PK": "Asia/Karachi", - "PL": "Europe/Warsaw", - "PM": "America/Miquelon", - "PR": "America/Puerto_Rico", - "PS": "Asia/Hebron", - "PT": "Europe/Lisbon", - "PW": "Pacific/Palau", - "PY": "America/Asuncion", - "QA": "Asia/Qatar", - "RE": "Indian/Reunion", - "RO": "Europe/Bucharest", - "RS": "Europe/Belgrade", - "RU": "Europe/Moscow", - "RW": "Africa/Kigali", - "SA": "Asia/Riyadh", - "SB": "Pacific/Guadalcanal", - "SC": "Indian/Mahe", - "SD": "Africa/Khartoum", - "SE": "Europe/Stockholm", - "SG": "Asia/Singapore", - "SI": "Europe/Ljubljana", - "SK": "Europe/Bratislava", - "SL": "Africa/Freetown", - "SM": "Europe/San_Marino", - "SN": "Africa/Dakar", - "SO": "Africa/Mogadishu", - "SR": "America/Paramaribo", - "SS": "Africa/Juba", - "ST": "Africa/Sao_Tome", - "SV": "America/El_Salvador", - "SX": "America/Lower_Princes", - "SY": "Asia/Damascus", - "SZ": "Africa/Mbabane", - "TC": "America/Grand_Turk", - "TD": "Africa/Ndjamena", - "TG": "Africa/Lome", - "TH": "Asia/Bangkok", - "TJ": "Asia/Dushanbe", - "TL": "Asia/Dili", - "TM": "Asia/Ashgabat", - "TN": "Africa/Tunis", - "TO": "Pacific/Tongatapu", - "TR": "Europe/Istanbul", - "TT": "America/Port_of_Spain", - "TW": "Asia/Taipei", - "TZ": "Africa/Dar_es_Salaam", - "UA": "Europe/Kyiv", - "UG": "Africa/Kampala", - "US": "America/New_York", - "UY": "America/Montevideo", - "UZ": "Asia/Tashkent", - "VA": "Europe/Vatican", - "VC": "America/St_Vincent", - "VE": "America/Caracas", - "VG": "America/Tortola", - "VI": "America/St_Thomas", - "VN": "Asia/Ho_Chi_Minh", - "VU": "Pacific/Efate", - "WS": "Pacific/Apia", - "XK": "Europe/Belgrade", - "YE": "Asia/Aden", - "YT": "Indian/Mayotte", - "ZA": "Africa/Johannesburg", - "ZM": "Africa/Lusaka", - "ZW": "Africa/Harare", -} - - -def build_residential_locations_by_iso(enum_cls: type[ProxyLocation]) -> dict[str, ProxyLocation]: - mapping: dict[str, ProxyLocation] = {"US": enum_cls.RESIDENTIAL} - for iso_code in sorted(RESIDENTIAL_COUNTRY_TIMEZONES): - if iso_code == "US": - continue - mapping[iso_code] = getattr(enum_cls, f"RESIDENTIAL_{iso_code}") - return mapping - - -def build_iso_by_residential_location( - residential_locations_by_iso: dict[str, ProxyLocation], -) -> dict[ProxyLocation, str]: - return {location: iso for iso, location in residential_locations_by_iso.items()} - - -def build_tzinfo_by_residential_location( - residential_locations_by_iso: dict[str, ProxyLocation], -) -> dict[ProxyLocation, ZoneInfo]: - return { - location: ZoneInfo(RESIDENTIAL_COUNTRY_TIMEZONES[iso]) for iso, location in residential_locations_by_iso.items() - } diff --git a/skyvern/schemas/runs.py b/skyvern/schemas/runs.py index fd6b7c6a..08e6d586 100644 --- a/skyvern/schemas/runs.py +++ b/skyvern/schemas/runs.py @@ -30,11 +30,6 @@ from skyvern.schemas.docs.doc_strings import ( TOTP_URL_DOC_STRING, WEBHOOK_URL_DOC_STRING, ) -from skyvern.schemas.proxy_locations import ( - build_iso_by_residential_location, - build_residential_locations_by_iso, - build_tzinfo_by_residential_location, -) from skyvern.utils.url_validators import validate_url @@ -45,236 +40,25 @@ class ProxyLocation(StrEnum): US_TX = "US-TX" US_FL = "US-FL" US_WA = "US-WA" + RESIDENTIAL_ES = "RESIDENTIAL_ES" + RESIDENTIAL_IE = "RESIDENTIAL_IE" + RESIDENTIAL_GB = "RESIDENTIAL_GB" + RESIDENTIAL_IN = "RESIDENTIAL_IN" + RESIDENTIAL_JP = "RESIDENTIAL_JP" + RESIDENTIAL_FR = "RESIDENTIAL_FR" + RESIDENTIAL_DE = "RESIDENTIAL_DE" + RESIDENTIAL_NZ = "RESIDENTIAL_NZ" + RESIDENTIAL_ZA = "RESIDENTIAL_ZA" + RESIDENTIAL_AR = "RESIDENTIAL_AR" + RESIDENTIAL_AU = "RESIDENTIAL_AU" + RESIDENTIAL_BR = "RESIDENTIAL_BR" + RESIDENTIAL_TR = "RESIDENTIAL_TR" + RESIDENTIAL_CA = "RESIDENTIAL_CA" + RESIDENTIAL_MX = "RESIDENTIAL_MX" + RESIDENTIAL_IT = "RESIDENTIAL_IT" + RESIDENTIAL_NL = "RESIDENTIAL_NL" RESIDENTIAL_ISP = "RESIDENTIAL_ISP" NONE = "NONE" - # JoinMassive residential locations - RESIDENTIAL_AD = "RESIDENTIAL_AD" - RESIDENTIAL_AE = "RESIDENTIAL_AE" - RESIDENTIAL_AF = "RESIDENTIAL_AF" - RESIDENTIAL_AG = "RESIDENTIAL_AG" - RESIDENTIAL_AI = "RESIDENTIAL_AI" - RESIDENTIAL_AL = "RESIDENTIAL_AL" - RESIDENTIAL_AM = "RESIDENTIAL_AM" - RESIDENTIAL_AO = "RESIDENTIAL_AO" - RESIDENTIAL_AR = "RESIDENTIAL_AR" - RESIDENTIAL_AS = "RESIDENTIAL_AS" - RESIDENTIAL_AT = "RESIDENTIAL_AT" - RESIDENTIAL_AU = "RESIDENTIAL_AU" - RESIDENTIAL_AW = "RESIDENTIAL_AW" - RESIDENTIAL_AX = "RESIDENTIAL_AX" - RESIDENTIAL_AZ = "RESIDENTIAL_AZ" - RESIDENTIAL_BA = "RESIDENTIAL_BA" - RESIDENTIAL_BB = "RESIDENTIAL_BB" - RESIDENTIAL_BD = "RESIDENTIAL_BD" - RESIDENTIAL_BE = "RESIDENTIAL_BE" - RESIDENTIAL_BF = "RESIDENTIAL_BF" - RESIDENTIAL_BG = "RESIDENTIAL_BG" - RESIDENTIAL_BH = "RESIDENTIAL_BH" - RESIDENTIAL_BI = "RESIDENTIAL_BI" - RESIDENTIAL_BJ = "RESIDENTIAL_BJ" - RESIDENTIAL_BM = "RESIDENTIAL_BM" - RESIDENTIAL_BN = "RESIDENTIAL_BN" - RESIDENTIAL_BO = "RESIDENTIAL_BO" - RESIDENTIAL_BQ = "RESIDENTIAL_BQ" - RESIDENTIAL_BR = "RESIDENTIAL_BR" - RESIDENTIAL_BS = "RESIDENTIAL_BS" - RESIDENTIAL_BT = "RESIDENTIAL_BT" - RESIDENTIAL_BW = "RESIDENTIAL_BW" - RESIDENTIAL_BY = "RESIDENTIAL_BY" - RESIDENTIAL_BZ = "RESIDENTIAL_BZ" - RESIDENTIAL_CA = "RESIDENTIAL_CA" - RESIDENTIAL_CD = "RESIDENTIAL_CD" - RESIDENTIAL_CF = "RESIDENTIAL_CF" - RESIDENTIAL_CG = "RESIDENTIAL_CG" - RESIDENTIAL_CH = "RESIDENTIAL_CH" - RESIDENTIAL_CI = "RESIDENTIAL_CI" - RESIDENTIAL_CK = "RESIDENTIAL_CK" - RESIDENTIAL_CL = "RESIDENTIAL_CL" - RESIDENTIAL_CM = "RESIDENTIAL_CM" - RESIDENTIAL_CN = "RESIDENTIAL_CN" - RESIDENTIAL_CO = "RESIDENTIAL_CO" - RESIDENTIAL_CR = "RESIDENTIAL_CR" - RESIDENTIAL_CU = "RESIDENTIAL_CU" - RESIDENTIAL_CV = "RESIDENTIAL_CV" - RESIDENTIAL_CW = "RESIDENTIAL_CW" - RESIDENTIAL_CY = "RESIDENTIAL_CY" - RESIDENTIAL_CZ = "RESIDENTIAL_CZ" - RESIDENTIAL_DE = "RESIDENTIAL_DE" - RESIDENTIAL_DJ = "RESIDENTIAL_DJ" - RESIDENTIAL_DK = "RESIDENTIAL_DK" - RESIDENTIAL_DM = "RESIDENTIAL_DM" - RESIDENTIAL_DO = "RESIDENTIAL_DO" - RESIDENTIAL_DZ = "RESIDENTIAL_DZ" - RESIDENTIAL_EC = "RESIDENTIAL_EC" - RESIDENTIAL_EE = "RESIDENTIAL_EE" - RESIDENTIAL_EG = "RESIDENTIAL_EG" - RESIDENTIAL_ES = "RESIDENTIAL_ES" - RESIDENTIAL_ET = "RESIDENTIAL_ET" - RESIDENTIAL_FI = "RESIDENTIAL_FI" - RESIDENTIAL_FJ = "RESIDENTIAL_FJ" - RESIDENTIAL_FK = "RESIDENTIAL_FK" - RESIDENTIAL_FM = "RESIDENTIAL_FM" - RESIDENTIAL_FO = "RESIDENTIAL_FO" - RESIDENTIAL_FR = "RESIDENTIAL_FR" - RESIDENTIAL_GA = "RESIDENTIAL_GA" - RESIDENTIAL_GB = "RESIDENTIAL_GB" - RESIDENTIAL_GD = "RESIDENTIAL_GD" - RESIDENTIAL_GE = "RESIDENTIAL_GE" - RESIDENTIAL_GF = "RESIDENTIAL_GF" - RESIDENTIAL_GG = "RESIDENTIAL_GG" - RESIDENTIAL_GH = "RESIDENTIAL_GH" - RESIDENTIAL_GI = "RESIDENTIAL_GI" - RESIDENTIAL_GL = "RESIDENTIAL_GL" - RESIDENTIAL_GM = "RESIDENTIAL_GM" - RESIDENTIAL_GN = "RESIDENTIAL_GN" - RESIDENTIAL_GP = "RESIDENTIAL_GP" - RESIDENTIAL_GQ = "RESIDENTIAL_GQ" - RESIDENTIAL_GR = "RESIDENTIAL_GR" - RESIDENTIAL_GT = "RESIDENTIAL_GT" - RESIDENTIAL_GU = "RESIDENTIAL_GU" - RESIDENTIAL_GW = "RESIDENTIAL_GW" - RESIDENTIAL_GY = "RESIDENTIAL_GY" - RESIDENTIAL_HK = "RESIDENTIAL_HK" - RESIDENTIAL_HN = "RESIDENTIAL_HN" - RESIDENTIAL_HR = "RESIDENTIAL_HR" - RESIDENTIAL_HT = "RESIDENTIAL_HT" - RESIDENTIAL_HU = "RESIDENTIAL_HU" - RESIDENTIAL_ID = "RESIDENTIAL_ID" - RESIDENTIAL_IE = "RESIDENTIAL_IE" - RESIDENTIAL_IL = "RESIDENTIAL_IL" - RESIDENTIAL_IM = "RESIDENTIAL_IM" - RESIDENTIAL_IN = "RESIDENTIAL_IN" - RESIDENTIAL_IO = "RESIDENTIAL_IO" - RESIDENTIAL_IQ = "RESIDENTIAL_IQ" - RESIDENTIAL_IR = "RESIDENTIAL_IR" - RESIDENTIAL_IS = "RESIDENTIAL_IS" - RESIDENTIAL_IT = "RESIDENTIAL_IT" - RESIDENTIAL_JE = "RESIDENTIAL_JE" - RESIDENTIAL_JM = "RESIDENTIAL_JM" - RESIDENTIAL_JO = "RESIDENTIAL_JO" - RESIDENTIAL_JP = "RESIDENTIAL_JP" - RESIDENTIAL_KE = "RESIDENTIAL_KE" - RESIDENTIAL_KG = "RESIDENTIAL_KG" - RESIDENTIAL_KH = "RESIDENTIAL_KH" - RESIDENTIAL_KI = "RESIDENTIAL_KI" - RESIDENTIAL_KM = "RESIDENTIAL_KM" - RESIDENTIAL_KN = "RESIDENTIAL_KN" - RESIDENTIAL_KR = "RESIDENTIAL_KR" - RESIDENTIAL_KW = "RESIDENTIAL_KW" - RESIDENTIAL_KY = "RESIDENTIAL_KY" - RESIDENTIAL_KZ = "RESIDENTIAL_KZ" - RESIDENTIAL_LA = "RESIDENTIAL_LA" - RESIDENTIAL_LB = "RESIDENTIAL_LB" - RESIDENTIAL_LC = "RESIDENTIAL_LC" - RESIDENTIAL_LI = "RESIDENTIAL_LI" - RESIDENTIAL_LK = "RESIDENTIAL_LK" - RESIDENTIAL_LR = "RESIDENTIAL_LR" - RESIDENTIAL_LS = "RESIDENTIAL_LS" - RESIDENTIAL_LT = "RESIDENTIAL_LT" - RESIDENTIAL_LU = "RESIDENTIAL_LU" - RESIDENTIAL_LV = "RESIDENTIAL_LV" - RESIDENTIAL_LY = "RESIDENTIAL_LY" - RESIDENTIAL_MA = "RESIDENTIAL_MA" - RESIDENTIAL_MC = "RESIDENTIAL_MC" - RESIDENTIAL_MD = "RESIDENTIAL_MD" - RESIDENTIAL_ME = "RESIDENTIAL_ME" - RESIDENTIAL_MF = "RESIDENTIAL_MF" - RESIDENTIAL_MG = "RESIDENTIAL_MG" - RESIDENTIAL_MK = "RESIDENTIAL_MK" - RESIDENTIAL_ML = "RESIDENTIAL_ML" - RESIDENTIAL_MM = "RESIDENTIAL_MM" - RESIDENTIAL_MN = "RESIDENTIAL_MN" - RESIDENTIAL_MO = "RESIDENTIAL_MO" - RESIDENTIAL_MP = "RESIDENTIAL_MP" - RESIDENTIAL_MQ = "RESIDENTIAL_MQ" - RESIDENTIAL_MR = "RESIDENTIAL_MR" - RESIDENTIAL_MS = "RESIDENTIAL_MS" - RESIDENTIAL_MT = "RESIDENTIAL_MT" - RESIDENTIAL_MU = "RESIDENTIAL_MU" - RESIDENTIAL_MV = "RESIDENTIAL_MV" - RESIDENTIAL_MW = "RESIDENTIAL_MW" - RESIDENTIAL_MX = "RESIDENTIAL_MX" - RESIDENTIAL_MY = "RESIDENTIAL_MY" - RESIDENTIAL_MZ = "RESIDENTIAL_MZ" - RESIDENTIAL_NA = "RESIDENTIAL_NA" - RESIDENTIAL_NC = "RESIDENTIAL_NC" - RESIDENTIAL_NE = "RESIDENTIAL_NE" - RESIDENTIAL_NG = "RESIDENTIAL_NG" - RESIDENTIAL_NI = "RESIDENTIAL_NI" - RESIDENTIAL_NL = "RESIDENTIAL_NL" - RESIDENTIAL_NO = "RESIDENTIAL_NO" - RESIDENTIAL_NP = "RESIDENTIAL_NP" - RESIDENTIAL_NZ = "RESIDENTIAL_NZ" - RESIDENTIAL_OM = "RESIDENTIAL_OM" - RESIDENTIAL_PA = "RESIDENTIAL_PA" - RESIDENTIAL_PE = "RESIDENTIAL_PE" - RESIDENTIAL_PF = "RESIDENTIAL_PF" - RESIDENTIAL_PG = "RESIDENTIAL_PG" - RESIDENTIAL_PH = "RESIDENTIAL_PH" - RESIDENTIAL_PK = "RESIDENTIAL_PK" - RESIDENTIAL_PL = "RESIDENTIAL_PL" - RESIDENTIAL_PM = "RESIDENTIAL_PM" - RESIDENTIAL_PR = "RESIDENTIAL_PR" - RESIDENTIAL_PS = "RESIDENTIAL_PS" - RESIDENTIAL_PT = "RESIDENTIAL_PT" - RESIDENTIAL_PW = "RESIDENTIAL_PW" - RESIDENTIAL_PY = "RESIDENTIAL_PY" - RESIDENTIAL_QA = "RESIDENTIAL_QA" - RESIDENTIAL_RE = "RESIDENTIAL_RE" - RESIDENTIAL_RO = "RESIDENTIAL_RO" - RESIDENTIAL_RS = "RESIDENTIAL_RS" - RESIDENTIAL_RU = "RESIDENTIAL_RU" - RESIDENTIAL_RW = "RESIDENTIAL_RW" - RESIDENTIAL_SA = "RESIDENTIAL_SA" - RESIDENTIAL_SB = "RESIDENTIAL_SB" - RESIDENTIAL_SC = "RESIDENTIAL_SC" - RESIDENTIAL_SD = "RESIDENTIAL_SD" - RESIDENTIAL_SE = "RESIDENTIAL_SE" - RESIDENTIAL_SG = "RESIDENTIAL_SG" - RESIDENTIAL_SI = "RESIDENTIAL_SI" - RESIDENTIAL_SK = "RESIDENTIAL_SK" - RESIDENTIAL_SL = "RESIDENTIAL_SL" - RESIDENTIAL_SM = "RESIDENTIAL_SM" - RESIDENTIAL_SN = "RESIDENTIAL_SN" - RESIDENTIAL_SO = "RESIDENTIAL_SO" - RESIDENTIAL_SR = "RESIDENTIAL_SR" - RESIDENTIAL_SS = "RESIDENTIAL_SS" - RESIDENTIAL_ST = "RESIDENTIAL_ST" - RESIDENTIAL_SV = "RESIDENTIAL_SV" - RESIDENTIAL_SX = "RESIDENTIAL_SX" - RESIDENTIAL_SY = "RESIDENTIAL_SY" - RESIDENTIAL_SZ = "RESIDENTIAL_SZ" - RESIDENTIAL_TC = "RESIDENTIAL_TC" - RESIDENTIAL_TD = "RESIDENTIAL_TD" - RESIDENTIAL_TG = "RESIDENTIAL_TG" - RESIDENTIAL_TH = "RESIDENTIAL_TH" - RESIDENTIAL_TJ = "RESIDENTIAL_TJ" - RESIDENTIAL_TL = "RESIDENTIAL_TL" - RESIDENTIAL_TM = "RESIDENTIAL_TM" - RESIDENTIAL_TN = "RESIDENTIAL_TN" - RESIDENTIAL_TO = "RESIDENTIAL_TO" - RESIDENTIAL_TR = "RESIDENTIAL_TR" - RESIDENTIAL_TT = "RESIDENTIAL_TT" - RESIDENTIAL_TW = "RESIDENTIAL_TW" - RESIDENTIAL_TZ = "RESIDENTIAL_TZ" - RESIDENTIAL_UA = "RESIDENTIAL_UA" - RESIDENTIAL_UG = "RESIDENTIAL_UG" - RESIDENTIAL_UY = "RESIDENTIAL_UY" - RESIDENTIAL_UZ = "RESIDENTIAL_UZ" - RESIDENTIAL_VA = "RESIDENTIAL_VA" - RESIDENTIAL_VC = "RESIDENTIAL_VC" - RESIDENTIAL_VE = "RESIDENTIAL_VE" - RESIDENTIAL_VG = "RESIDENTIAL_VG" - RESIDENTIAL_VI = "RESIDENTIAL_VI" - RESIDENTIAL_VN = "RESIDENTIAL_VN" - RESIDENTIAL_VU = "RESIDENTIAL_VU" - RESIDENTIAL_WS = "RESIDENTIAL_WS" - RESIDENTIAL_XK = "RESIDENTIAL_XK" - RESIDENTIAL_YE = "RESIDENTIAL_YE" - RESIDENTIAL_YT = "RESIDENTIAL_YT" - RESIDENTIAL_ZA = "RESIDENTIAL_ZA" - RESIDENTIAL_ZM = "RESIDENTIAL_ZM" - RESIDENTIAL_ZW = "RESIDENTIAL_ZW" @staticmethod def get_zone(proxy_location: ProxyLocation) -> str: @@ -292,25 +76,74 @@ class ProxyLocation(StrEnum): @classmethod def residential_country_locations(cls) -> set[ProxyLocation]: - return set(_RESIDENTIAL_LOCATIONS_BY_ISO.values()) + return { + cls.RESIDENTIAL, + cls.RESIDENTIAL_ES, + cls.RESIDENTIAL_IE, + cls.RESIDENTIAL_GB, + cls.RESIDENTIAL_IN, + cls.RESIDENTIAL_JP, + cls.RESIDENTIAL_FR, + cls.RESIDENTIAL_DE, + cls.RESIDENTIAL_NZ, + cls.RESIDENTIAL_ZA, + cls.RESIDENTIAL_AR, + cls.RESIDENTIAL_AU, + cls.RESIDENTIAL_BR, + cls.RESIDENTIAL_TR, + cls.RESIDENTIAL_CA, + cls.RESIDENTIAL_MX, + cls.RESIDENTIAL_IT, + cls.RESIDENTIAL_NL, + } @staticmethod def get_proxy_count(proxy_location: ProxyLocation) -> int: - iso_code = _ISO_BY_RESIDENTIAL_LOCATION.get(proxy_location) - if iso_code == "US": - return 10000 - if iso_code is not None: - return 2000 - return 10000 + counts = { + ProxyLocation.RESIDENTIAL: 10000, + ProxyLocation.RESIDENTIAL_ES: 2000, + ProxyLocation.RESIDENTIAL_IE: 2000, + ProxyLocation.RESIDENTIAL_GB: 2000, + ProxyLocation.RESIDENTIAL_IN: 2000, + ProxyLocation.RESIDENTIAL_JP: 2000, + ProxyLocation.RESIDENTIAL_FR: 2000, + ProxyLocation.RESIDENTIAL_DE: 2000, + ProxyLocation.RESIDENTIAL_NZ: 2000, + ProxyLocation.RESIDENTIAL_ZA: 2000, + ProxyLocation.RESIDENTIAL_AR: 2000, + ProxyLocation.RESIDENTIAL_AU: 2000, + ProxyLocation.RESIDENTIAL_BR: 2000, + ProxyLocation.RESIDENTIAL_TR: 2000, + ProxyLocation.RESIDENTIAL_CA: 2000, + ProxyLocation.RESIDENTIAL_MX: 2000, + ProxyLocation.RESIDENTIAL_IT: 2000, + ProxyLocation.RESIDENTIAL_NL: 2000, + } + return counts.get(proxy_location, 10000) @staticmethod def get_country_code(proxy_location: ProxyLocation) -> str: - return _ISO_BY_RESIDENTIAL_LOCATION.get(proxy_location, "US") - - -_RESIDENTIAL_LOCATIONS_BY_ISO = build_residential_locations_by_iso(ProxyLocation) -_ISO_BY_RESIDENTIAL_LOCATION = build_iso_by_residential_location(_RESIDENTIAL_LOCATIONS_BY_ISO) -_TZINFO_BY_RESIDENTIAL_LOCATION = build_tzinfo_by_residential_location(_RESIDENTIAL_LOCATIONS_BY_ISO) + mapping = { + ProxyLocation.RESIDENTIAL: "US", + ProxyLocation.RESIDENTIAL_ES: "ES", + ProxyLocation.RESIDENTIAL_IE: "IE", + ProxyLocation.RESIDENTIAL_GB: "GB", + ProxyLocation.RESIDENTIAL_IN: "IN", + ProxyLocation.RESIDENTIAL_JP: "JP", + ProxyLocation.RESIDENTIAL_FR: "FR", + ProxyLocation.RESIDENTIAL_DE: "DE", + ProxyLocation.RESIDENTIAL_NZ: "NZ", + ProxyLocation.RESIDENTIAL_ZA: "ZA", + ProxyLocation.RESIDENTIAL_AR: "AR", + ProxyLocation.RESIDENTIAL_AU: "AU", + ProxyLocation.RESIDENTIAL_BR: "BR", + ProxyLocation.RESIDENTIAL_TR: "TR", + ProxyLocation.RESIDENTIAL_CA: "CA", + ProxyLocation.RESIDENTIAL_MX: "MX", + ProxyLocation.RESIDENTIAL_IT: "IT", + ProxyLocation.RESIDENTIAL_NL: "NL", + } + return mapping.get(proxy_location, "US") def get_tzinfo_from_proxy(proxy_location: ProxyLocation) -> ZoneInfo | None: @@ -335,13 +168,60 @@ def get_tzinfo_from_proxy(proxy_location: ProxyLocation) -> ZoneInfo | None: if proxy_location == ProxyLocation.RESIDENTIAL: return ZoneInfo("America/New_York") + if proxy_location == ProxyLocation.RESIDENTIAL_ES: + return ZoneInfo("Europe/Madrid") + + if proxy_location == ProxyLocation.RESIDENTIAL_IE: + return ZoneInfo("Europe/Dublin") + + if proxy_location == ProxyLocation.RESIDENTIAL_GB: + return ZoneInfo("Europe/London") + + if proxy_location == ProxyLocation.RESIDENTIAL_IN: + return ZoneInfo("Asia/Kolkata") + + if proxy_location == ProxyLocation.RESIDENTIAL_JP: + return ZoneInfo("Asia/Tokyo") + + if proxy_location == ProxyLocation.RESIDENTIAL_FR: + return ZoneInfo("Europe/Paris") + + if proxy_location == ProxyLocation.RESIDENTIAL_DE: + return ZoneInfo("Europe/Berlin") + + if proxy_location == ProxyLocation.RESIDENTIAL_NZ: + return ZoneInfo("Pacific/Auckland") + + if proxy_location == ProxyLocation.RESIDENTIAL_ZA: + return ZoneInfo("Africa/Johannesburg") + + if proxy_location == ProxyLocation.RESIDENTIAL_AR: + return ZoneInfo("America/Argentina/Buenos_Aires") + + if proxy_location == ProxyLocation.RESIDENTIAL_AU: + return ZoneInfo("Australia/Sydney") + + if proxy_location == ProxyLocation.RESIDENTIAL_BR: + return ZoneInfo("America/Sao_Paulo") + + if proxy_location == ProxyLocation.RESIDENTIAL_TR: + return ZoneInfo("Europe/Istanbul") + + if proxy_location == ProxyLocation.RESIDENTIAL_CA: + return ZoneInfo("America/Toronto") + + if proxy_location == ProxyLocation.RESIDENTIAL_MX: + return ZoneInfo("America/Mexico_City") + + if proxy_location == ProxyLocation.RESIDENTIAL_IT: + return ZoneInfo("Europe/Rome") + + if proxy_location == ProxyLocation.RESIDENTIAL_NL: + return ZoneInfo("Europe/Amsterdam") + if proxy_location == ProxyLocation.RESIDENTIAL_ISP: return ZoneInfo("America/New_York") - tzinfo = _TZINFO_BY_RESIDENTIAL_LOCATION.get(proxy_location) - if tzinfo is not None: - return tzinfo - return None