From d3e365a51b0c9085967ff4e0bd1841e75af6a163 Mon Sep 17 00:00:00 2001 From: Kirill Chernakov Date: Tue, 19 Nov 2024 12:30:44 +0400 Subject: [PATCH 1/8] feat: skeleton loading state for alerts table (#2511) --- keep-ui/app/alerts/[id]/page.tsx | 2 +- .../app/alerts/alert-table-alert-facets.tsx | 11 +++- .../app/alerts/alert-table-facet-types.tsx | 2 + keep-ui/app/alerts/alert-table-facet.tsx | 18 ++++- keep-ui/app/alerts/alert-table-utils.tsx | 2 +- keep-ui/app/alerts/alert-table.tsx | 19 ++---- keep-ui/app/alerts/alert-tabs.tsx | 12 +--- keep-ui/app/alerts/alerts-table-body.tsx | 30 +++++++-- keep-ui/app/alerts/alerts.client.tsx | 32 --------- keep-ui/app/alerts/alerts.tsx | 20 +++--- keep-ui/components/navbar/AlertsLinks.tsx | 19 ++++-- .../navbar/CustomPresetAlertLinks.tsx | 2 + keep-ui/components/navbar/UserInfo.tsx | 13 ++-- keep-ui/shared/lib/hooks/useMounted.tsx | 11 ++++ keep-ui/utils/hooks/useAlerts.ts | 43 ++++++------ keep-ui/utils/hooks/usePresets.ts | 3 +- tests/e2e_tests/test_end_to_end.py | 66 +++++++++++-------- 17 files changed, 164 insertions(+), 141 deletions(-) delete mode 100644 keep-ui/app/alerts/alerts.client.tsx create mode 100644 keep-ui/shared/lib/hooks/useMounted.tsx diff --git a/keep-ui/app/alerts/[id]/page.tsx b/keep-ui/app/alerts/[id]/page.tsx index 89a007659..2137123d8 100644 --- a/keep-ui/app/alerts/[id]/page.tsx +++ b/keep-ui/app/alerts/[id]/page.tsx @@ -1,4 +1,4 @@ -import AlertsPage from "../alerts.client"; +import AlertsPage from "../alerts"; type PageProps = { params: { id: string }; diff --git a/keep-ui/app/alerts/alert-table-alert-facets.tsx b/keep-ui/app/alerts/alert-table-alert-facets.tsx index 1366558b4..3c57b14ed 100644 --- a/keep-ui/app/alerts/alert-table-alert-facets.tsx +++ b/keep-ui/app/alerts/alert-table-alert-facets.tsx @@ -16,6 +16,7 @@ import { AddFacetModal, } from "./alert-table-facet-dynamic"; import { PlusIcon } from "@heroicons/react/24/outline"; +import { usePathname } from "next/navigation"; export const AlertFacets: React.FC = ({ alerts, @@ -26,7 +27,9 @@ export const AlertFacets: React.FC = ({ onDelete, className, table, + showSkeleton, }) => { + const pathname = usePathname(); const timeRangeFilter = table .getState() .columnFilters.find((filter) => filter.id === "lastReceived"); @@ -35,7 +38,7 @@ export const AlertFacets: React.FC = ({ | { start: Date; end: Date; isFromCalendar: boolean } | undefined; - const presetName = window.location.pathname.split("/").pop() || "default"; + const presetName = pathname?.split("/").pop() || "default"; const [isModalOpen, setIsModalOpen] = useLocalStorage( `addFacetModalOpen-${presetName}`, @@ -207,6 +210,7 @@ export const AlertFacets: React.FC = ({ } facetKey="severity" facetFilters={facetFilters} + showSkeleton={showSkeleton} /> = ({ } facetKey="status" facetFilters={facetFilters} + showSkeleton={showSkeleton} /> = ({ } facetKey="source" facetFilters={facetFilters} + showSkeleton={showSkeleton} /> = ({ } facetKey="assignee" facetFilters={facetFilters} + showSkeleton={showSkeleton} /> = ({ } facetKey="dismissed" facetFilters={facetFilters} + showSkeleton={showSkeleton} /> = ({ handleSelect("incident", value, exclusive, isAllOnly) } facetFilters={facetFilters} + showSkeleton={showSkeleton} /> {/* Dynamic facets */} {dynamicFacets.map((facet) => ( diff --git a/keep-ui/app/alerts/alert-table-facet-types.tsx b/keep-ui/app/alerts/alert-table-facet-types.tsx index d07439d4b..bcee24fd2 100644 --- a/keep-ui/app/alerts/alert-table-facet-types.tsx +++ b/keep-ui/app/alerts/alert-table-facet-types.tsx @@ -29,6 +29,7 @@ export interface FacetProps { facetKey: string; facetFilters: FacetFilters; showIcon?: boolean; + showSkeleton?: boolean; } export interface AlertFacetsProps { @@ -44,4 +45,5 @@ export interface AlertFacetsProps { onDelete: (facetKey: string) => void; className?: string; table: Table; + showSkeleton?: boolean; } diff --git a/keep-ui/app/alerts/alert-table-facet.tsx b/keep-ui/app/alerts/alert-table-facet.tsx index 03fa7556c..83a53a909 100644 --- a/keep-ui/app/alerts/alert-table-facet.tsx +++ b/keep-ui/app/alerts/alert-table-facet.tsx @@ -4,6 +4,8 @@ import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/20/solid"; import { FacetProps } from "./alert-table-facet-types"; import { FacetValue } from "./alert-table-facet-value"; import { useLocalStorage } from "utils/hooks/useLocalStorage"; +import { usePathname } from "next/navigation"; +import Skeleton from "react-loading-skeleton"; export const Facet: React.FC = ({ name, @@ -12,9 +14,11 @@ export const Facet: React.FC = ({ facetKey, facetFilters, showIcon = true, + showSkeleton, }) => { + const pathname = usePathname(); // Get preset name from URL - const presetName = window.location.pathname.split("/").pop() || "default"; + const presetName = pathname?.split("/").pop() || "default"; // Store open/close state in localStorage with a unique key per preset and facet const [isOpen, setIsOpen] = useLocalStorage( @@ -60,7 +64,17 @@ export const Facet: React.FC = ({ )}
- {values.length > 0 ? ( + {showSkeleton ? ( + Array.from({ length: 3 }).map((_, index) => ( +
+ + +
+ )) + ) : values.length > 0 ? ( filteredValues.map((value) => ( ( { // if presetName is alert-history, do not open sidebar @@ -303,21 +303,12 @@ export function AlertTable({ setDynamicFacets={setDynamicFacets} onDelete={handleFacetDelete} table={table} + showSkeleton={showSkeleton} />
- {isAsyncLoading && ( - - Alerts will show up in this table as they are added to Keep... - - )} {/* For dynamic preset, add alert tabs*/} {!presetStatic && ( + {Array(20) + .fill("") + .map((index, rowIndex) => ( + + {table.getAllColumns().map((c, cellIndex) => ( + + + + ))} + + ))} + + ); + } + return ( {table.getRowModel().rows.map((row) => { @@ -100,11 +124,7 @@ export function AlertsTableBody({ "relative z-[1]" // Ensure cell content is above the border )} > - {showSkeleton ? ( - - ) : ( - flexRender(cell.column.columnDef.cell, cell.getContext()) - )} + {flexRender(cell.column.columnDef.cell, cell.getContext())} ); })} diff --git a/keep-ui/app/alerts/alerts.client.tsx b/keep-ui/app/alerts/alerts.client.tsx deleted file mode 100644 index f409867bf..000000000 --- a/keep-ui/app/alerts/alerts.client.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -import { useRouter } from "next/navigation"; -import { useSession } from "next-auth/react"; -import Loading from "../loading"; -import Alerts from "./alerts"; - -type AlertsPageProps = { - presetName: string; -}; - -export default function AlertsPage({ presetName }: AlertsPageProps) { - const { data: session, status } = useSession(); - - const router = useRouter(); - - if (status === "loading") { - return ; - } - - if (status === "unauthenticated") { - console.log("unauthenticated"); - router.push("/signin"); - } - - if (session && !session.tenantId) { - console.log("no tenantId"); - router.push("/signin"); - } - - return ; -} diff --git a/keep-ui/app/alerts/alerts.tsx b/keep-ui/app/alerts/alerts.tsx index d70c6318d..3aa011e64 100644 --- a/keep-ui/app/alerts/alerts.tsx +++ b/keep-ui/app/alerts/alerts.tsx @@ -1,3 +1,5 @@ +"use client"; + import { useEffect, useMemo, useState } from "react"; import { Preset } from "./models"; import { useAlerts } from "utils/hooks/useAlerts"; @@ -16,7 +18,8 @@ import { useRouter, useSearchParams } from "next/navigation"; import AlertChangeStatusModal from "./alert-change-status-modal"; import { useAlertPolling } from "utils/hooks/usePusher"; import NotFound from "@/app/not-found"; -import NotAuthorized from "@/app/not-authorized"; +import { useMounted } from "@/shared/lib/hooks/useMounted"; +import { useSession } from "next-auth/react"; const defaultPresets: Preset[] = [ { @@ -107,6 +110,11 @@ export default function Alerts({ presetName }: AlertsProps) { mutate: mutateAlerts, error: alertsError, } = usePresetAlerts(selectedPreset ? selectedPreset.name : ""); + + // const isMounted = useMounted(); + const { status: sessionStatus } = useSession(); + const isLoading = isAsyncLoading || sessionStatus === "loading"; + useEffect(() => { const fingerprint = searchParams?.get("alertPayloadFingerprint"); if (fingerprint) { @@ -126,14 +134,6 @@ export default function Alerts({ presetName }: AlertsProps) { if (!selectedPreset) { return ; } - if (alertsError) { - if (alertsError.statusCode === 401) { - console.log("unauthenticated 401"); - window.location.href = "/signin"; - return null; - } - return ; - } return ( <> @@ -141,7 +141,7 @@ export default function Alerts({ presetName }: AlertsProps) { key={selectedPreset.name} preset={selectedPreset} alerts={alerts} - isAsyncLoading={isAsyncLoading} + isAsyncLoading={isLoading} setTicketModalAlert={setTicketModalAlert} setNoteModalAlert={setNoteModalAlert} setRunWorkflowModalAlert={setRunWorkflowModalAlert} diff --git a/keep-ui/components/navbar/AlertsLinks.tsx b/keep-ui/components/navbar/AlertsLinks.tsx index 71b998bf6..ce094f415 100644 --- a/keep-ui/components/navbar/AlertsLinks.tsx +++ b/keep-ui/components/navbar/AlertsLinks.tsx @@ -14,6 +14,7 @@ import { useLocalStorage } from "utils/hooks/useLocalStorage"; import { ActionMeta, MultiValue } from "react-select"; import { useTags } from "utils/hooks/useTags"; import { usePresets } from "utils/hooks/usePresets"; +import { useMounted } from "@/shared/lib/hooks/useMounted"; import clsx from "clsx"; type AlertsLinksProps = { @@ -22,6 +23,8 @@ type AlertsLinksProps = { export const AlertsLinks = ({ session }: AlertsLinksProps) => { const [isTagModalOpen, setIsTagModalOpen] = useState(false); + const isMounted = useMounted(); + const [storedTags, setStoredTags] = useLocalStorage( "selectedTags", [] @@ -59,7 +62,7 @@ export const AlertsLinks = ({ session }: AlertsLinksProps) => { // Determine if we should show the feed link const shouldShowFeed = (() => { // If we have server data, check if feed preset exists - if (staticPresets) { + if (staticPresets.length > 0) { return staticPresets.some((preset) => preset.name === "feed"); } @@ -69,13 +72,19 @@ export const AlertsLinks = ({ session }: AlertsLinksProps) => { return staticPresetsOrderFromLS?.some((preset) => preset.name === "feed"); } - // If we're still loading (no data and no error), show based on cache + // For the initial render on the server, always show feed + if (!isMounted) { + return true; + } + return staticPresetsOrderFromLS?.some((preset) => preset.name === "feed"); })(); // Get the current alerts count only if we should show feed const currentAlertsCount = (() => { - if (!shouldShowFeed) return 0; + if (!shouldShowFeed) { + return 0; + } // First try to get from server data const serverPreset = staticPresets?.find( @@ -89,7 +98,7 @@ export const AlertsLinks = ({ session }: AlertsLinksProps) => { const cachedPreset = staticPresetsOrderFromLS?.find( (preset) => preset.name === "feed" ); - return cachedPreset?.alerts_count ?? 0; + return cachedPreset?.alerts_count ?? undefined; })(); return ( @@ -141,7 +150,7 @@ export const AlertsLinks = ({ session }: AlertsLinksProps) => { )} - {session && ( + {session && isMounted && ( {/* React Player for playing alert sound */} ); diff --git a/keep-ui/components/navbar/UserInfo.tsx b/keep-ui/components/navbar/UserInfo.tsx index 6c993d565..40173f5cf 100644 --- a/keep-ui/components/navbar/UserInfo.tsx +++ b/keep-ui/components/navbar/UserInfo.tsx @@ -17,7 +17,8 @@ import * as Frigade from "@frigade/react"; import { useState } from "react"; import Onboarding from "./Onboarding"; import { useSignOut } from "@/shared/lib/useSignOut"; -import { useSetSentryUser } from "@/shared/lib/useSetSentryUser"; + +const ONBOARDING_FLOW_ID = "flow_FHDz1hit"; type UserDropdownProps = { session: Session; @@ -89,7 +90,7 @@ type UserInfoProps = { }; export const UserInfo = ({ session }: UserInfoProps) => { - const [isOnboardingComplete, setIsOnboardingComplete] = useState(false); + const { flow } = Frigade.useFlow(ONBOARDING_FLOW_ID); const [isOnboardingOpen, setIsOnboardingOpen] = useState(false); return ( @@ -113,14 +114,11 @@ export const UserInfo = ({ session }: UserInfoProps) => { Join our Slack - {session && } - {isOnboardingComplete === false && ( + {flow?.isCompleted === false && (
  • setIsOnboardingComplete(true)} + flowId={ONBOARDING_FLOW_ID} onClick={() => setIsOnboardingOpen(true)} - // css={{ backgroundColor: "#F9FAFB" }} /> { />
  • )} + {session && } ); diff --git a/keep-ui/shared/lib/hooks/useMounted.tsx b/keep-ui/shared/lib/hooks/useMounted.tsx new file mode 100644 index 000000000..fe2b29974 --- /dev/null +++ b/keep-ui/shared/lib/hooks/useMounted.tsx @@ -0,0 +1,11 @@ +import { useState, useEffect } from "react"; + +export function useMounted() { + const [isMounted, setIsMounted] = useState(false); + + useEffect(() => { + setIsMounted(true); + }, []); + + return isMounted; +} diff --git a/keep-ui/utils/hooks/useAlerts.ts b/keep-ui/utils/hooks/useAlerts.ts index 28fa523d0..4bbe5fd65 100644 --- a/keep-ui/utils/hooks/useAlerts.ts +++ b/keep-ui/utils/hooks/useAlerts.ts @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useMemo } from "react"; import { AlertDto } from "app/alerts/models"; import { useSession } from "next-auth/react"; import useSWR, { SWRConfiguration } from "swr"; @@ -53,40 +53,37 @@ export const useAlerts = () => { presetName: string, options: SWRConfiguration = { revalidateOnFocus: false } ) => { - const [alertsMap, setAlertsMap] = useState>( - new Map() - ); - const { data: alertsFromEndpoint = [], mutate, isLoading, - error, + error: alertsError, } = useAllAlerts(presetName, options); - useEffect(() => { - if (alertsFromEndpoint.length) { - const newAlertsMap = new Map( - alertsFromEndpoint.map((alertFromEndpoint) => [ - alertFromEndpoint.fingerprint, - { - ...alertFromEndpoint, - lastReceived: toDateObjectWithFallback( - alertFromEndpoint.lastReceived - ), - }, - ]) - ); - - setAlertsMap(newAlertsMap); + const alertsValue = useMemo(() => { + if (!alertsFromEndpoint.length) { + return []; } + + const alertsMap = new Map( + alertsFromEndpoint.map((alertFromEndpoint) => [ + alertFromEndpoint.fingerprint, + { + ...alertFromEndpoint, + lastReceived: toDateObjectWithFallback( + alertFromEndpoint.lastReceived + ), + }, + ]) + ); + return Array.from(alertsMap.values()); }, [alertsFromEndpoint]); return { - data: Array.from(alertsMap.values()), + data: alertsValue, mutate: mutate, isLoading: isLoading, - error: error, + error: alertsError, }; }; diff --git a/keep-ui/utils/hooks/usePresets.ts b/keep-ui/utils/hooks/usePresets.ts index 00e49588f..a0a0d76e2 100644 --- a/keep-ui/utils/hooks/usePresets.ts +++ b/keep-ui/utils/hooks/usePresets.ts @@ -8,8 +8,7 @@ import { useLocalStorage } from "utils/hooks/useLocalStorage"; import { useConfig } from "./useConfig"; import useSWRSubscription from "swr/subscription"; import { useWebsocket } from "./usePusher"; -import { usePathname, useSearchParams } from "next/navigation"; -import moment from "moment"; +import { useSearchParams } from "next/navigation"; export const usePresets = (type?: string, useFilters?: boolean) => { const { data: session } = useSession(); diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 7dcabfa25..80236d1df 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -33,10 +33,9 @@ # - Spin up the environment using docker-compose. # - Run "playwright codegen localhost:3000" # - Copy the generated code to a new test function. -import re import string import sys - +from datetime import datetime # Running the tests in GitHub Actions: # - Look at the test-pr-e2e.yml file in the .github/workflows directory. @@ -44,31 +43,50 @@ # os.environ["PLAYWRIGHT_HEADLESS"] = "false" -def test_sanity(browser): +def setup_console_listener(page, log_entries): + """Set up console listener to capture logs.""" + page.on("console", lambda msg: (log_entries.append(f"{datetime.now()}: {msg.text}, location: {msg.location}"))) + +def save_failure_artifacts(page, log_entries): + """Save screenshots, HTML content, and console logs on test failure.""" + # Generate unique name for the dump files + current_test_name = ( + "playwright_dump_" + + os.path.basename(__file__)[:-3] + + "_" + + sys._getframe().f_code.co_name + ) + + # Save screenshot + page.screenshot(path=current_test_name + ".png") + + # Save HTML content + with open(current_test_name + ".html", "w", encoding="utf-8") as f: + f.write(page.content()) + + # Save console logs + with open(current_test_name + "_console.log", "w", encoding="utf-8") as f: + f.write("\n".join(log_entries)) + +def test_sanity(browser): # browser is actually a page object + log_entries = [] + setup_console_listener(browser, log_entries) + try: browser.goto("http://localhost:3000/") browser.wait_for_url("http://localhost:3000/incidents") assert "Keep" in browser.title() except Exception: - # Current file + test name for unique html and png dump. - current_test_name = ( - "playwright_dump_" - + os.path.basename(__file__)[:-3] - + "_" - + sys._getframe().f_code.co_name - ) - - browser.screenshot(path=current_test_name + ".png") - with open(current_test_name + ".html", "w") as f: - f.write(browser.content()) + save_failure_artifacts(browser, log_entries) raise - -def test_insert_new_alert(browser): +def test_insert_new_alert(browser): # browser is actually a page object """ Test to insert a new alert - """ + log_entries = [] + setup_console_listener(browser, log_entries) + try: browser.goto( "http://localhost:3000/signin?callbackUrl=http%3A%2F%2Flocalhost%3A3000%2Fproviders" @@ -86,6 +104,8 @@ def test_insert_new_alert(browser): browser.wait_for_timeout(10000) # refresh the page browser.reload() + # wait for badge counter to update + browser.wait_for_timeout(500) feed_badge = browser.get_by_test_id("menu-alerts-feed-badge") feed_count = int(feed_badge.text_content()) assert feed_count > feed_count_before @@ -94,17 +114,7 @@ def test_insert_new_alert(browser): feed_link.click() except Exception: - # Current file + test name for unique html and png dump. - current_test_name = ( - "playwright_dump_" - + os.path.basename(__file__)[:-3] - + "_" - + sys._getframe().f_code.co_name - ) - - browser.screenshot(path=current_test_name + ".png") - with open(current_test_name + ".html", "w") as f: - f.write(browser.content()) + save_failure_artifacts(browser, log_entries) raise From 892a79ee5ad2acc3ef88b6f60bff6ac8a13b81af Mon Sep 17 00:00:00 2001 From: Tal Date: Tue, 19 Nov 2024 11:03:26 +0200 Subject: [PATCH 2/8] fix(ui): styling in alert table when empty (#2531) --- keep-ui/app/alerts/alerts-table-body.tsx | 2 +- .../servicenow_provider/servicenow_provider.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/keep-ui/app/alerts/alerts-table-body.tsx b/keep-ui/app/alerts/alerts-table-body.tsx index f3f5e723d..b492379d5 100644 --- a/keep-ui/app/alerts/alerts-table-body.tsx +++ b/keep-ui/app/alerts/alerts-table-body.tsx @@ -35,7 +35,7 @@ export function AlertsTableBody({ if (showEmptyState) { return ( <> -
    +
    Date: Tue, 19 Nov 2024 11:30:31 +0200 Subject: [PATCH 3/8] fix(ui): auth type defaults to NOAUTH (#2529) --- keep-ui/shared/lib/server/getConfig.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/keep-ui/shared/lib/server/getConfig.ts b/keep-ui/shared/lib/server/getConfig.ts index 44b11f30e..cec63a630 100644 --- a/keep-ui/shared/lib/server/getConfig.ts +++ b/keep-ui/shared/lib/server/getConfig.ts @@ -15,6 +15,9 @@ export function getConfig() { authType = AuthenticationType.DB; } else if (authType === NO_AUTH) { authType = AuthenticationType.NOAUTH; + } else { + // Default to NOAUTH + authType = AuthenticationType.NOAUTH; } // we want to support preview branches on vercel From 838d1d7f81d391d843fc13e5d09385bdfb8771fd Mon Sep 17 00:00:00 2001 From: Kirill Chernakov Date: Wed, 20 Nov 2024 12:22:15 +0400 Subject: [PATCH 4/8] refactor: useHydratedSession instead of built-in useSession (#2407) --- keep-ui/app/ai/ai.tsx | 2 +- keep-ui/app/alerts/ViewAlertModal.tsx | 2 +- .../app/alerts/alert-assign-ticket-modal.tsx | 2 +- .../alerts/alert-associate-incident-modal.tsx | 2 +- .../app/alerts/alert-change-status-modal.tsx | 2 +- .../alerts/alert-create-incident-ai-modal.tsx | 2 +- keep-ui/app/alerts/alert-dismiss-modal.tsx | 2 +- keep-ui/app/alerts/alert-menu.tsx | 2 +- keep-ui/app/alerts/alert-note-modal.tsx | 2 +- keep-ui/app/alerts/alert-presets.tsx | 2 +- .../alert-push-alert-to-server-modal.tsx | 2 +- .../app/alerts/alert-run-workflow-modal.tsx | 2 +- keep-ui/app/alerts/alert-tab-modal.tsx | 6 +- keep-ui/app/alerts/alert-tabs.tsx | 2 +- keep-ui/app/alerts/alerts.tsx | 4 +- keep-ui/app/auth-provider.tsx | 17 ++++- keep-ui/app/dashboard/[id]/dashboard.tsx | 65 +++++++++++++------ .../deduplication/DeduplicationSidebar.tsx | 2 +- .../app/deduplication/DeduplicationTable.tsx | 2 +- .../create-or-update-extraction-rule.tsx | 2 +- keep-ui/app/extraction/extractions-table.tsx | 2 +- keep-ui/app/frigade-provider.tsx | 4 +- .../[id]/activity/incident-activity.tsx | 2 +- .../activity/ui/IncidentActivityComment.tsx | 2 +- .../[id]/alerts/incident-alert-menu.tsx | 2 +- keep-ui/app/layout.tsx | 10 ++- .../create-or-update-maintenance-rule.tsx | 2 +- .../maintenance/maintenance-rules-table.tsx | 2 +- .../app/mapping/create-or-edit-mapping.tsx | 2 +- keep-ui/app/mapping/rules-table.tsx | 2 +- keep-ui/app/providers/page.client.tsx | 2 +- keep-ui/app/providers/provider-form.tsx | 2 +- .../CorrelationSidebarBody.tsx | 2 +- .../rules/CorrelationSidebar/DeleteRule.tsx | 2 +- keep-ui/app/settings/auth/permissions-tab.tsx | 2 +- keep-ui/app/settings/auth/users-sidebar.tsx | 12 ++-- keep-ui/app/settings/settings.client.tsx | 30 ++++----- keep-ui/app/topology/model/useTopology.ts | 2 +- .../topology/model/useTopologyApplications.ts | 2 +- .../workflows/[workflow_id]/executions.tsx | 2 +- keep-ui/app/workflows/builder/page.client.tsx | 2 +- .../builder/workflow-execution-results.tsx | 6 +- keep-ui/app/workflows/dragndrop.tsx | 2 +- .../workflows/manual-run-workflow-modal.tsx | 2 +- keep-ui/app/workflows/workflow-tile.tsx | 2 +- keep-ui/app/workflows/workflows.client.tsx | 2 +- .../incidents/model/useIncidentActions.tsx | 2 +- .../shared/lib/hooks/useHydratedSession.tsx | 31 +++++++++ keep-ui/shared/ui/PostHogPageView.tsx | 2 +- keep-ui/utils/hooks/useAI.ts | 2 +- keep-ui/utils/hooks/useAlertQuality.ts | 6 +- keep-ui/utils/hooks/useAlerts.ts | 2 +- .../utils/hooks/useDashboardMetricWidgets.ts | 47 +++++++------- keep-ui/utils/hooks/useDashboardPresets.ts | 45 ++++++++----- keep-ui/utils/hooks/useDashboards.ts | 2 +- keep-ui/utils/hooks/useDeduplicationRules.ts | 2 +- keep-ui/utils/hooks/useExtractionRules.ts | 2 +- keep-ui/utils/hooks/useGroups.ts | 2 +- keep-ui/utils/hooks/useIncidents.ts | 2 +- keep-ui/utils/hooks/useMaintenanceRules.ts | 2 +- keep-ui/utils/hooks/useMappingRules.ts | 2 +- keep-ui/utils/hooks/usePermissions.ts | 2 +- keep-ui/utils/hooks/usePresets.ts | 2 +- keep-ui/utils/hooks/useProviders.ts | 2 +- keep-ui/utils/hooks/usePusher.ts | 2 +- keep-ui/utils/hooks/useRoles.ts | 2 +- keep-ui/utils/hooks/useRules.ts | 2 +- keep-ui/utils/hooks/useScopes.ts | 2 +- keep-ui/utils/hooks/useSearchAlerts.ts | 2 +- keep-ui/utils/hooks/useTags.ts | 2 +- keep-ui/utils/hooks/useUsers.ts | 2 +- keep-ui/utils/hooks/useWorkflowExecutions.ts | 2 +- keep-ui/utils/hooks/useWorkflowRun.ts | 2 +- keep-ui/utils/hooks/useWorkflows.ts | 2 +- 74 files changed, 245 insertions(+), 160 deletions(-) create mode 100644 keep-ui/shared/lib/hooks/useHydratedSession.tsx diff --git a/keep-ui/app/ai/ai.tsx b/keep-ui/app/ai/ai.tsx index 7e9d23aa7..2446337a7 100644 --- a/keep-ui/app/ai/ai.tsx +++ b/keep-ui/app/ai/ai.tsx @@ -1,7 +1,7 @@ "use client"; import { Card, List, ListItem, Title, Subtitle } from "@tremor/react"; import { useAIStats, usePollAILogs } from "utils/hooks/useAI"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { toast } from "react-toastify"; import { useEffect, useState, useRef, FormEvent } from "react"; diff --git a/keep-ui/app/alerts/ViewAlertModal.tsx b/keep-ui/app/alerts/ViewAlertModal.tsx index 6bbeca28f..7bc404172 100644 --- a/keep-ui/app/alerts/ViewAlertModal.tsx +++ b/keep-ui/app/alerts/ViewAlertModal.tsx @@ -3,7 +3,7 @@ import Modal from "@/components/ui/Modal"; // Ensure this path matches your proj import { Button, Icon, Switch, Text } from "@tremor/react"; import { toast } from "react-toastify"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { XMarkIcon } from "@heroicons/react/24/outline"; import "./ViewAlertModal.css"; import React, { useState } from "react"; diff --git a/keep-ui/app/alerts/alert-assign-ticket-modal.tsx b/keep-ui/app/alerts/alert-assign-ticket-modal.tsx index f3920c764..0ca7bae0a 100644 --- a/keep-ui/app/alerts/alert-assign-ticket-modal.tsx +++ b/keep-ui/app/alerts/alert-assign-ticket-modal.tsx @@ -4,7 +4,7 @@ import { Button, TextInput, Text } from "@tremor/react"; import { PlusIcon } from "@heroicons/react/20/solid"; import { useForm, Controller, SubmitHandler } from "react-hook-form"; import { Providers } from "./../providers/providers"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { AlertDto } from "./models"; import Modal from "@/components/ui/Modal"; diff --git a/keep-ui/app/alerts/alert-associate-incident-modal.tsx b/keep-ui/app/alerts/alert-associate-incident-modal.tsx index 9d59afdbf..923d30cd8 100644 --- a/keep-ui/app/alerts/alert-associate-incident-modal.tsx +++ b/keep-ui/app/alerts/alert-associate-incident-modal.tsx @@ -2,7 +2,7 @@ import Modal from "@/components/ui/Modal"; import { Button, Divider, Title } from "@tremor/react"; import Select from "@/components/ui/Select"; import { CreateOrUpdateIncidentForm } from "@/features/create-or-update-incident"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { FormEvent, useCallback, useEffect, useState } from "react"; import { toast } from "react-toastify"; import { useApiUrl } from "utils/hooks/useConfig"; diff --git a/keep-ui/app/alerts/alert-change-status-modal.tsx b/keep-ui/app/alerts/alert-change-status-modal.tsx index d090599dc..f68f46e61 100644 --- a/keep-ui/app/alerts/alert-change-status-modal.tsx +++ b/keep-ui/app/alerts/alert-change-status-modal.tsx @@ -9,7 +9,7 @@ import Select, { import { useState } from "react"; import { AlertDto, Status } from "./models"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { toast } from "react-toastify"; import { CheckCircleIcon, diff --git a/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx b/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx index ada499e65..9d077ed66 100644 --- a/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx +++ b/keep-ui/app/alerts/alert-create-incident-ai-modal.tsx @@ -1,7 +1,7 @@ import React, { useState } from "react"; import Modal from "@/components/ui/Modal"; import { Callout, Button, Title, Card } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { toast } from "react-toastify"; import Loading from "../loading"; import { AlertDto } from "./models"; diff --git a/keep-ui/app/alerts/alert-dismiss-modal.tsx b/keep-ui/app/alerts/alert-dismiss-modal.tsx index 11bf3d63f..93976f22d 100644 --- a/keep-ui/app/alerts/alert-dismiss-modal.tsx +++ b/keep-ui/app/alerts/alert-dismiss-modal.tsx @@ -17,7 +17,7 @@ import "react-quill/dist/quill.snow.css"; import { AlertDto } from "./models"; import { format, set, isSameDay, isAfter, addMinutes } from "date-fns"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { usePresets } from "utils/hooks/usePresets"; import { useAlerts } from "utils/hooks/useAlerts"; import { toast } from "react-toastify"; diff --git a/keep-ui/app/alerts/alert-menu.tsx b/keep-ui/app/alerts/alert-menu.tsx index 997be6959..4784090d2 100644 --- a/keep-ui/app/alerts/alert-menu.tsx +++ b/keep-ui/app/alerts/alert-menu.tsx @@ -12,7 +12,7 @@ import { } from "@heroicons/react/24/outline"; import { IoNotificationsOffOutline } from "react-icons/io5"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import Link from "next/link"; import { ProviderMethod } from "app/providers/providers"; diff --git a/keep-ui/app/alerts/alert-note-modal.tsx b/keep-ui/app/alerts/alert-note-modal.tsx index a737059a9..fb9f6910b 100644 --- a/keep-ui/app/alerts/alert-note-modal.tsx +++ b/keep-ui/app/alerts/alert-note-modal.tsx @@ -7,7 +7,7 @@ const ReactQuill = import "react-quill/dist/quill.snow.css"; import { Button } from "@tremor/react"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { AlertDto } from "./models"; import Modal from "@/components/ui/Modal"; diff --git a/keep-ui/app/alerts/alert-presets.tsx b/keep-ui/app/alerts/alert-presets.tsx index 5263b7b1f..217ff5fc2 100644 --- a/keep-ui/app/alerts/alert-presets.tsx +++ b/keep-ui/app/alerts/alert-presets.tsx @@ -4,7 +4,7 @@ import Modal from "@/components/ui/Modal"; import { Button, Subtitle, TextInput, Switch, Text } from "@tremor/react"; import { useApiUrl } from "utils/hooks/useConfig"; import { toast } from "react-toastify"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { usePresets } from "utils/hooks/usePresets"; import { useTags } from "utils/hooks/useTags"; import { useRouter } from "next/navigation"; diff --git a/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx b/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx index 76931c8ed..44576e546 100644 --- a/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx +++ b/keep-ui/app/alerts/alert-push-alert-to-server-modal.tsx @@ -7,7 +7,7 @@ import { FieldValues, } from "react-hook-form"; import Modal from "@/components/ui/Modal"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { useProviders } from "utils/hooks/useProviders"; import ImageWithFallback from "@/components/ImageWithFallback"; diff --git a/keep-ui/app/alerts/alert-run-workflow-modal.tsx b/keep-ui/app/alerts/alert-run-workflow-modal.tsx index 3ade1e15a..514719fb4 100644 --- a/keep-ui/app/alerts/alert-run-workflow-modal.tsx +++ b/keep-ui/app/alerts/alert-run-workflow-modal.tsx @@ -3,7 +3,7 @@ import { AlertDto } from "./models"; import Modal from "@/components/ui/Modal"; import { useWorkflows } from "utils/hooks/useWorkflows"; import { useState } from "react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { toast } from "react-toastify"; import { useRouter } from "next/navigation"; diff --git a/keep-ui/app/alerts/alert-tab-modal.tsx b/keep-ui/app/alerts/alert-tab-modal.tsx index d5a99e7d6..c8a2b232d 100644 --- a/keep-ui/app/alerts/alert-tab-modal.tsx +++ b/keep-ui/app/alerts/alert-tab-modal.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import Modal from "@/components/ui/Modal"; import { Button, TextInput } from "@tremor/react"; import { AlertsRulesBuilder } from "app/alerts/alerts-rules-builder"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; interface AlertTabModalProps { @@ -114,8 +114,8 @@ const AlertTabModal = ({ !newTabName ? "Tab name is required" : !newTabFilter - ? "Tab filter is required (notice you need to click 'enter' to apply the filter)" - : "" + ? "Tab filter is required (notice you need to click 'enter' to apply the filter)" + : "" } > Add Tab diff --git a/keep-ui/app/alerts/alert-tabs.tsx b/keep-ui/app/alerts/alert-tabs.tsx index 42c8ea938..2413c4076 100644 --- a/keep-ui/app/alerts/alert-tabs.tsx +++ b/keep-ui/app/alerts/alert-tabs.tsx @@ -5,7 +5,7 @@ import AlertTabModal from "./alert-tab-modal"; import { evalWithContext } from "./alerts-rules-builder"; import { XMarkIcon } from "@heroicons/react/24/outline"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; interface Tab { id?: string; name: string; diff --git a/keep-ui/app/alerts/alerts.tsx b/keep-ui/app/alerts/alerts.tsx index 3aa011e64..4d0fe7117 100644 --- a/keep-ui/app/alerts/alerts.tsx +++ b/keep-ui/app/alerts/alerts.tsx @@ -18,8 +18,7 @@ import { useRouter, useSearchParams } from "next/navigation"; import AlertChangeStatusModal from "./alert-change-status-modal"; import { useAlertPolling } from "utils/hooks/usePusher"; import NotFound from "@/app/not-found"; -import { useMounted } from "@/shared/lib/hooks/useMounted"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; const defaultPresets: Preset[] = [ { @@ -111,7 +110,6 @@ export default function Alerts({ presetName }: AlertsProps) { error: alertsError, } = usePresetAlerts(selectedPreset ? selectedPreset.name : ""); - // const isMounted = useMounted(); const { status: sessionStatus } = useSession(); const isLoading = isAsyncLoading || sessionStatus === "loading"; diff --git a/keep-ui/app/auth-provider.tsx b/keep-ui/app/auth-provider.tsx index 21e157dfc..8a3107208 100644 --- a/keep-ui/app/auth-provider.tsx +++ b/keep-ui/app/auth-provider.tsx @@ -1,11 +1,24 @@ "use client"; +import { Session } from "next-auth"; import { SessionProvider } from "next-auth/react"; +declare global { + interface Window { + __NEXT_AUTH_SESSION__?: Session | null; + } +} + type Props = { children?: React.ReactNode; + session?: Session | null; }; -export const NextAuthProvider = ({ children }: Props) => { - return {children} +export const NextAuthProvider = ({ children, session }: Props) => { + // Hydrate session on mount + if (typeof window !== "undefined" && !!session) { + window.__NEXT_AUTH_SESSION__ = session; + } + + return {children}; }; diff --git a/keep-ui/app/dashboard/[id]/dashboard.tsx b/keep-ui/app/dashboard/[id]/dashboard.tsx index 77b060624..965f7f5fa 100644 --- a/keep-ui/app/dashboard/[id]/dashboard.tsx +++ b/keep-ui/app/dashboard/[id]/dashboard.tsx @@ -1,20 +1,29 @@ "use client"; -import {useParams} from "next/navigation"; -import {ChangeEvent, useEffect, useState} from "react"; +import { useParams } from "next/navigation"; +import { ChangeEvent, useEffect, useState } from "react"; import GridLayout from "../GridLayout"; import WidgetModal from "../WidgetModal"; -import {Button, Card, Icon, Subtitle, TextInput} from "@tremor/react"; -import {GenericsMetrics, LayoutItem, Threshold, WidgetData, WidgetType} from "../types"; -import {Preset} from "app/alerts/models"; -import {FiEdit2, FiSave} from "react-icons/fi"; -import {useSession} from "next-auth/react"; -import {useDashboards} from "utils/hooks/useDashboards"; -import {useApiUrl} from "utils/hooks/useConfig"; +import { Button, Card, Icon, Subtitle, TextInput } from "@tremor/react"; +import { + GenericsMetrics, + LayoutItem, + Threshold, + WidgetData, + WidgetType, +} from "../types"; +import { Preset } from "app/alerts/models"; +import { FiEdit2, FiSave } from "react-icons/fi"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; +import { useDashboards } from "utils/hooks/useDashboards"; +import { useApiUrl } from "utils/hooks/useConfig"; import "./../styles.css"; -import {toast} from "react-toastify"; -import {GenericFilters} from "@/components/filters/GenericFilters"; -import {useDashboardPreset} from "utils/hooks/useDashboardPresets"; -import {MetricsWidget, useDashboardMetricWidgets} from '@/utils/hooks/useDashboardMetricWidgets'; +import { toast } from "react-toastify"; +import { GenericFilters } from "@/components/filters/GenericFilters"; +import { useDashboardPreset } from "utils/hooks/useDashboardPresets"; +import { + MetricsWidget, + useDashboardMetricWidgets, +} from "@/utils/hooks/useDashboardMetricWidgets"; const DASHBOARD_FILTERS = [ { @@ -33,7 +42,7 @@ const DashboardPage = () => { const [isModalOpen, setIsModalOpen] = useState(false); const [layout, setLayout] = useState([]); const [widgetData, setWidgetData] = useState([]); - const {widgets: allMetricWidgets} = useDashboardMetricWidgets(true); + const { widgets: allMetricWidgets } = useDashboardMetricWidgets(true); const [editingItem, setEditingItem] = useState(null); const [dashboardName, setDashboardName] = useState(decodeURIComponent(id)); const [isEditingName, setIsEditingName] = useState(false); @@ -59,7 +68,9 @@ const DashboardPage = () => { const closeModal = () => setIsModalOpen(false); const handleAddWidget = ( - name: string, widgetType: WidgetType, preset?: Preset , + name: string, + widgetType: WidgetType, + preset?: Preset, thresholds?: Threshold[], metric?: MetricsWidget, genericMetrics?: GenericsMetrics @@ -69,10 +80,25 @@ const DashboardPage = () => { i: uniqueId, x: (layout.length % 12) * 2, y: Math.floor(layout.length / 12) * 2, - w: widgetType === WidgetType.GENERICS_METRICS ? 12 : widgetType === WidgetType.METRIC ? 6 : 3, - h: widgetType === WidgetType.GENERICS_METRICS ? 20 : widgetType === WidgetType.METRIC ? 8 : 3, + w: + widgetType === WidgetType.GENERICS_METRICS + ? 12 + : widgetType === WidgetType.METRIC + ? 6 + : 3, + h: + widgetType === WidgetType.GENERICS_METRICS + ? 20 + : widgetType === WidgetType.METRIC + ? 8 + : 3, minW: widgetType === WidgetType.GENERICS_METRICS ? 10 : 2, - minH: widgetType === WidgetType.GENERICS_METRICS ? 15 : widgetType === WidgetType.METRIC ? 7 : 3, + minH: + widgetType === WidgetType.GENERICS_METRICS + ? 15 + : widgetType === WidgetType.METRIC + ? 7 + : 3, static: false, }; const newWidget: WidgetData = { @@ -82,7 +108,7 @@ const DashboardPage = () => { name, widgetType, genericMetrics, - metric + metric, }; setLayout((prevLayout) => [...prevLayout, newItem]); setWidgetData((prevData) => [...prevData, newWidget]); @@ -90,7 +116,6 @@ const DashboardPage = () => { const handleEditWidget = (id: string, update?: WidgetData) => { let itemToEdit = widgetData.find((d) => d.i === id) || null; - console.log(itemToEdit, update) if (itemToEdit && update) { setEditingItem({ ...itemToEdit, ...update }); } else { diff --git a/keep-ui/app/deduplication/DeduplicationSidebar.tsx b/keep-ui/app/deduplication/DeduplicationSidebar.tsx index 0a3bf8943..48a6d808e 100644 --- a/keep-ui/app/deduplication/DeduplicationSidebar.tsx +++ b/keep-ui/app/deduplication/DeduplicationSidebar.tsx @@ -24,7 +24,7 @@ import { InformationCircleIcon, } from "@heroicons/react/24/outline"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { KeyedMutator } from "swr"; interface ProviderOption { diff --git a/keep-ui/app/deduplication/DeduplicationTable.tsx b/keep-ui/app/deduplication/DeduplicationTable.tsx index 05d634451..3951fbaaa 100644 --- a/keep-ui/app/deduplication/DeduplicationTable.tsx +++ b/keep-ui/app/deduplication/DeduplicationTable.tsx @@ -25,7 +25,7 @@ import DeduplicationSidebar from "app/deduplication/DeduplicationSidebar"; import { TrashIcon, PauseIcon, PlusIcon } from "@heroicons/react/24/outline"; import Image from "next/image"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; const columnHelper = createColumnHelper(); diff --git a/keep-ui/app/extraction/create-or-update-extraction-rule.tsx b/keep-ui/app/extraction/create-or-update-extraction-rule.tsx index a770f68c9..11d7c032b 100644 --- a/keep-ui/app/extraction/create-or-update-extraction-rule.tsx +++ b/keep-ui/app/extraction/create-or-update-extraction-rule.tsx @@ -13,7 +13,7 @@ import { Switch, Badge, } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { FormEvent, useEffect, useState } from "react"; import { toast } from "react-toastify"; import { useApiUrl } from "utils/hooks/useConfig"; diff --git a/keep-ui/app/extraction/extractions-table.tsx b/keep-ui/app/extraction/extractions-table.tsx index 48fcb7f51..7b621b05b 100644 --- a/keep-ui/app/extraction/extractions-table.tsx +++ b/keep-ui/app/extraction/extractions-table.tsx @@ -18,7 +18,7 @@ import { useReactTable, } from "@tanstack/react-table"; import { MdRemoveCircle, MdModeEdit } from "react-icons/md"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { useMappings } from "utils/hooks/useMappingRules"; import { toast } from "react-toastify"; diff --git a/keep-ui/app/frigade-provider.tsx b/keep-ui/app/frigade-provider.tsx index 3d98f4aa3..2ae5b4619 100644 --- a/keep-ui/app/frigade-provider.tsx +++ b/keep-ui/app/frigade-provider.tsx @@ -1,7 +1,7 @@ "use client"; import * as Frigade from "@frigade/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; export const FrigadeProvider = ({ children, }: { @@ -14,7 +14,7 @@ export const FrigadeProvider = ({ userId={ session?.user.email === "keep" ? undefined - : session?.user.email ?? session?.user.name + : (session?.user.email ?? session?.user.name) } theme={{ colors: { diff --git a/keep-ui/app/incidents/[id]/activity/incident-activity.tsx b/keep-ui/app/incidents/[id]/activity/incident-activity.tsx index 3b6ea0787..7a62633f6 100644 --- a/keep-ui/app/incidents/[id]/activity/incident-activity.tsx +++ b/keep-ui/app/incidents/[id]/activity/incident-activity.tsx @@ -11,7 +11,7 @@ import { usePollIncidentComments, } from "@/utils/hooks/useIncidents"; import { useAlerts } from "@/utils/hooks/useAlerts"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { IncidentActivityItem } from "./ui/IncidentActivityItem"; import { IncidentActivityComment } from "./ui/IncidentActivityComment"; import { useMemo } from "react"; diff --git a/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx b/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx index 2cd8f0b77..d015b02e9 100644 --- a/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx +++ b/keep-ui/app/incidents/[id]/activity/ui/IncidentActivityComment.tsx @@ -2,7 +2,7 @@ import { IncidentDto } from "@/entities/incidents/model"; import { AuditEvent } from "@/utils/hooks/useAlerts"; import { useApiUrl } from "@/utils/hooks/useConfig"; import { TextInput, Button } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useState, useCallback, useEffect } from "react"; import { toast } from "react-toastify"; import { KeyedMutator } from "swr"; diff --git a/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx b/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx index 03d7c615e..f902df664 100644 --- a/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx +++ b/keep-ui/app/incidents/[id]/alerts/incident-alert-menu.tsx @@ -1,6 +1,6 @@ import { Icon } from "@tremor/react"; import { AlertDto } from "app/alerts/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { toast } from "react-toastify"; import { useApiUrl } from "utils/hooks/useConfig"; import { useIncidentAlerts } from "utils/hooks/useIncidents"; diff --git a/keep-ui/app/layout.tsx b/keep-ui/app/layout.tsx index d7b0f90ab..a8ee5503a 100644 --- a/keep-ui/app/layout.tsx +++ b/keep-ui/app/layout.tsx @@ -7,11 +7,13 @@ import { TopologyPollingContextProvider } from "@/app/topology/model/TopologyPol import { FrigadeProvider } from "./frigade-provider"; import { getConfig } from "@/shared/lib/server/getConfig"; import { ConfigProvider } from "./config-provider"; -import "./globals.css"; -import "react-toastify/dist/ReactToastify.css"; import { PHProvider } from "./posthog-provider"; import dynamic from "next/dynamic"; import ReadOnlyBanner from "./read-only-banner"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/pages/api/auth/[...nextauth]"; +import "./globals.css"; +import "react-toastify/dist/ReactToastify.css"; const PostHogPageView = dynamic(() => import("@/shared/ui/PostHogPageView"), { ssr: false, @@ -29,12 +31,14 @@ type RootLayoutProps = { export default async function RootLayout({ children }: RootLayoutProps) { const config = getConfig(); + const session = await getServerSession(authOptions); + return ( - + {/* @ts-ignore-error Server Component */} diff --git a/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx b/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx index fc50ca66d..9a71bc59f 100644 --- a/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx +++ b/keep-ui/app/maintenance/create-or-update-maintenance-rule.tsx @@ -10,7 +10,7 @@ import { Select, SelectItem, } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { FormEvent, useEffect, useState } from "react"; import { toast } from "react-toastify"; import { useApiUrl } from "utils/hooks/useConfig"; diff --git a/keep-ui/app/maintenance/maintenance-rules-table.tsx b/keep-ui/app/maintenance/maintenance-rules-table.tsx index 819caa4c6..790082e83 100644 --- a/keep-ui/app/maintenance/maintenance-rules-table.tsx +++ b/keep-ui/app/maintenance/maintenance-rules-table.tsx @@ -17,7 +17,7 @@ import { useReactTable, } from "@tanstack/react-table"; import { MdRemoveCircle, MdModeEdit } from "react-icons/md"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { toast } from "react-toastify"; import { useApiUrl } from "utils/hooks/useConfig"; import { MaintenanceRule } from "./model"; diff --git a/keep-ui/app/mapping/create-or-edit-mapping.tsx b/keep-ui/app/mapping/create-or-edit-mapping.tsx index 0145999fa..5c0b61a95 100644 --- a/keep-ui/app/mapping/create-or-edit-mapping.tsx +++ b/keep-ui/app/mapping/create-or-edit-mapping.tsx @@ -17,7 +17,7 @@ import { TabPanels, TabPanel, } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { ChangeEvent, FormEvent, diff --git a/keep-ui/app/mapping/rules-table.tsx b/keep-ui/app/mapping/rules-table.tsx index 476ec90f3..dc80a5326 100644 --- a/keep-ui/app/mapping/rules-table.tsx +++ b/keep-ui/app/mapping/rules-table.tsx @@ -18,7 +18,7 @@ import { ExpandedState, } from "@tanstack/react-table"; import { MdRemoveCircle, MdModeEdit } from "react-icons/md"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { useMappings } from "utils/hooks/useMappingRules"; import { toast } from "react-toastify"; diff --git a/keep-ui/app/providers/page.client.tsx b/keep-ui/app/providers/page.client.tsx index b44cdf109..aac212780 100644 --- a/keep-ui/app/providers/page.client.tsx +++ b/keep-ui/app/providers/page.client.tsx @@ -1,6 +1,6 @@ "use client"; import { defaultProvider, Provider } from "./providers"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { KeepApiError } from "@/shared/lib/KeepApiError"; import { useApiUrl } from "utils/hooks/useConfig"; import ProvidersTiles from "./providers-tiles"; diff --git a/keep-ui/app/providers/provider-form.tsx b/keep-ui/app/providers/provider-form.tsx index 80e519a7d..5d59cf35a 100644 --- a/keep-ui/app/providers/provider-form.tsx +++ b/keep-ui/app/providers/provider-form.tsx @@ -2,7 +2,7 @@ // There's also a lot of s**t in here, but it works for now 🤷‍♂️ // @ts-nocheck import React, { useEffect, useState, useRef, useCallback } from "react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { Provider } from "./providers"; import { useApiUrl } from "utils/hooks/useConfig"; import Image from "next/image"; diff --git a/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx b/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx index ffb225c04..29d5d8fa2 100644 --- a/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx +++ b/keep-ui/app/rules/CorrelationSidebar/CorrelationSidebarBody.tsx @@ -7,7 +7,7 @@ import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; import { CorrelationForm } from "./CorrelationForm"; import { CorrelationGroups } from "./CorrelationGroups"; import { CorrelationSubmission } from "./CorrelationSubmission"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useRules } from "utils/hooks/useRules"; import { CorrelationForm as CorrelationFormType } from "."; import { useRouter, useSearchParams } from "next/navigation"; diff --git a/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx b/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx index feabbeb1d..992a2151c 100644 --- a/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx +++ b/keep-ui/app/rules/CorrelationSidebar/DeleteRule.tsx @@ -1,6 +1,6 @@ import { TrashIcon } from "@radix-ui/react-icons"; import { Button } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { MouseEvent } from "react"; import { useApiUrl } from "utils/hooks/useConfig"; import { useRules } from "utils/hooks/useRules"; diff --git a/keep-ui/app/settings/auth/permissions-tab.tsx b/keep-ui/app/settings/auth/permissions-tab.tsx index 6a98e5445..702b00811 100644 --- a/keep-ui/app/settings/auth/permissions-tab.tsx +++ b/keep-ui/app/settings/auth/permissions-tab.tsx @@ -10,7 +10,7 @@ import Loading from "app/loading"; import { PermissionsTable } from "./permissions-table"; import PermissionSidebar from "./permissions-sidebar"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; interface Props { accessToken: string; diff --git a/keep-ui/app/settings/auth/users-sidebar.tsx b/keep-ui/app/settings/auth/users-sidebar.tsx index 7c5752ed5..b485ec6af 100644 --- a/keep-ui/app/settings/auth/users-sidebar.tsx +++ b/keep-ui/app/settings/auth/users-sidebar.tsx @@ -5,8 +5,6 @@ import { Subtitle, Button, TextInput, - SearchSelect, - SearchSelectItem, MultiSelect, MultiSelectItem, Callout, @@ -21,7 +19,7 @@ import { import { useRoles } from "utils/hooks/useRoles"; import { useGroups } from "utils/hooks/useGroups"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { User, Group } from "app/settings/models"; import { AuthenticationType } from "utils/authenticationType"; import { useConfig } from "utils/hooks/useConfig"; @@ -105,7 +103,9 @@ const UsersSidebar = ({ }, [user, setValue, isOpen, reset, clearErrors, identifierType]); const onSubmit: SubmitHandler = async (data) => { - if (!userCreationAllowed) return; + if (!userCreationAllowed) { + return; + } setIsSubmitting(true); clearErrors("root.serverError"); @@ -385,8 +385,8 @@ const UsersSidebar = ({ {isSubmitting ? "Saving..." : isNewUser - ? "Create User" - : "Save"} + ? "Create User" + : "Save"} )}
    diff --git a/keep-ui/app/settings/settings.client.tsx b/keep-ui/app/settings/settings.client.tsx index 0b8c213b2..36d912a69 100644 --- a/keep-ui/app/settings/settings.client.tsx +++ b/keep-ui/app/settings/settings.client.tsx @@ -11,7 +11,7 @@ import { LockClosedIcon, } from "@heroicons/react/24/outline"; import { MdOutlineSecurity } from "react-icons/md"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { useConfig } from "utils/hooks/useConfig"; import { AuthenticationType } from "utils/authenticationType"; @@ -73,24 +73,24 @@ export default function SettingsPage() { newSelectedTab === "users" ? 0 : newSelectedTab === "webhook" - ? 1 - : newSelectedTab === "smtp" - ? 2 - : 0; + ? 1 + : newSelectedTab === "smtp" + ? 2 + : 0; const userSubTabIndex = newUserSubTab === "users" ? 0 : newUserSubTab === "groups" - ? 1 - : newUserSubTab === "roles" - ? 2 - : newUserSubTab === "permissions" - ? 3 - : newUserSubTab === "api-keys" - ? 4 - : newUserSubTab === "sso" - ? 5 - : 0; + ? 1 + : newUserSubTab === "roles" + ? 2 + : newUserSubTab === "permissions" + ? 3 + : newUserSubTab === "api-keys" + ? 4 + : newUserSubTab === "sso" + ? 5 + : 0; setTabIndex(tabIndex); setUserSubTabIndex(userSubTabIndex); setSelectedTab(newSelectedTab); diff --git a/keep-ui/app/topology/model/useTopology.ts b/keep-ui/app/topology/model/useTopology.ts index 41f42354f..b93d42c48 100644 --- a/keep-ui/app/topology/model/useTopology.ts +++ b/keep-ui/app/topology/model/useTopology.ts @@ -1,5 +1,5 @@ import { TopologyService } from "@/app/topology/model/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { fetcher } from "@/utils/fetcher"; import { useEffect } from "react"; diff --git a/keep-ui/app/topology/model/useTopologyApplications.ts b/keep-ui/app/topology/model/useTopologyApplications.ts index eb6c34b61..eb749d254 100644 --- a/keep-ui/app/topology/model/useTopologyApplications.ts +++ b/keep-ui/app/topology/model/useTopologyApplications.ts @@ -2,7 +2,7 @@ import { TopologyApplication } from "./models"; import { useApiUrl } from "utils/hooks/useConfig"; import useSWR, { SWRConfiguration } from "swr"; import { fetcher } from "@/utils/fetcher"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useCallback, useMemo } from "react"; import { useTopologyBaseKey, useTopology } from "./useTopology"; import { useRevalidateMultiple } from "@/utils/state"; diff --git a/keep-ui/app/workflows/[workflow_id]/executions.tsx b/keep-ui/app/workflows/[workflow_id]/executions.tsx index 86df4cd2b..963588fcd 100644 --- a/keep-ui/app/workflows/[workflow_id]/executions.tsx +++ b/keep-ui/app/workflows/[workflow_id]/executions.tsx @@ -1,7 +1,7 @@ "use client"; import { Callout, Card } from "@tremor/react"; import React, { useEffect, useState } from "react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { ExclamationCircleIcon } from "@heroicons/react/24/outline"; import Loading from "app/loading"; import { useRouter } from "next/navigation"; diff --git a/keep-ui/app/workflows/builder/page.client.tsx b/keep-ui/app/workflows/builder/page.client.tsx index 73f9223d2..fd418e388 100644 --- a/keep-ui/app/workflows/builder/page.client.tsx +++ b/keep-ui/app/workflows/builder/page.client.tsx @@ -9,7 +9,7 @@ import { ArrowUpOnSquareIcon, PlayIcon, } from "@heroicons/react/20/solid"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { BuilderCard } from "./builder-card"; import Loading from "../../loading"; diff --git a/keep-ui/app/workflows/builder/workflow-execution-results.tsx b/keep-ui/app/workflows/builder/workflow-execution-results.tsx index b468682e2..5983214b7 100644 --- a/keep-ui/app/workflows/builder/workflow-execution-results.tsx +++ b/keep-ui/app/workflows/builder/workflow-execution-results.tsx @@ -7,7 +7,7 @@ import { Card, Title, } from "@tremor/react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import Loading from "../../loading"; import { ExclamationCircleIcon } from "@heroicons/react/24/outline"; @@ -211,8 +211,8 @@ export function ExecutionResults({ log.message?.includes("NOT to run") ? "bg-red-100" : log.message?.includes("evaluated to run") - ? "bg-green-100" - : "" + ? "bg-green-100" + : "" }`} key={index} > diff --git a/keep-ui/app/workflows/dragndrop.tsx b/keep-ui/app/workflows/dragndrop.tsx index cc7c1d80f..2cf06f9e3 100644 --- a/keep-ui/app/workflows/dragndrop.tsx +++ b/keep-ui/app/workflows/dragndrop.tsx @@ -1,6 +1,6 @@ import React, { useRef, useState } from "react"; import { useApiUrl } from "utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; const FileUpload: React.FC = () => { const apiUrl = useApiUrl(); diff --git a/keep-ui/app/workflows/manual-run-workflow-modal.tsx b/keep-ui/app/workflows/manual-run-workflow-modal.tsx index bd548ae12..825fb9375 100644 --- a/keep-ui/app/workflows/manual-run-workflow-modal.tsx +++ b/keep-ui/app/workflows/manual-run-workflow-modal.tsx @@ -3,7 +3,7 @@ import { Button, Select, SelectItem, Title } from "@tremor/react"; import Modal from "@/components/ui/Modal"; import { useWorkflows } from "utils/hooks/useWorkflows"; import { useState } from "react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "utils/hooks/useConfig"; import { toast } from "react-toastify"; import { useRouter } from "next/navigation"; diff --git a/keep-ui/app/workflows/workflow-tile.tsx b/keep-ui/app/workflows/workflow-tile.tsx index ad9a4e636..636ad7e3d 100644 --- a/keep-ui/app/workflows/workflow-tile.tsx +++ b/keep-ui/app/workflows/workflow-tile.tsx @@ -1,6 +1,6 @@ "use client"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { Workflow, Filter } from "./models"; import { useApiUrl } from "utils/hooks/useConfig"; import Image from "next/image"; diff --git a/keep-ui/app/workflows/workflows.client.tsx b/keep-ui/app/workflows/workflows.client.tsx index 8a5d9e34b..58e53fc30 100644 --- a/keep-ui/app/workflows/workflows.client.tsx +++ b/keep-ui/app/workflows/workflows.client.tsx @@ -8,7 +8,7 @@ import { ExclamationCircleIcon, PlusCircleIcon, } from "@heroicons/react/24/outline"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { fetcher } from "../../utils/fetcher"; import { Workflow, MockWorkflow } from "./models"; import { useApiUrl } from "utils/hooks/useConfig"; diff --git a/keep-ui/entities/incidents/model/useIncidentActions.tsx b/keep-ui/entities/incidents/model/useIncidentActions.tsx index 98d676009..76b3074ad 100644 --- a/keep-ui/entities/incidents/model/useIncidentActions.tsx +++ b/keep-ui/entities/incidents/model/useIncidentActions.tsx @@ -1,5 +1,5 @@ import { useApiUrl } from "@/utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useCallback } from "react"; import { toast } from "react-toastify"; import { useSWRConfig } from "swr"; diff --git a/keep-ui/shared/lib/hooks/useHydratedSession.tsx b/keep-ui/shared/lib/hooks/useHydratedSession.tsx new file mode 100644 index 000000000..6fddec50f --- /dev/null +++ b/keep-ui/shared/lib/hooks/useHydratedSession.tsx @@ -0,0 +1,31 @@ +"use client"; +import { useState, useEffect } from "react"; +import { useSession as useNextAuthSession } from "next-auth/react"; +import type { Session } from "next-auth"; +import type { UseSessionOptions, SessionContextValue } from "next-auth/react"; + +export function useHydratedSession( + options?: UseSessionOptions +): SessionContextValue { + const [isHydrated, setIsHydrated] = useState(false); + const session = useNextAuthSession(options); + useEffect(() => { + setIsHydrated(true); + }, []); + // Ensure we're in browser environment + const isBrowser = typeof window !== "undefined"; + // On first render, return hydrated session if available + if ( + (!isHydrated || session.status === "loading") && + isBrowser && + window.__NEXT_AUTH_SESSION__ !== null && + window.__NEXT_AUTH_SESSION__ !== undefined + ) { + return { + data: window.__NEXT_AUTH_SESSION__, + status: "authenticated" as const, + update: session.update, + } satisfies SessionContextValue; + } + return session; +} diff --git a/keep-ui/shared/ui/PostHogPageView.tsx b/keep-ui/shared/ui/PostHogPageView.tsx index d267f5968..818737a8d 100644 --- a/keep-ui/shared/ui/PostHogPageView.tsx +++ b/keep-ui/shared/ui/PostHogPageView.tsx @@ -5,7 +5,7 @@ import { usePathname, useSearchParams } from "next/navigation"; import { useEffect } from "react"; import { usePostHog } from "posthog-js/react"; import { useConfig } from "@/utils/hooks/useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "../lib/hooks/useHydratedSession"; import { NoAuthUserEmail } from "@/utils/authenticationType"; export default function PostHogPageView(): null { diff --git a/keep-ui/utils/hooks/useAI.ts b/keep-ui/utils/hooks/useAI.ts index 329830b32..80f5f2531 100644 --- a/keep-ui/utils/hooks/useAI.ts +++ b/keep-ui/utils/hooks/useAI.ts @@ -1,5 +1,5 @@ import { AILogs, AIStats } from "app/ai/model"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useAlertQuality.ts b/keep-ui/utils/hooks/useAlertQuality.ts index 9921da550..3445ae923 100644 --- a/keep-ui/utils/hooks/useAlertQuality.ts +++ b/keep-ui/utils/hooks/useAlertQuality.ts @@ -1,9 +1,9 @@ -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import { fetcher } from "../fetcher"; import useSWRImmutable from "swr/immutable"; import { useSearchParams } from "next/navigation"; -import { useMemo } from "react"; +import { useMemo } from "react"; import { useApiUrl } from "./useConfig"; export const useAlertQualityMetrics = ( @@ -19,7 +19,7 @@ export const useAlertQualityMetrics = ( const fieldArray = Array.isArray(fields) ? fields : [fields]; fieldArray.forEach((field) => params.append("fields", field)); } - + return params.toString(); }, [fields, searchParams]); // TODO: Proper type needs to be defined. diff --git a/keep-ui/utils/hooks/useAlerts.ts b/keep-ui/utils/hooks/useAlerts.ts index 4bbe5fd65..6b8abf516 100644 --- a/keep-ui/utils/hooks/useAlerts.ts +++ b/keep-ui/utils/hooks/useAlerts.ts @@ -1,6 +1,6 @@ import { useState, useEffect, useMemo } from "react"; import { AlertDto } from "app/alerts/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useDashboardMetricWidgets.ts b/keep-ui/utils/hooks/useDashboardMetricWidgets.ts index d7d24ecc8..51ab7ba9c 100644 --- a/keep-ui/utils/hooks/useDashboardMetricWidgets.ts +++ b/keep-ui/utils/hooks/useDashboardMetricWidgets.ts @@ -1,7 +1,7 @@ - import {useSession} from "next-auth/react"; - import { useApiUrl } from "./useConfig"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; +import { useApiUrl } from "./useConfig"; import useSWR from "swr"; -import {fetcher} from "@/utils/fetcher"; +import { fetcher } from "@/utils/fetcher"; import { usePathname, useSearchParams } from "next/navigation"; export interface MetricsWidget { @@ -12,7 +12,7 @@ export interface MetricsWidget { interface DistributionData { hour: string; - number: number + number: number; } interface DashboardDistributionData { @@ -20,47 +20,48 @@ interface DashboardDistributionData { ipd: DistributionData[]; apd: DistributionData[]; wpd: DistributionData[]; - } export const useDashboardMetricWidgets = (useFilters?: boolean) => { - const {data: session} = useSession(); + const { data: session } = useSession(); const apiUrl = useApiUrl(); const searchParams = useSearchParams(); const filters = searchParams?.toString(); - const {data, error, mutate} = useSWR( - session ? `${apiUrl}/dashboard/metric-widgets${ - useFilters && filters ? `?${filters}` : "" - }` : null, - (url: string) => fetcher(url, session!.accessToken) - ) - console.log(filters) + const { data, error, mutate } = useSWR( + session + ? `${apiUrl}/dashboard/metric-widgets${ + useFilters && filters ? `?${filters}` : "" + }` + : null, + (url: string) => fetcher(url, session!.accessToken) + ); + console.log(filters); - let widgets: MetricsWidget[] = [] + let widgets: MetricsWidget[] = []; if (data) { - widgets = [ + widgets = [ { id: "mttr", name: "MTTR", - data: data.mttr + data: data.mttr, }, { id: "apd", - "name": "Alerts/Day", - data: data.apd + name: "Alerts/Day", + data: data.apd, }, { id: "ipd", name: "Incidents/Day", - data: data.ipd + data: data.ipd, }, { id: "wpd", name: "Workflows/Day", - data: data.wpd - } + data: data.wpd, + }, ]; } - return {widgets}; -} \ No newline at end of file + return { widgets }; +}; diff --git a/keep-ui/utils/hooks/useDashboardPresets.ts b/keep-ui/utils/hooks/useDashboardPresets.ts index 2f5cd0310..807fd7e1d 100644 --- a/keep-ui/utils/hooks/useDashboardPresets.ts +++ b/keep-ui/utils/hooks/useDashboardPresets.ts @@ -1,16 +1,18 @@ -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { usePresets } from "./usePresets"; import { Preset } from "app/alerts/models"; -import { useMemo } from "react"; +import { useCallback, useMemo } from "react"; import { useSearchParams } from "next/navigation"; export const useDashboardPreset = () => { const { data: session } = useSession(); - const { useAllPresets, useStaticPresets, presetsOrderFromLS, staticPresetsOrderFromLS } = usePresets( - "dashboard", - true - ); + const { + useAllPresets, + useStaticPresets, + presetsOrderFromLS, + staticPresetsOrderFromLS, + } = usePresets("dashboard", true); const { data: presets = [] } = useAllPresets({ revalidateIfStale: false, revalidateOnFocus: false, @@ -20,24 +22,35 @@ export const useDashboardPreset = () => { }); const searchParams = useSearchParams(); - - const checkValidPreset = (preset: Preset) => { - if (!preset.is_private) { - return true; - } - return preset && preset.created_by == session?.user?.email; - }; + const checkValidPreset = useCallback( + (preset: Preset) => { + if (!preset.is_private) { + return true; + } + return preset && preset.created_by == session?.user?.email; + }, + [session] + ); let allPreset = useMemo(() => { /*If any filters are applied on the dashboard, we will fetch live data; otherwise, we will use data from localStorage to sync values between the navbar and the dashboard.*/ - let combinedPresets = searchParams?.toString() ? [...presets, ...fetchedPresets]: [...presetsOrderFromLS, ...staticPresetsOrderFromLS]; + let combinedPresets = searchParams?.toString() + ? [...presets, ...fetchedPresets] + : [...presetsOrderFromLS, ...staticPresetsOrderFromLS]; //private preset checks combinedPresets = combinedPresets.filter((preset) => checkValidPreset(preset) ); return combinedPresets; - }, [presets, fetchedPresets, searchParams, presets, fetchedPresets]); + }, [ + searchParams, + presets, + fetchedPresets, + presetsOrderFromLS, + staticPresetsOrderFromLS, + checkValidPreset, + ]); - return allPreset; + return allPreset; }; diff --git a/keep-ui/utils/hooks/useDashboards.ts b/keep-ui/utils/hooks/useDashboards.ts index 7f3c81245..e3c9e495c 100644 --- a/keep-ui/utils/hooks/useDashboards.ts +++ b/keep-ui/utils/hooks/useDashboards.ts @@ -1,5 +1,5 @@ import useSWR from "swr"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useDeduplicationRules.ts b/keep-ui/utils/hooks/useDeduplicationRules.ts index 54b68015b..74b13fd82 100644 --- a/keep-ui/utils/hooks/useDeduplicationRules.ts +++ b/keep-ui/utils/hooks/useDeduplicationRules.ts @@ -1,5 +1,5 @@ import { DeduplicationRule } from "app/deduplication/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useExtractionRules.ts b/keep-ui/utils/hooks/useExtractionRules.ts index 0ff32b445..4655326a5 100644 --- a/keep-ui/utils/hooks/useExtractionRules.ts +++ b/keep-ui/utils/hooks/useExtractionRules.ts @@ -1,5 +1,5 @@ import { ExtractionRule } from "app/extraction/model"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useGroups.ts b/keep-ui/utils/hooks/useGroups.ts index 3e1dde9a2..fd3c29dae 100644 --- a/keep-ui/utils/hooks/useGroups.ts +++ b/keep-ui/utils/hooks/useGroups.ts @@ -1,5 +1,5 @@ import { Group } from "app/settings/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useIncidents.ts b/keep-ui/utils/hooks/useIncidents.ts index 59ae7353f..c24bdc298 100644 --- a/keep-ui/utils/hooks/useIncidents.ts +++ b/keep-ui/utils/hooks/useIncidents.ts @@ -5,7 +5,7 @@ import { PaginatedIncidentsDto, } from "@/entities/incidents/model"; import { PaginatedWorkflowExecutionDto } from "app/workflows/builder/types"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useMaintenanceRules.ts b/keep-ui/utils/hooks/useMaintenanceRules.ts index b771615b1..f2d3f618b 100644 --- a/keep-ui/utils/hooks/useMaintenanceRules.ts +++ b/keep-ui/utils/hooks/useMaintenanceRules.ts @@ -1,5 +1,5 @@ import { MaintenanceRule } from "app/maintenance/model"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useMappingRules.ts b/keep-ui/utils/hooks/useMappingRules.ts index cf116bc9c..49042ae09 100644 --- a/keep-ui/utils/hooks/useMappingRules.ts +++ b/keep-ui/utils/hooks/useMappingRules.ts @@ -1,5 +1,5 @@ import { MappingRule } from "app/mapping/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/usePermissions.ts b/keep-ui/utils/hooks/usePermissions.ts index b240ec2f6..05307ddc7 100644 --- a/keep-ui/utils/hooks/usePermissions.ts +++ b/keep-ui/utils/hooks/usePermissions.ts @@ -1,5 +1,5 @@ import { Permission } from "app/settings/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/usePresets.ts b/keep-ui/utils/hooks/usePresets.ts index a0a0d76e2..5065c74b9 100644 --- a/keep-ui/utils/hooks/usePresets.ts +++ b/keep-ui/utils/hooks/usePresets.ts @@ -1,6 +1,6 @@ import { useState, useEffect, useRef } from "react"; import { Preset } from "app/alerts/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useProviders.ts b/keep-ui/utils/hooks/useProviders.ts index 668af3a1e..06ad74a4d 100644 --- a/keep-ui/utils/hooks/useProviders.ts +++ b/keep-ui/utils/hooks/useProviders.ts @@ -1,4 +1,4 @@ -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "./useConfig"; import { SWRConfiguration } from "swr"; import { ProvidersResponse } from "app/providers/providers"; diff --git a/keep-ui/utils/hooks/usePusher.ts b/keep-ui/utils/hooks/usePusher.ts index f1b0c23ed..c430ef054 100644 --- a/keep-ui/utils/hooks/usePusher.ts +++ b/keep-ui/utils/hooks/usePusher.ts @@ -1,6 +1,6 @@ import Pusher, { Options as PusherOptions } from "pusher-js"; import { useConfig } from "./useConfig"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "./useConfig"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; diff --git a/keep-ui/utils/hooks/useRoles.ts b/keep-ui/utils/hooks/useRoles.ts index dabfc9b58..cf37634fa 100644 --- a/keep-ui/utils/hooks/useRoles.ts +++ b/keep-ui/utils/hooks/useRoles.ts @@ -1,5 +1,5 @@ import { Role } from "app/settings/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useRules.ts b/keep-ui/utils/hooks/useRules.ts index 97976d51e..add981b45 100644 --- a/keep-ui/utils/hooks/useRules.ts +++ b/keep-ui/utils/hooks/useRules.ts @@ -1,4 +1,4 @@ -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; diff --git a/keep-ui/utils/hooks/useScopes.ts b/keep-ui/utils/hooks/useScopes.ts index 775d8717a..122a2a289 100644 --- a/keep-ui/utils/hooks/useScopes.ts +++ b/keep-ui/utils/hooks/useScopes.ts @@ -1,5 +1,5 @@ import { Scope } from "app/settings/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useSearchAlerts.ts b/keep-ui/utils/hooks/useSearchAlerts.ts index 01de3fe14..9ef8cb0b0 100644 --- a/keep-ui/utils/hooks/useSearchAlerts.ts +++ b/keep-ui/utils/hooks/useSearchAlerts.ts @@ -1,6 +1,6 @@ import useSWR, { SWRConfiguration } from "swr"; import { AlertDto } from "app/alerts/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "./useConfig"; import { fetcher } from "utils/fetcher"; import { useDebouncedValue } from "./useDebouncedValue"; diff --git a/keep-ui/utils/hooks/useTags.ts b/keep-ui/utils/hooks/useTags.ts index 124da6649..7587c386f 100644 --- a/keep-ui/utils/hooks/useTags.ts +++ b/keep-ui/utils/hooks/useTags.ts @@ -1,4 +1,4 @@ -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useUsers.ts b/keep-ui/utils/hooks/useUsers.ts index de254e040..723045071 100644 --- a/keep-ui/utils/hooks/useUsers.ts +++ b/keep-ui/utils/hooks/useUsers.ts @@ -1,5 +1,5 @@ import { User } from "app/settings/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import useSWRImmutable from "swr/immutable"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useWorkflowExecutions.ts b/keep-ui/utils/hooks/useWorkflowExecutions.ts index 8e6fccc27..53fea2d8c 100644 --- a/keep-ui/utils/hooks/useWorkflowExecutions.ts +++ b/keep-ui/utils/hooks/useWorkflowExecutions.ts @@ -3,7 +3,7 @@ import { PaginatedWorkflowExecutionDto, WorkflowExecution, } from "app/workflows/builder/types"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useSearchParams } from "next/navigation"; import useSWR, { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; diff --git a/keep-ui/utils/hooks/useWorkflowRun.ts b/keep-ui/utils/hooks/useWorkflowRun.ts index dbaa98dc8..a645e9f86 100644 --- a/keep-ui/utils/hooks/useWorkflowRun.ts +++ b/keep-ui/utils/hooks/useWorkflowRun.ts @@ -1,5 +1,5 @@ import { useState } from "react"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { useApiUrl } from "./useConfig"; import { useRouter } from "next/navigation"; import { useProviders } from "./useProviders"; diff --git a/keep-ui/utils/hooks/useWorkflows.ts b/keep-ui/utils/hooks/useWorkflows.ts index 26859eaf2..1a8eae55c 100644 --- a/keep-ui/utils/hooks/useWorkflows.ts +++ b/keep-ui/utils/hooks/useWorkflows.ts @@ -1,5 +1,5 @@ import { Workflow } from "app/workflows/models"; -import { useSession } from "next-auth/react"; +import { useHydratedSession as useSession } from "@/shared/lib/hooks/useHydratedSession"; import { SWRConfiguration } from "swr"; import { useApiUrl } from "./useConfig"; import { fetcher } from "../fetcher"; From b96bd67eb87f2bb3198ddd79db8ca5468553c2ea Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 20 Nov 2024 11:52:51 +0200 Subject: [PATCH 5/8] feat: keep.join function for workflows (#2547) --- keep/api/core/db.py | 4 ++-- keep/functions/__init__.py | 18 +++++++++++++++++- keep/iohandler/iohandler.py | 11 ++--------- .../cloudwatch_provider/cloudwatch_provider.py | 3 +++ poetry.lock | 16 +++++++++++++++- pyproject.toml | 3 ++- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/keep/api/core/db.py b/keep/api/core/db.py index e72dce8d2..2032f1cbb 100644 --- a/keep/api/core/db.py +++ b/keep/api/core/db.py @@ -827,7 +827,7 @@ def get_last_workflow_executions(tenant_id: str, limit=20): ) return execution_with_logs - + def get_workflow_executions_count(tenant_id: str): with Session(engine) as session: @@ -1745,7 +1745,7 @@ def get_incident_for_grouping_rule( # Create and add a new incident if it doesn't exist incident = Incident( tenant_id=tenant_id, - user_generated_name=f"Incident generated by rule {rule.name}", + user_generated_name=f"{rule.name}", rule_id=rule.id, rule_fingerprint=rule_fingerprint, is_predicted=False, diff --git a/keep/functions/__init__.py b/keep/functions/__init__.py index 503021a8e..14ab6de64 100644 --- a/keep/functions/__init__.py +++ b/keep/functions/__init__.py @@ -1,11 +1,11 @@ import copy import datetime -import json import re import urllib.parse from datetime import timedelta from itertools import groupby +import json5 as json import pytz from dateutil import parser from dateutil.parser import ParserError @@ -175,6 +175,22 @@ def slice(str_to_slice: str, start: int = 0, end: int = 0) -> str: return str_to_slice[int(start) : int(end)] +def join( + iterable: list | dict | str, delimiter: str = ",", prefix: str | None = None +) -> str: + if isinstance(iterable, str): + iterable = json.loads(iterable) + + if isinstance(iterable, dict): + if prefix: + return delimiter.join([f"{prefix}{k}={v}" for k, v in iterable.items()]) + return delimiter.join([f"{k}={v}" for k, v in iterable.items()]) + + if prefix: + return delimiter.join([f"{prefix}{item}" for item in iterable]) + return delimiter.join([str(item) for item in iterable]) + + def dict_pop(data: str | dict, *args) -> dict: if isinstance(data, str): data = json.loads(data) diff --git a/keep/iohandler/iohandler.py b/keep/iohandler/iohandler.py index 7f0f22fec..4bcbb015c 100644 --- a/keep/iohandler/iohandler.py +++ b/keep/iohandler/iohandler.py @@ -520,17 +520,10 @@ def __get_short_urls(self, urls: list) -> dict: if __name__ == "__main__": # debug & test context_manager = ContextManager("keep") - context_manager.event_context = { - "ticket_id": "1234", - "severity": "high", - "ticket_created_at": "2021-09-01T00:00:00Z", - } + context_manager.event_context = {"tags": {"k1": "v1", "k2": "v2"}} iohandler = IOHandler(context_manager) res = iohandler.render( - iohandler.quote( - "not '{{ alert.ticket_id }}' or (('{{ alert.ticket_status }}' in ['Resolved', 'Closed', 'Canceled']) and ('{{ alert.severity }}' == 'critical' or keep.datetime_compare(keep.utcnow(), keep.to_utc('{{ alert.ticket_created_at }}')) > 168))" - ), - safe=False, + 'https://www.keephq.dev?keep.join("{{alert.tags}}", "&", "prefix_")' ) from asteval import Interpreter diff --git a/keep/providers/cloudwatch_provider/cloudwatch_provider.py b/keep/providers/cloudwatch_provider/cloudwatch_provider.py index 3a04a9521..be200f8ca 100644 --- a/keep/providers/cloudwatch_provider/cloudwatch_provider.py +++ b/keep/providers/cloudwatch_provider/cloudwatch_provider.py @@ -257,6 +257,7 @@ def validate_scopes(self): # 4. validate start query logs_client = self.__generate_client("logs") + query = False try: query = logs_client.start_query( logGroupName="keepTest", @@ -277,6 +278,8 @@ def validate_scopes(self): else: self.logger.info("Error validating AWS logs:StartQuery scope") scopes["logs:StartQuery"] = str(e) + + query_id = False if query: try: query_id = logs_client.describe_queries().get("queries")[0]["queryId"] diff --git a/poetry.lock b/poetry.lock index 5ed29a9fb..65fa8a5cc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2237,6 +2237,20 @@ files = [ {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, ] +[[package]] +name = "json5" +version = "0.9.28" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "json5-0.9.28-py3-none-any.whl", hash = "sha256:29c56f1accdd8bc2e037321237662034a7e07921e2b7223281a5ce2c46f0c4df"}, + {file = "json5-0.9.28.tar.gz", hash = "sha256:1f82f36e615bc5b42f1bbd49dbc94b12563c56408c6ffa06414ea310890e9a6e"}, +] + +[package.extras] +dev = ["build (==1.2.2.post1)", "coverage (==7.5.3)", "mypy (==1.13.0)", "pip (==24.3.1)", "pylint (==3.2.3)", "ruff (==0.7.3)", "twine (==5.1.1)", "uv (==0.5.1)"] + [[package]] name = "jwcrypto" version = "1.5.6" @@ -5353,4 +5367,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "d405584a8c24ff3b5e3c7f4405d24145e5b2bf7b951f5c6279977d7cd0780d5e" +content-hash = "1f7fba5a2c241db5654d7f84018d40650402bdc53e46ef5b09e7fcf3d6f055a8" diff --git a/pyproject.toml b/pyproject.toml index ee75f9569..713a701e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "keep" -version = "0.29.1" +version = "0.29.2" description = "Alerting. for developers, by developers." authors = ["Keep Alerting LTD"] readme = "README.md" @@ -95,6 +95,7 @@ networkx = "^3.3" google-auth = "2.34.0" clickhouse-driver = "^0.2.9" google-cloud-logging = "^3.11.3" +json5 = "^0.9.28" [tool.poetry.group.dev.dependencies] pre-commit = "^3.0.4" pre-commit-hooks = "^4.4.0" From dae291b5ec952ddb02b088d5098ee3bee560ae55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:10:02 +0200 Subject: [PATCH 6/8] chore(deps-dev): bump aiohttp from 3.10.2 to 3.10.11 (#2548) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 455 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 285 insertions(+), 170 deletions(-) diff --git a/poetry.lock b/poetry.lock index 65fa8a5cc..cea7ddf06 100644 --- a/poetry.lock +++ b/poetry.lock @@ -24,87 +24,102 @@ files = [ [[package]] name = "aiohttp" -version = "3.10.2" +version = "3.10.11" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95213b3d79c7e387144e9cb7b9d2809092d6ff2c044cb59033aedc612f38fb6d"}, - {file = "aiohttp-3.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1aa005f060aff7124cfadaa2493f00a4e28ed41b232add5869e129a2e395935a"}, - {file = "aiohttp-3.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eabe6bf4c199687592f5de4ccd383945f485779c7ffb62a9b9f1f8a3f9756df8"}, - {file = "aiohttp-3.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e010736fc16d21125c7e2dc5c350cd43c528b85085c04bf73a77be328fe944"}, - {file = "aiohttp-3.10.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99f81f9c1529fd8e03be4a7bd7df32d14b4f856e90ef6e9cbad3415dbfa9166c"}, - {file = "aiohttp-3.10.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d611d1a01c25277bcdea06879afbc11472e33ce842322496b211319aa95441bb"}, - {file = "aiohttp-3.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00191d38156e09e8c81ef3d75c0d70d4f209b8381e71622165f22ef7da6f101"}, - {file = "aiohttp-3.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74c091a5ded6cb81785de2d7a8ab703731f26de910dbe0f3934eabef4ae417cc"}, - {file = "aiohttp-3.10.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:18186a80ec5a701816adbf1d779926e1069392cf18504528d6e52e14b5920525"}, - {file = "aiohttp-3.10.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5a7ceb2a0d2280f23a02c64cd0afdc922079bb950400c3dd13a1ab2988428aac"}, - {file = "aiohttp-3.10.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8bd7be6ff6c162a60cb8fce65ee879a684fbb63d5466aba3fa5b9288eb04aefa"}, - {file = "aiohttp-3.10.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fae962b62944eaebff4f4fddcf1a69de919e7b967136a318533d82d93c3c6bd1"}, - {file = "aiohttp-3.10.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a0fde16d284efcacbe15fb0c1013f0967b6c3e379649239d783868230bf1db42"}, - {file = "aiohttp-3.10.2-cp310-cp310-win32.whl", hash = "sha256:f81cd85a0e76ec7b8e2b6636fe02952d35befda4196b8c88f3cec5b4fb512839"}, - {file = "aiohttp-3.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:54ba10eb5a3481c28282eb6afb5f709aedf53cf9c3a31875ffbdc9fc719ffd67"}, - {file = "aiohttp-3.10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:87fab7f948e407444c2f57088286e00e2ed0003ceaf3d8f8cc0f60544ba61d91"}, - {file = "aiohttp-3.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ec6ad66ed660d46503243cbec7b2b3d8ddfa020f984209b3b8ef7d98ce69c3f2"}, - {file = "aiohttp-3.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4be88807283bd96ae7b8e401abde4ca0bab597ba73b5e9a2d98f36d451e9aac"}, - {file = "aiohttp-3.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01c98041f90927c2cbd72c22a164bb816fa3010a047d264969cf82e1d4bcf8d1"}, - {file = "aiohttp-3.10.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54e36c67e1a9273ecafab18d6693da0fb5ac48fd48417e4548ac24a918c20998"}, - {file = "aiohttp-3.10.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7de3ddb6f424af54535424082a1b5d1ae8caf8256ebd445be68c31c662354720"}, - {file = "aiohttp-3.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dd9c7db94b4692b827ce51dcee597d61a0e4f4661162424faf65106775b40e7"}, - {file = "aiohttp-3.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e57e21e1167705f8482ca29cc5d02702208d8bf4aff58f766d94bcd6ead838cd"}, - {file = "aiohttp-3.10.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a1a50e59b720060c29e2951fd9f13c01e1ea9492e5a527b92cfe04dd64453c16"}, - {file = "aiohttp-3.10.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:686c87782481fda5ee6ba572d912a5c26d9f98cc5c243ebd03f95222af3f1b0f"}, - {file = "aiohttp-3.10.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dafb4abb257c0ed56dc36f4e928a7341b34b1379bd87e5a15ce5d883c2c90574"}, - {file = "aiohttp-3.10.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:494a6f77560e02bd7d1ab579fdf8192390567fc96a603f21370f6e63690b7f3d"}, - {file = "aiohttp-3.10.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6fe8503b1b917508cc68bf44dae28823ac05e9f091021e0c41f806ebbb23f92f"}, - {file = "aiohttp-3.10.2-cp311-cp311-win32.whl", hash = "sha256:4ddb43d06ce786221c0dfd3c91b4892c318eaa36b903f7c4278e7e2fa0dd5102"}, - {file = "aiohttp-3.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:ca2f5abcb0a9a47e56bac173c01e9f6c6e7f27534d91451c5f22e6a35a5a2093"}, - {file = "aiohttp-3.10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:14eb6b17f6246959fb0b035d4f4ae52caa870c4edfb6170aad14c0de5bfbf478"}, - {file = "aiohttp-3.10.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:465e445ec348d4e4bd349edd8b22db75f025da9d7b6dc1369c48e7935b85581e"}, - {file = "aiohttp-3.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:341f8ece0276a828d95b70cd265d20e257f5132b46bf77d759d7f4e0443f2906"}, - {file = "aiohttp-3.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c01fbb87b5426381cd9418b3ddcf4fc107e296fa2d3446c18ce6c76642f340a3"}, - {file = "aiohttp-3.10.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c474af073e1a6763e1c5522bbb2d85ff8318197e4c6c919b8d7886e16213345"}, - {file = "aiohttp-3.10.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d9076810a5621236e29b2204e67a68e1fe317c8727ee4c9abbfbb1083b442c38"}, - {file = "aiohttp-3.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8f515d6859e673940e08de3922b9c4a2249653b0ac181169313bd6e4b1978ac"}, - {file = "aiohttp-3.10.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:655e583afc639bef06f3b2446972c1726007a21003cd0ef57116a123e44601bc"}, - {file = "aiohttp-3.10.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8da9449a575133828cc99985536552ea2dcd690e848f9d41b48d8853a149a959"}, - {file = "aiohttp-3.10.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:19073d57d0feb1865d12361e2a1f5a49cb764bf81a4024a3b608ab521568093a"}, - {file = "aiohttp-3.10.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8e98e1845805f184d91fda6f9ab93d7c7b0dddf1c07e0255924bfdb151a8d05"}, - {file = "aiohttp-3.10.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:377220a5efde6f9497c5b74649b8c261d3cce8a84cb661be2ed8099a2196400a"}, - {file = "aiohttp-3.10.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92f7f4a4dc9cdb5980973a74d43cdbb16286dacf8d1896b6c3023b8ba8436f8e"}, - {file = "aiohttp-3.10.2-cp312-cp312-win32.whl", hash = "sha256:9bb2834a6f11d65374ce97d366d6311a9155ef92c4f0cee543b2155d06dc921f"}, - {file = "aiohttp-3.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:518dc3cb37365255708283d1c1c54485bbacccd84f0a0fb87ed8917ba45eda5b"}, - {file = "aiohttp-3.10.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7f98e70bbbf693086efe4b86d381efad8edac040b8ad02821453083d15ec315f"}, - {file = "aiohttp-3.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9f6f0b252a009e98fe84028a4ec48396a948e7a65b8be06ccfc6ef68cf1f614d"}, - {file = "aiohttp-3.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9360e3ffc7b23565600e729e8c639c3c50d5520e05fdf94aa2bd859eef12c407"}, - {file = "aiohttp-3.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3988044d1635c7821dd44f0edfbe47e9875427464e59d548aece447f8c22800a"}, - {file = "aiohttp-3.10.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a9d59da1543a6f1478c3436fd49ec59be3868bca561a33778b4391005e499d"}, - {file = "aiohttp-3.10.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f49bdb94809ac56e09a310a62f33e5f22973d6fd351aac72a39cd551e98194"}, - {file = "aiohttp-3.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddfd2dca3f11c365d6857a07e7d12985afc59798458a2fdb2ffa4a0332a3fd43"}, - {file = "aiohttp-3.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:685c1508ec97b2cd3e120bfe309a4ff8e852e8a7460f1ef1de00c2c0ed01e33c"}, - {file = "aiohttp-3.10.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:49904f38667c44c041a0b44c474b3ae36948d16a0398a8f8cd84e2bb3c42a069"}, - {file = "aiohttp-3.10.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:352f3a4e5f11f3241a49b6a48bc5b935fabc35d1165fa0d87f3ca99c1fcca98b"}, - {file = "aiohttp-3.10.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:fc61f39b534c5d5903490478a0dd349df397d2284a939aa3cbaa2fb7a19b8397"}, - {file = "aiohttp-3.10.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:ad2274e707be37420d0b6c3d26a8115295fe9d8e6e530fa6a42487a8ca3ad052"}, - {file = "aiohttp-3.10.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c836bf3c7512100219fe1123743fd8dd9a2b50dd7cfb0c3bb10d041309acab4b"}, - {file = "aiohttp-3.10.2-cp38-cp38-win32.whl", hash = "sha256:53e8898adda402be03ff164b0878abe2d884e3ea03a4701e6ad55399d84b92dc"}, - {file = "aiohttp-3.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:7cc8f65f5b22304693de05a245b6736b14cb5bc9c8a03da6e2ae9ef15f8b458f"}, - {file = "aiohttp-3.10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9dfc906d656e14004c5bc672399c1cccc10db38df2b62a13fb2b6e165a81c316"}, - {file = "aiohttp-3.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:91b10208b222ddf655c3a3d5b727879d7163db12b634492df41a9182a76edaae"}, - {file = "aiohttp-3.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9fd16b5e1a7bdd14668cd6bde60a2a29b49147a535c74f50d8177d11b38433a7"}, - {file = "aiohttp-3.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2bfdda4971bd79201f59adbad24ec2728875237e1c83bba5221284dbbf57bda"}, - {file = "aiohttp-3.10.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69d73f869cf29e8a373127fc378014e2b17bcfbe8d89134bc6fb06a2f67f3cb3"}, - {file = "aiohttp-3.10.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df59f8486507c421c0620a2c3dce81fbf1d54018dc20ff4fecdb2c106d6e6abc"}, - {file = "aiohttp-3.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df930015db36b460aa9badbf35eccbc383f00d52d4b6f3de2ccb57d064a6ade"}, - {file = "aiohttp-3.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:562b1153ab7f766ee6b8b357ec777a302770ad017cf18505d34f1c088fccc448"}, - {file = "aiohttp-3.10.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d984db6d855de58e0fde1ef908d48fe9a634cadb3cf715962722b4da1c40619d"}, - {file = "aiohttp-3.10.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:14dc3fcb0d877911d775d511eb617a486a8c48afca0a887276e63db04d3ee920"}, - {file = "aiohttp-3.10.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b52a27a5c97275e254704e1049f4b96a81e67d6205f52fa37a4777d55b0e98ef"}, - {file = "aiohttp-3.10.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:cd33d9de8cfd006a0d0fe85f49b4183c57e91d18ffb7e9004ce855e81928f704"}, - {file = "aiohttp-3.10.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1238fc979160bc03a92fff9ad021375ff1c8799c6aacb0d8ea1b357ea40932bb"}, - {file = "aiohttp-3.10.2-cp39-cp39-win32.whl", hash = "sha256:e2f43d238eae4f0b04f58d4c0df4615697d4ca3e9f9b1963d49555a94f0f5a04"}, - {file = "aiohttp-3.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:947847f07a8f81d7b39b2d0202fd73e61962ebe17ac2d8566f260679e467da7b"}, - {file = "aiohttp-3.10.2.tar.gz", hash = "sha256:4d1f694b5d6e459352e5e925a42e05bac66655bfde44d81c59992463d2897014"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"}, + {file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"}, + {file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"}, + {file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"}, + {file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"}, + {file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"}, + {file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"}, + {file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"}, + {file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"}, + {file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"}, + {file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"}, + {file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"}, + {file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"}, + {file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"}, ] [package.dependencies] @@ -113,7 +128,7 @@ aiosignal = ">=1.1.2" attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.0,<2.0" +yarl = ">=1.12.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] @@ -3387,6 +3402,113 @@ wcwidth = "*" [package.extras] tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"] +[[package]] +name = "propcache" +version = "0.2.0" +description = "Accelerated property cache" +optional = false +python-versions = ">=3.8" +files = [ + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, + {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, + {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, + {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, + {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, + {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, + {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, + {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, + {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, +] + [[package]] name = "proto-plus" version = "1.23.0" @@ -5248,106 +5370,99 @@ dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] [[package]] name = "yarl" -version = "1.9.4" +version = "1.17.2" description = "Yet another URL library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, - {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, - {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, - {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, - {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, - {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, - {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, - {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, - {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, - {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, - {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, - {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, - {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, - {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, - {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, - {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93771146ef048b34201bfa382c2bf74c524980870bb278e6df515efaf93699ff"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8281db240a1616af2f9c5f71d355057e73a1409c4648c8949901396dc0a3c151"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:170ed4971bf9058582b01a8338605f4d8c849bd88834061e60e83b52d0c76870"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc61b005f6521fcc00ca0d1243559a5850b9dd1e1fe07b891410ee8fe192d0c0"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871e1b47eec7b6df76b23c642a81db5dd6536cbef26b7e80e7c56c2fd371382e"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a58a2f2ca7aaf22b265388d40232f453f67a6def7355a840b98c2d547bd037f"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:736bb076f7299c5c55dfef3eb9e96071a795cb08052822c2bb349b06f4cb2e0a"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fd51299e21da709eabcd5b2dd60e39090804431292daacbee8d3dabe39a6bc0"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:358dc7ddf25e79e1cc8ee16d970c23faee84d532b873519c5036dbb858965795"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:50d866f7b1a3f16f98603e095f24c0eeba25eb508c85a2c5939c8b3870ba2df8"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b9c4643e7d843a0dca9cd9d610a0876e90a1b2cbc4c5ba7930a0d90baf6903f"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d63123bfd0dce5f91101e77c8a5427c3872501acece8c90df457b486bc1acd47"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4e76381be3d8ff96a4e6c77815653063e87555981329cf8f85e5be5abf449021"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:734144cd2bd633a1516948e477ff6c835041c0536cef1d5b9a823ae29899665b"}, + {file = "yarl-1.17.2-cp310-cp310-win32.whl", hash = "sha256:26bfb6226e0c157af5da16d2d62258f1ac578d2899130a50433ffee4a5dfa673"}, + {file = "yarl-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:76499469dcc24759399accd85ec27f237d52dec300daaca46a5352fcbebb1071"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:792155279dc093839e43f85ff7b9b6493a8eaa0af1f94f1f9c6e8f4de8c63500"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38bc4ed5cae853409cb193c87c86cd0bc8d3a70fd2268a9807217b9176093ac6"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4a8c83f6fcdc327783bdc737e8e45b2e909b7bd108c4da1892d3bc59c04a6d84"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6d5fed96f0646bfdf698b0a1cebf32b8aae6892d1bec0c5d2d6e2df44e1e2d"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:782ca9c58f5c491c7afa55518542b2b005caedaf4685ec814fadfcee51f02493"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff6af03cac0d1a4c3c19e5dcc4c05252411bf44ccaa2485e20d0a7c77892ab6e"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a3f47930fbbed0f6377639503848134c4aa25426b08778d641491131351c2c8"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1fa68a3c921365c5745b4bd3af6221ae1f0ea1bf04b69e94eda60e57958907f"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:187df91395c11e9f9dc69b38d12406df85aa5865f1766a47907b1cc9855b6303"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:93d1c8cc5bf5df401015c5e2a3ce75a5254a9839e5039c881365d2a9dcfc6dc2"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11d86c6145ac5c706c53d484784cf504d7d10fa407cb73b9d20f09ff986059ef"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c42774d1d1508ec48c3ed29e7b110e33f5e74a20957ea16197dbcce8be6b52ba"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8e589379ef0407b10bed16cc26e7392ef8f86961a706ade0a22309a45414d7"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1056cadd5e850a1c026f28e0704ab0a94daaa8f887ece8dfed30f88befb87bb0"}, + {file = "yarl-1.17.2-cp311-cp311-win32.whl", hash = "sha256:be4c7b1c49d9917c6e95258d3d07f43cfba2c69a6929816e77daf322aaba6628"}, + {file = "yarl-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:ac8eda86cc75859093e9ce390d423aba968f50cf0e481e6c7d7d63f90bae5c9c"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dd90238d3a77a0e07d4d6ffdebc0c21a9787c5953a508a2231b5f191455f31e9"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c74f0b0472ac40b04e6d28532f55cac8090e34c3e81f118d12843e6df14d0909"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d486ddcaca8c68455aa01cf53d28d413fb41a35afc9f6594a730c9779545876"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25b7e93f5414b9a983e1a6c1820142c13e1782cc9ed354c25e933aebe97fcf2"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a0baff7827a632204060f48dca9e63fbd6a5a0b8790c1a2adfb25dc2c9c0d50"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:460024cacfc3246cc4d9f47a7fc860e4fcea7d1dc651e1256510d8c3c9c7cde0"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5870d620b23b956f72bafed6a0ba9a62edb5f2ef78a8849b7615bd9433384171"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2941756754a10e799e5b87e2319bbec481ed0957421fba0e7b9fb1c11e40509f"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9611b83810a74a46be88847e0ea616794c406dbcb4e25405e52bff8f4bee2d0a"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cd7e35818d2328b679a13268d9ea505c85cd773572ebb7a0da7ccbca77b6a52e"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6b981316fcd940f085f646b822c2ff2b8b813cbd61281acad229ea3cbaabeb6b"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:688058e89f512fb7541cb85c2f149c292d3fa22f981d5a5453b40c5da49eb9e8"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56afb44a12b0864d17b597210d63a5b88915d680f6484d8d202ed68ade38673d"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:17931dfbb84ae18b287279c1f92b76a3abcd9a49cd69b92e946035cff06bcd20"}, + {file = "yarl-1.17.2-cp312-cp312-win32.whl", hash = "sha256:ff8d95e06546c3a8c188f68040e9d0360feb67ba8498baf018918f669f7bc39b"}, + {file = "yarl-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:4c840cc11163d3c01a9d8aad227683c48cd3e5be5a785921bcc2a8b4b758c4f3"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3294f787a437cb5d81846de3a6697f0c35ecff37a932d73b1fe62490bef69211"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1e7fedb09c059efee2533119666ca7e1a2610072076926fa028c2ba5dfeb78c"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da9d3061e61e5ae3f753654813bc1cd1c70e02fb72cf871bd6daf78443e9e2b1"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91c012dceadc695ccf69301bfdccd1fc4472ad714fe2dd3c5ab4d2046afddf29"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f11fd61d72d93ac23718d393d2a64469af40be2116b24da0a4ca6922df26807e"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46c465ad06971abcf46dd532f77560181387b4eea59084434bdff97524444032"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef6eee1a61638d29cd7c85f7fd3ac7b22b4c0fabc8fd00a712b727a3e73b0685"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4434b739a8a101a837caeaa0137e0e38cb4ea561f39cb8960f3b1e7f4967a3fc"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:752485cbbb50c1e20908450ff4f94217acba9358ebdce0d8106510859d6eb19a"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:17791acaa0c0f89323c57da7b9a79f2174e26d5debbc8c02d84ebd80c2b7bff8"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5c6ea72fe619fee5e6b5d4040a451d45d8175f560b11b3d3e044cd24b2720526"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db5ac3871ed76340210fe028f535392f097fb31b875354bcb69162bba2632ef4"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7a1606ba68e311576bcb1672b2a1543417e7e0aa4c85e9e718ba6466952476c0"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9bc27dd5cfdbe3dc7f381b05e6260ca6da41931a6e582267d5ca540270afeeb2"}, + {file = "yarl-1.17.2-cp313-cp313-win32.whl", hash = "sha256:52492b87d5877ec405542f43cd3da80bdcb2d0c2fbc73236526e5f2c28e6db28"}, + {file = "yarl-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:8e1bf59e035534ba4077f5361d8d5d9194149f9ed4f823d1ee29ef3e8964ace3"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c556fbc6820b6e2cda1ca675c5fa5589cf188f8da6b33e9fc05b002e603e44fa"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f44a4247461965fed18b2573f3a9eb5e2c3cad225201ee858726cde610daca"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a3ede8c248f36b60227eb777eac1dbc2f1022dc4d741b177c4379ca8e75571a"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2654caaf5584449d49c94a6b382b3cb4a246c090e72453493ea168b931206a4d"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d41c684f286ce41fa05ab6af70f32d6da1b6f0457459a56cf9e393c1c0b2217"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2270d590997445a0dc29afa92e5534bfea76ba3aea026289e811bf9ed4b65a7f"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18662443c6c3707e2fc7fad184b4dc32dd428710bbe72e1bce7fe1988d4aa654"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75ac158560dec3ed72f6d604c81090ec44529cfb8169b05ae6fcb3e986b325d9"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1fee66b32e79264f428dc8da18396ad59cc48eef3c9c13844adec890cd339db5"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:585ce7cd97be8f538345de47b279b879e091c8b86d9dbc6d98a96a7ad78876a3"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c019abc2eca67dfa4d8fb72ba924871d764ec3c92b86d5b53b405ad3d6aa56b0"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c6e659b9a24d145e271c2faf3fa6dd1fcb3e5d3f4e17273d9e0350b6ab0fe6e2"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d17832ba39374134c10e82d137e372b5f7478c4cceeb19d02ae3e3d1daed8721"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bc3003710e335e3f842ae3fd78efa55f11a863a89a72e9a07da214db3bf7e1f8"}, + {file = "yarl-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f5ffc6b7ace5b22d9e73b2a4c7305740a339fbd55301d52735f73e21d9eb3130"}, + {file = "yarl-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:48e424347a45568413deec6f6ee2d720de2cc0385019bedf44cd93e8638aa0ed"}, + {file = "yarl-1.17.2-py3-none-any.whl", hash = "sha256:dd7abf4f717e33b7487121faf23560b3a50924f80e4bef62b22dab441ded8f3b"}, + {file = "yarl-1.17.2.tar.gz", hash = "sha256:753eaaa0c7195244c84b5cc159dc8204b7fd99f716f11198f999f2332a86b178"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" +propcache = ">=0.2.0" [[package]] name = "zipp" From 57df5a19fac0a516848cb01c23776af554f8f6c8 Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 20 Nov 2024 12:49:44 +0200 Subject: [PATCH 7/8] fix: failing tests due to change in incident name (#2550) --- keep/api/routes/preset.py | 12 +++--- keep/functions/__init__.py | 5 ++- .../pagerduty_provider/pagerduty_provider.py | 9 ++++- tests/test_rules_engine.py | 39 ++++++++++++------- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/keep/api/routes/preset.py b/keep/api/routes/preset.py index a5051650f..1f3f9b22a 100644 --- a/keep/api/routes/preset.py +++ b/keep/api/routes/preset.py @@ -137,10 +137,10 @@ def pull_data_from_providers( f"Provider {provider.type} ({provider.id}) does not implement pulling incidents", extra=extra, ) - except Exception as e: - logger.error( + except Exception: + logger.exception( f"Unknown error pulling incidents from provider {provider.type} ({provider.id})", - extra={**extra, "error": str(e)}, + extra={**extra, "trace_id": trace_id}, ) else: logger.debug( @@ -165,10 +165,10 @@ def pull_data_from_providers( f"Provider {provider.type} ({provider.id}) does not implement pulling topology data", extra=extra, ) - except Exception as e: - logger.error( + except Exception: + logger.exception( f"Unknown error pulling topology from provider {provider.type} ({provider.id})", - extra={**extra, "error": str(e)}, + extra={**extra}, ) for fingerprint, alert in sorted_provider_alerts_by_fingerprint.items(): diff --git a/keep/functions/__init__.py b/keep/functions/__init__.py index 14ab6de64..b5a8b665d 100644 --- a/keep/functions/__init__.py +++ b/keep/functions/__init__.py @@ -1,11 +1,12 @@ import copy import datetime +import json import re import urllib.parse from datetime import timedelta from itertools import groupby -import json5 as json +import json5 import pytz from dateutil import parser from dateutil.parser import ParserError @@ -179,7 +180,7 @@ def join( iterable: list | dict | str, delimiter: str = ",", prefix: str | None = None ) -> str: if isinstance(iterable, str): - iterable = json.loads(iterable) + iterable = json5.loads(iterable) if isinstance(iterable, dict): if prefix: diff --git a/keep/providers/pagerduty_provider/pagerduty_provider.py b/keep/providers/pagerduty_provider/pagerduty_provider.py index 5e9ea7e2a..2f6ecc8c4 100644 --- a/keep/providers/pagerduty_provider/pagerduty_provider.py +++ b/keep/providers/pagerduty_provider/pagerduty_provider.py @@ -575,6 +575,7 @@ def _query(self, incident_id: str = None): else incidents ) + @staticmethod def _format_alert( event: dict, provider_instance: "BaseProvider" = None ) -> AlertDto: @@ -791,11 +792,15 @@ def _get_incidents(self) -> list[IncidentDto]: raw_incidents = self.__get_all_incidents_or_alerts() incidents = [] for incident in raw_incidents: - incident_dto = self._format_incident({"event": {"data": incident}}) + incident_dto = PagerdutyProvider._format_incident( + {"event": {"data": incident}} + ) incident_alerts = self.__get_all_incidents_or_alerts( incident_id=incident_dto.fingerprint ) - incident_alerts = [self._format_alert(alert) for alert in incident_alerts] + incident_alerts = [ + PagerdutyProvider._format_alert(alert) for alert in incident_alerts + ] incident_dto._alerts = incident_alerts incidents.append(incident_dto) return incidents diff --git a/tests/test_rules_engine.py b/tests/test_rules_engine.py index 5abf1f5a9..40627b372 100644 --- a/tests/test_rules_engine.py +++ b/tests/test_rules_engine.py @@ -2,16 +2,21 @@ import hashlib import json import os -import time import uuid import pytest -from sqlalchemy import desc, asc -from keep.api.core.db import create_rule as create_rule_db, get_last_incidents, get_incident_alerts_by_incident_id +from keep.api.core.db import create_rule as create_rule_db +from keep.api.core.db import get_incident_alerts_by_incident_id, get_last_incidents from keep.api.core.db import get_rules as get_rules_db from keep.api.core.dependencies import SINGLE_TENANT_UUID -from keep.api.models.alert import AlertDto, AlertSeverity, AlertStatus, IncidentSeverity, IncidentStatus +from keep.api.models.alert import ( + AlertDto, + AlertSeverity, + AlertStatus, + IncidentSeverity, + IncidentStatus, +) from keep.api.models.db.alert import Alert from keep.api.models.db.rule import ResolveOn from keep.rulesengine.rulesengine import RulesEngine @@ -264,9 +269,12 @@ def test_incident_attributes(db_session): # check that there are results assert results is not None assert len(results) == 1 - assert results[0].user_generated_name == "Incident generated by rule {}".format(rules[0].name) + assert results[0].user_generated_name == "{}".format(rules[0].name) assert results[0].alerts_count == i + 1 - assert results[0].last_seen_time.isoformat(timespec='milliseconds')+"Z" == alert.lastReceived + assert ( + results[0].last_seen_time.isoformat(timespec="milliseconds") + "Z" + == alert.lastReceived + ) assert results[0].start_time == alerts[0].timestamp @@ -322,7 +330,7 @@ def test_incident_severity(db_session): # check that there are results assert results is not None assert len(results) == 1 - assert results[0].user_generated_name == "Incident generated by rule {}".format(rules[0].name) + assert results[0].user_generated_name == "{}".format(rules[0].name) assert results[0].alerts_count == 3 assert results[0].severity.value == IncidentSeverity.INFO.value @@ -341,7 +349,7 @@ def test_incident_resolution_on_all(db_session, create_alert): definition_cel='(severity == "critical")', created_by="test@keephq.dev", require_approve=False, - resolve_on=ResolveOn.ALL.value + resolve_on=ResolveOn.ALL.value, ) incidents, total_count = get_last_incidents( @@ -353,13 +361,13 @@ def test_incident_resolution_on_all(db_session, create_alert): assert total_count == 0 create_alert( - f"Something went wrong", + "Something went wrong", AlertStatus.FIRING, datetime.datetime.utcnow(), {"severity": AlertSeverity.CRITICAL.value}, ) create_alert( - f"Something went wrong again", + "Something went wrong again", AlertStatus.FIRING, datetime.datetime.utcnow(), {"severity": AlertSeverity.CRITICAL.value}, @@ -387,7 +395,7 @@ def test_incident_resolution_on_all(db_session, create_alert): # Same fingerprint create_alert( - f"Something went wrong", + "Something went wrong", AlertStatus.RESOLVED, datetime.datetime.utcnow(), {"severity": AlertSeverity.CRITICAL.value}, @@ -415,7 +423,7 @@ def test_incident_resolution_on_all(db_session, create_alert): assert incident.status == IncidentStatus.FIRING.value create_alert( - f"Something went wrong again", + "Something went wrong again", AlertStatus.RESOLVED, datetime.datetime.utcnow(), {"severity": AlertSeverity.CRITICAL.value}, @@ -444,9 +452,11 @@ def test_incident_resolution_on_all(db_session, create_alert): @pytest.mark.parametrize( "direction,second_fire_order", - [(ResolveOn.FIRST.value, ('fp2', 'fp1')), (ResolveOn.LAST.value, ('fp2', 'fp1'))] + [(ResolveOn.FIRST.value, ("fp2", "fp1")), (ResolveOn.LAST.value, ("fp2", "fp1"))], ) -def test_incident_resolution_on_edge(db_session, create_alert, direction, second_fire_order): +def test_incident_resolution_on_edge( + db_session, create_alert, direction, second_fire_order +): create_rule_db( tenant_id=SINGLE_TENANT_UUID, @@ -560,6 +570,7 @@ def test_incident_resolution_on_edge(db_session, create_alert, direction, second assert alert_count == 2 assert incident.status == IncidentStatus.RESOLVED.value + # Next steps: # - test that alerts in the same group are being updated correctly # - test group are being updated correctly From 917cbc549c2a25fa13fbac23794c3b9327303232 Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 20 Nov 2024 13:14:19 +0200 Subject: [PATCH 8/8] fix(pagerduty): enforce new format (#2552) --- keep/providers/pagerduty_provider/pagerduty_provider.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/keep/providers/pagerduty_provider/pagerduty_provider.py b/keep/providers/pagerduty_provider/pagerduty_provider.py index 2f6ecc8c4..598cf091b 100644 --- a/keep/providers/pagerduty_provider/pagerduty_provider.py +++ b/keep/providers/pagerduty_provider/pagerduty_provider.py @@ -577,7 +577,9 @@ def _query(self, incident_id: str = None): @staticmethod def _format_alert( - event: dict, provider_instance: "BaseProvider" = None + event: dict, + provider_instance: "BaseProvider" = None, + force_new_format: bool = False, ) -> AlertDto: # If somebody connected the provider before we refactored it old_format_event = event.get("event", {}) @@ -622,7 +624,7 @@ def _format_alert_old(event: dict) -> AlertDto: last_received = data.pop( "created_at", datetime.datetime.now(tz=datetime.timezone.utc).isoformat() ) - name = data.pop("title") + name = data.pop("title", "unknown title") service = data.pop("service", {}).get("summary", "unknown") environment = next( iter( @@ -799,7 +801,8 @@ def _get_incidents(self) -> list[IncidentDto]: incident_id=incident_dto.fingerprint ) incident_alerts = [ - PagerdutyProvider._format_alert(alert) for alert in incident_alerts + PagerdutyProvider._format_alert(alert, None, force_new_format=True) + for alert in incident_alerts ] incident_dto._alerts = incident_alerts incidents.append(incident_dto)