diff --git a/.env.example b/.env.example index bc7473f..cf9989f 100644 --- a/.env.example +++ b/.env.example @@ -1,11 +1,56 @@ ANONYMIZED_TELEMETRY=false +# ========== LLM ========== + GOOGLE_API_KEY= # 권장 (다른 모델로 교체 가능) [다른 모델로 교체시 성능 보장 불가] GOOGLE_MODEL=gemini-2.5-flash-preview-05-20 -GOOGLE_PLANNER_MODEL=gemini-2.5-flash-preview-05-20 +#GOOGLE_PLANNER_MODEL=gemini-2.5-flash-preview-05-20 + +# min(INITIAL_BACKOFF * (2 ** try_cnt), MAX_BACKOFF)만큼 API가 실패시 대기합니다. +INITIAL_BACKOFF=60 +MAX_BACKOFF=600 + +# ========== Monitoring ========== # 선택 PROXY_HOST=127.0.0.1 PROXY_PORT=11080 -BACKEND_URL=http://localhost:11081 \ No newline at end of file +BACKEND_URL=http://localhost:11081 + +# https://docs.browser-use.com/development/observability +# Lmnr 계정이 필요합니다. +# https://lmnr.ai/ +LMNR_PROJECT_API_KEY= + +# 브라우저 언어 설정 +LANG=en_US + +# ========= Account ========== + +# 필수 뒤에 있는 이메일 주소는 Google 계정의 로그인 힌트로 사용됩니다. +# 이메일의 전체를 입력해주세요 +GOOGLE_ID=bot.imnya.ng@gmail.com + +# provider 계정 (본인이 사용하지 않는 계정 권장) (Github, apple, kakao등 다른 계정 추가 가능) +# PROVIDOR_CREDENTIALS_IN_LLM는 True로 설정시, 아래 계정 정보가 LLM에 포함되어 사용됩니다. +# 쿠키와 로컬스토리지 사용은 제외됩니다. +PROVIDOR_CREDENTIALS_IN_LLM=False + +GOOGLE_ID= +GOOGLE_PASSWORD= + +NAVER_ID= +NAVER_PASSWORD= + +FACEBOOK_ID= +FACEBOOK_PASSWORD= + +GITGUB_ID= +GITHUB_PASSWORD= + +LinkedIn_ID= +LinkedIn_PASSWORD= + +Microsoft_ID= +Microsoft_PASSWORD= \ No newline at end of file diff --git a/README.md b/README.md index b4101c4..7cbd443 100644 --- a/README.md +++ b/README.md @@ -6,25 +6,39 @@ # 환경 설정 이 프로젝트는 [uv](https://docs.astral.sh/uv/getting-started/installation/)라는 Python 패키지 관리자를 사용하여 설정해야합니다. -또한 [oauth-backend](https://github.com/j93es/oauth-backend)가 설정된 상태여야만 합니다. + +또한 [oauth-backend](https://github.com/j93es/oauth-backend)가 설정되길 권장합니다. +> 프록시를 사용한다면 이 가이드에 따라 인증서 또한 설정되어야만 합니다. +> +> 그렇지 않으면 실행되지 않습니다. +> +> 윈도우 환경에서는 `sudo certutil -addstore root mitmproxy-ca-cert.cer`로 인증합니다. +> +> Sudo가 활성화되어있지 않은 환경에서는 관리자로 상향된 쉘에서 실행합니다. +> +> MacOS 환경에서는 `sudo security add-trusted-cert -d -p ssl -p basic -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem`으로 인증합니다. +> +> 다른 플렛폼은 수동으로 설정되어야만 합니다. +> https://docs.mitmproxy.org/stable/concepts/certificates/ + +--- uv 설치 후 다음과 같은 명령어를 입력합니다. -``` +```sh uv sync ``` venv와 패키지가 설치가 됩니다. -browser_use가 Playwright에 대한 의존성이 있어 브라우저 설치가 필요합니다 +~~browser_use가 Playwright에 대한 의존성이 있어 브라우저 설치가 필요합니다~~ + +스텔스 기능 때문에 Chrome이 필요합니다. -``` -playwright install chromium --with-deps --no-shell -``` 다음과 같은 명령어로 실행합니다. -``` +```sh uv run main.py ``` @@ -32,6 +46,12 @@ Environment는 .env.example에 따라 설정되어야합니다. .env.example을 .env로 복사하여서 사용해주세요. +# 쿠키와 로컬 스토리지 설정 방법 + +```sh +uv run playwright open https://google.com/ --save-storage=./data/storage_state.json +``` + # 실행 ```sh @@ -44,6 +64,8 @@ curl "https://f.imnya.ng/.whs/tp-domains/data/domains/latest.txt" -o domains.txt ```pwsh +# domains.txt 받기 +curl "https://f.imnya.ng/.whs/tp-domains/data/domains/latest.txt" -o domains.txt # ./run.ps1 {domains.txt 시작 줄} {domains.txt 끝 줄} {HTML 검사 Skip} ./run.ps1 12540 13000 False ``` diff --git a/lib/browser_config.py b/lib/browser_config.py deleted file mode 100644 index a4b1e39..0000000 --- a/lib/browser_config.py +++ /dev/null @@ -1,29 +0,0 @@ -from browser_use.browser.context import BrowserContextConfig -from pathlib import Path -import os - -from typing import Any - -def browser_config_kwargs(lang: str = "en_US") -> dict[str, Any]: - browser_config_kwargs: dict[str, Any] = { - "keep_alive": True, - "browser_type": "chromium", - "headless": False, - "disable_security": True, - "extra_browser_args": [ - "--disable-web-security", - "--disable-features=IsolateOrigins,site-per-process", - "--disable-popup-blocking", - f"--lang={lang}", - "--ignore-certificate-errors" - ], - } - - proxy_host = os.getenv("PROXY_HOST") - proxy_port = os.getenv("PROXY_PORT") - if proxy_host and proxy_port: - browser_config_kwargs["extra_browser_args"].append( - f"--proxy-server=http={proxy_host}:{proxy_port};https={proxy_host}:{proxy_port}" - ) - - return browser_config_kwargs \ No newline at end of file diff --git a/lib/llm/__init__.py b/lib/llm/__init__.py new file mode 100644 index 0000000..2c41b3f --- /dev/null +++ b/lib/llm/__init__.py @@ -0,0 +1,25 @@ +from langchain.callbacks.base import BaseCallbackHandler +from langchain_google_genai import ChatGoogleGenerativeAI + +class QuotaExhaustedHandler(BaseCallbackHandler): + def on_llm_error(self, error, **kwargs): + if "ResourceExhausted" in str(error) or "429" in str(error): + print("⚠️ API 쿼터가 소진되었습니다. 재시도 로직에 위임합니다...") + # backoff handled in scan_one_url + +def CreateChatGoogleGenerativeAI(model: str): + """재시도 로직이 포함된 LLM 생성""" + if model == "fallback": + print("⚠️ Fallback 모델을 사용합니다. Envorinment 변수를 확인하세요.") + print("⚠️ Model Gemini-2.0-flash-lite를 사용합니다.") + model = "gemini-2.0-flash-lite" + return ChatGoogleGenerativeAI( + model=model, + max_retries=10, # 최대 재시도 횟수 증가 + model_kwargs={ + "request_timeout": 120, # 타임아웃 시간 증가 (2분) + }, + callbacks=[QuotaExhaustedHandler()], + # API 호출 간격 조정 + temperature=0.1, + ) diff --git a/lib/llm/prompt/__init__.py b/lib/llm/prompt/__init__.py new file mode 100644 index 0000000..88bdff2 --- /dev/null +++ b/lib/llm/prompt/__init__.py @@ -0,0 +1,12 @@ +from dotenv import load_dotenv +import os + +from lib.llm.prompt import llm_login, session + +load_dotenv(override=True) + +def extend_planner_system_message(): + if os.getenv("PROVIDOR_CREDENTIALS_IN_LLM", "False").lower() == "true": + return llm_login.extend_planner_system_message + else: + return session.extend_planner_system_message \ No newline at end of file diff --git a/lib/prompt.py b/lib/llm/prompt/llm_login.py similarity index 55% rename from lib/prompt.py rename to lib/llm/prompt/llm_login.py index 9bb58e7..630f606 100644 --- a/lib/prompt.py +++ b/lib/llm/prompt/llm_login.py @@ -1,17 +1,34 @@ +from dotenv import load_dotenv +import os + +load_dotenv(override=True) +google_id = os.getenv("GOOGLE_ID", "") +google_password = os.getenv("GOOGLE_PASSWORD", "") + +naver_id = os.getenv("NAVER_ID", "") +naver_password = os.getenv("NAVER_PASSWORD", "") + +facebook_id = os.getenv("FACEBOOK_ID", "") +facebook_password = os.getenv("FACEBOOK_PASSWORD", "") + +github_id = os.getenv("GITHUB_ID", "") +github_password = os.getenv("GITHUB_PASSWORD", "") + # Extended planner prompt -extend_planner_system_message = """ +extend_planner_system_message = f""" 🎯 Mission: Collect Initial SSO Redirect URLs (For Browser Automation) ※ **모든 STEP에서 구글 검색, Bing 검색 등 어떤 외부 검색 기능도 절대 사용하지 않고, 초기에 주어진 URL에서 탐색하세요.** +※ **초기에 주어진 URL 내에서 실제로 확인되지 않은 URL로 직접 이동하는것은 허용되지 않습니다.** 0. **초기 블록(Block) 체크** - 브라우저가 로그인 페이지에 접근하려 할 때, **페이지가 차단(blocked)** 되거나 **방화벽, CAPTCHA, 접근 제한** 등으로 인해 정상적으로 로드되지 않으면 즉시 프로세스를 종료하고 아래 JSON만 반환해야 합니다. ```json [ - { + {{ "provider": "Blocked", "oauth_uri": "-" - } + }} ] ``` - 이후 단계로 절대 넘어가지 않도록 합니다. @@ -23,9 +40,7 @@ extend_planner_system_message = """ 2. **SSO 버튼 식별** - 로그인 페이지에서 다음과 같은 소셜 로그인 버튼을 찾습니다: - - “Continue with Google” - - “Sign in with GitHub” - - “Login with Naver” + - Google, GitHub, Facebook, Linkedin, Microsoft, Naver” - ✅ **실제 SSO 버튼**임이 명확히 확인되는 경우에만 진행합니다. - ❌ 제외 대상: - “Passkey” 관련 버튼 @@ -33,28 +48,29 @@ extend_planner_system_message = """ - 이메일 기반 로그인 - 인증서, 휴대폰 인증 등 비-OAuth 로그인 옵션 -3. **리디렉션 URL 캡처** - - 유효한 SSO 버튼을 하나 이상 찾았다면, 각각의 버튼을 **새 탭으로 열기**를 시도하거나, 불가능할 경우 **직접 클릭**합니다. - - 클릭 후 첫 번째로 **리디렉션된 URL(쿼리 스트링 포함)**을 캡처합니다. 이 URL은: - - ✅ 예시: `https://example.com/auth/google?include_all_params=...` - - ❌ **OAuth 공급자 자체 엔드포인트** (예: `https://accounts.google.com/...`)는 수집하지 않습니다. - - 만약 **반복 행동(looping)**이 감지될 경우(예: 동일한 버튼을 여러 번 열거나 페이지 간 반복 이동), 즉시 프로세스를 종료하고 **빈 배열**을 반환합니다: - ```json - [] - ``` - - 정상적으로 리디렉션 URL을 획득했다면, 아래 형식으로 결과를 수집합니다: - ```json - [ - { - "provider": "Google", - "oauth_uri": "https://example.com/auth/google?include_all_params=..." - }, - { - "provider": "GitHub", - "oauth_uri": "https://example.com/auth/github?include_all_params=..." - } - ] - ``` +3. **SSO 버튼 클릭 및 로그인 시도** + - 유효한 SSO 버튼이 발견되면, 버튼을 클릭합니다. + - 클릭 후 **첫 번째로 리디렉션된 URL(쿼리 스트링 포함)**을 `oauth_uri`로 기록합니다. + - 공급자 페이지가 열리면, 아래 자격증명을 이용해 로그인을 시도합니다, 아래 자격증명에 포함되지 않는 SSO 버튼도 클릭까지는 시도합니다.: + - Google → `{google_id}` / `{google_password}` + - Naver → `{naver_id}` / `{naver_password}` + - GitHub → `{github_id}` / `{github_password}` + - 자격증명이 주어진 SSO 버튼인 경우 로그인 과정을 꼭 진행합니다. + - 로그인 과정이 모두 끝나거나 로그인이 되지 않는 경우 세션 및 쿠키를 모두 삭제하고 페이지를 새로고침합니다. + - 아직 로그인을 시도하지 않은 SSO 버튼이 있다면 이전 단계인 1. **로그인 페이지 탐색**, 2. **SSO 버튼 식별**, 3. **SSO 버튼 클릭 및 로그인 시도** 로 돌아가 절차를 반복합니다. + - 최종 결과는 다음과 같이 기록합니다: + ```json + [ + {{ + "provider": "Google", + "oauth_uri": "(optional) https://example.com/auth/google?client_id=...", + }}, + {{ + "provider": "Naver", + "oauth_uri": "(optional) https://example.com/auth/naver?client_id=...", + }} + ] + ``` 4. **SSO 버튼 미발견 또는 오류 발생 시** - 페이지 내부에 유효한 SSO 버튼이 전혀 없거나, 탐색 중 예기치 않은 오류가 발생하면 즉시 프로세스를 종료하고 **빈 배열**을 반환합니다: diff --git a/lib/llm/prompt/session.py b/lib/llm/prompt/session.py new file mode 100644 index 0000000..439c19c --- /dev/null +++ b/lib/llm/prompt/session.py @@ -0,0 +1,136 @@ +import os +from dotenv import load_dotenv + +load_dotenv(override=True) + +# Extended planner prompt +extend_planner_system_message = f""" +🎯 목적: 웹 자동화를 위한 **SSO 로그인 리디렉션 URL 수집** + +📌 주의사항 (전제 조건) +- ❌ **검색 엔진(Google, Bing 등) 사용 금지** +- ✅ **초기 제공된 URL 내에서만 탐색** +- ❌ 직접 이동하거나 추측한 링크 클릭 금지 +- ⛔ 추측한 URL은 대답하거나 클릭하지 마세요 + +--- + +## 🧩 Step 0: 페이지 차단(Block) 여부 확인 + +초기 URL의 로그인 페이지에 접근하여 다음 사항을 점검합니다: + +- 🚫 페이지 차단됨 (Firewall, Access Denied 등) → 즉시 중단 +- 🔒 CAPTCHA는 통과 가능 (해결하고 계속 진행) +- ❗ 로그인 UI가 정상적으로 로드되지 않으면 중단 + +📤 차단 시 즉시 반환: + +```json +[ + {{ + "provider": "Blocked", + "oauth_uri": "-" + }} +] +```` + +--- + +## 🔍 Step 1: 로그인 페이지 탐색 + +* 초기 URL에 접속하여 **클라이언트용 로그인 페이지**로 진입합니다. +* 쿠키 동의, 개인정보 안내 등 팝업은 무시하거나 닫고 계속 진행하세요. +* 페이지가 정상 로드되었다고 가정합니다. + +--- + +## 👀 Step 2: SSO 로그인 버튼 식별 + +아래 **OAuth SSO 버튼들만** 유효합니다: + +* ✅ Google, GitHub, Facebook, LinkedIn, Microsoft, Naver + +**유효한 버튼 기준**: + +* OAuth 인증 흐름을 실제로 트리거 +* `window.location` 또는 `` 또는 JS로 redirect가 발생 + +**제외 버튼들 (클릭 금지)**: + +* ❌ 일반 로그인, 패스키, 이메일/전화번호, 인증서 기반, 비밀번호 입력 + +--- + +## ✅ Step 3: 모든 SSO 버튼 클릭 및 로그인 시도 + +> 각 SSO 로그인 버튼을 클릭한 뒤 반드시 아래 절차를 **완전히 수행**해야 합니다. + +각 SSO 버튼에 대해 다음을 수행: + +1. 버튼 클릭 +2. 🌐 페이지가 이동되면, **현재 주소창(URL)을 확인하여 리디렉션된 OAuth URL**을 `oauth_uri`로 저장 + → 예: `https://accounts.google.com/o/oauth2/auth?...` +3. ✅ 로그인 진행: + - 세션 및 쿠키에 따라 이미 로그인된 상태로 간주하고 진행 + - Google OAuth인 경우 URL에 `&login_hint={str(os.getenv('GOOGLE_ID'))}` 추가 + - 버튼같은게 안눌리면 새로고침을 해봐 + - **로그인 완료 후 authorize 등 버튼이 있으면 클릭** + - GitHub같은 경우 Authorize 버튼이 뜨는데 오래걸릴 수 있음, 기다려야 할 수도 있음 + - 만약 버튼을 눌러도 반응이 없을 경우 새로고침을 한번 해주세요. +4. 로그인 성공 시 원래 페이지로 돌아오고, 해당 OAuth URL은 결과에 저장 +5. 다음 SSO 버튼으로 반복 진행 + +🛑 절대 아래와 같이 해석하지 말 것: +- ❌ 버튼 클릭 후 페이지 로딩만 기다리고 돌아가기 +- ❌ URL 저장 없이 go_back() 호출 + +📤 각 로그인 후 다음 형식으로 결과 저장: + +```json +[ + {{ + "provider": "Google", + "oauth_uri": "https://example.com/auth/google?client_id=..." + }} +] +```` + +```` + +--- + +### ✨ 추가 안전 장치: "뒤로가기(go_back) 호출 조건" 제한 + +```text +🛑 뒤로가기(go_back)은 다음 조건이 모두 충족될 때만 사용: +- ✅ 로그인 흐름이 완료됨 (예: redirect back to app, or callback URL) +- ✅ 현재 리디렉션 URL이 수집됨 +- ✅ 결과에 저장 후 다음 버튼 탐색을 위해 복귀 필요할 때 +``` + +--- + +## 🚫 Step 4: 버튼 없음 또는 예외 발생 시 + +* 유효한 SSO 버튼이 **전혀 없을 경우** +* 예외, 오류 등 발생 시 + +📤 즉시 중단 후 다음 형식으로 반환: + +```json +[] +``` + +--- + +## 📎 중요 규칙 요약 + +* ✅ **모든 SSO 로그인은 반드시 실행** (가능한 버튼은 모두 클릭) +* 🔁 단계는 반드시 순서대로 진행 +* 🔐 로그인은 쿠키/세션으로 유지된 상태에서 수행 +* 🚫 직접 ID/PW 입력하지 않음 +* ⛔ 추측 URL 클릭 금지 +* ❗ 예외 발생 시 반드시 규정된 JSON 포맷만 반환 + +--- +""" diff --git a/lib/utils/__init__.py b/lib/utils/__init__.py new file mode 100644 index 0000000..d2f3a8a --- /dev/null +++ b/lib/utils/__init__.py @@ -0,0 +1,40 @@ +from lib.utils.config import ( + BACKEND_URL, + GOOGLE_API_KEY, + GOOGLE_MODEL, + GOOGLE_PLANNER_MODEL, +) + + +def show_info(): + print("🔧 환경 설정:") + print(browser_use_version()) + print(f"🔗 Backend URL: {BACKEND_URL}") + print( + f"🔑 Google API Key: {'*' * (len(GOOGLE_API_KEY) - 4) + GOOGLE_API_KEY[-4:] if GOOGLE_API_KEY else None}" + ) + print(f"🌐 Google Model: {GOOGLE_MODEL}") + print(f"🌐 Google Planner Model: {GOOGLE_PLANNER_MODEL}") + + +def browser_use_version(): + try: + # run uv pip show browser-use + import subprocess + + result = subprocess.run( + ["uv", "pip", "show", "browser-use"], + capture_output=True, + text=True, + check=True, + ) + + print("📦 Browser Use 패키지 정보:") + return result.stdout.strip() + except ImportError: + return None + + +def env_cheker(): + if GOOGLE_API_KEY is None: + raise ValueError("GOOGLE_API_KEY 환경변수가 설정되지 않았습니다.") diff --git a/lib/utils/backend_client.py b/lib/utils/backend_client.py new file mode 100644 index 0000000..68f497e --- /dev/null +++ b/lib/utils/backend_client.py @@ -0,0 +1,22 @@ +import requests + +from lib.utils.config import BACKEND_URL + +def notify_backend(target_url): + # Backend에 스캔 시작을 알림 + try: + response = requests.post( + f"{BACKEND_URL}/start", params={"url": target_url}, timeout=5 + ) + if response.status_code == 200: + print(f"✅ Backend notified: {response.text}") + else: + print(f"⚠️ Backend notification failed: {response.status_code}") + except requests.exceptions.ConnectionError: + print( + f"⚠️ Backend server not available at {BACKEND_URL}. Continuing without notification." + ) + except requests.exceptions.Timeout: + print(f"⚠️ Backend notification timed out. Continuing without notification.") + except Exception as e: + print(f"⚠️ Failed to notify backend: {e}") diff --git a/lib/utils/browser_use/__init__.py b/lib/utils/browser_use/__init__.py new file mode 100644 index 0000000..c38ca03 --- /dev/null +++ b/lib/utils/browser_use/__init__.py @@ -0,0 +1,31 @@ +from lib.utils.browser_use.func import * + +# Initialize configuration +proxy_url = setup_proxy() + +# Create browser profile +async def GetProfile(): + storage_state_path = await setup_storage_state() + profile = BrowserProfile( + # Security settings + disable_security=True, + stealth=True, + + # Display settings + headless=False, + device_scale_factor=1, + window_size={"width": 1600, "height": 900}, + viewport={"width": 1600, "height": 900}, + + # Data persistence + user_data_dir=None, + storage_state=storage_state_path, + + # Network settings + proxy={"server": proxy_url} if proxy_url else None, + + # Additional arguments + args=get_browser_args(), + ) + + return profile \ No newline at end of file diff --git a/lib/utils/browser_use/clean_resources.py b/lib/utils/browser_use/clean_resources.py new file mode 100644 index 0000000..792be35 --- /dev/null +++ b/lib/utils/browser_use/clean_resources.py @@ -0,0 +1,25 @@ +from pathlib import Path + +async def clean_resources(agent=None, session=None): + """리소스를 정리하는 함수""" + storage_state_temp_path = Path("./data/storage_state_temp.json").resolve() + if storage_state_temp_path.exists(): + try: + # remove file + print(f"🗑️ 임시 스토리지 상태 파일 삭제 중: {storage_state_temp_path}") + # unlink removes the file + storage_state_temp_path.unlink() + print("🗑️ 임시 스토리지 상태 파일 삭제 완료.") + except Exception as e: + print(f"⚠️ 임시 스토리지 상태 파일 삭제 실패: {e}") + + if agent: + try: + await agent.close() + except Exception as e: + print(f"⚠️ 에이전트 리소스 정리 실패: {e}") + if session: + try: + await session.close() + except Exception as e: + print(f"⚠️ 세션 리소스 정리 실패: {e}") diff --git a/lib/utils/browser_use/func.py b/lib/utils/browser_use/func.py new file mode 100644 index 0000000..31eee31 --- /dev/null +++ b/lib/utils/browser_use/func.py @@ -0,0 +1,75 @@ +import os +from pathlib import Path +from dotenv import load_dotenv +from browser_use import BrowserProfile + +# Load environment variables +load_dotenv(override=True) + +def setup_proxy(): + """Configure proxy settings from environment variables.""" + proxy_host = os.getenv("PROXY_HOST") + proxy_port = os.getenv("PROXY_PORT") + + if proxy_host and proxy_port: + proxy_url = f"http://{proxy_host}:{proxy_port}" + print(f"🔗 Using proxy: {proxy_host}:{proxy_port}") + return proxy_url + else: + print("🔗 No proxy configured, using direct connection.") + return None + + +async def setup_storage_state(): + """Setup browser storage state for session persistence.""" + # Get the script directory to ensure correct path resolution + script_dir = Path(__file__).parent.parent.parent.parent + storage_state_path = script_dir / "data" / "storage_state.json" + storage_state_temp_path = script_dir / "data" / "storage_state_temp.json" + + print(f"📂 Storage state path: {storage_state_path}") + print(f"📂 Temp storage state path: {storage_state_temp_path}") + + if storage_state_path.exists(): + if storage_state_temp_path.exists(): + storage_state_temp_path.unlink() + + storage_state_temp_path.write_text( + storage_state_path.read_text(encoding="utf-8"), encoding="utf-8" + ) + print(f"🔄 Using existing storage state: {storage_state_temp_path}") + return str(storage_state_temp_path) + + print("⚠️ No existing storage state found") + return None + + +def get_browser_args(): + """Get browser arguments for enhanced compatibility and security.""" + return [ + # Security and isolation + "--disable-web-security", + "--disable-site-isolation-trials", + "--disable-features=IsolateOrigins,site-per-process", + "--ignore-certificate-errors", + "--ignore-ssl-errors", + "--allow-running-insecure-content", + # Performance and rendering + "--disable-features=VizDisplayCompositor", + "--disable-dev-shm-usage", + # Popup and automation + "--disable-popup-blocking", + "--disable-blink-features=AutomationControlled", + # Browser behavior + "--no-first-run", + "--no-service-autorun", + "--no-default-browser-check", + "--password-store=basic", + "--use-mock-keychain", + # Extensions + "--disable-extensions-file-access-check", + "--disable-extensions-http-throttling", + "--disable-component-extensions-with-background-pages", + # Language + f"--lang={os.getenv('LANG', 'en_US')}", + ] diff --git a/lib/utils/browser_use/model.py b/lib/utils/browser_use/model.py new file mode 100644 index 0000000..e4397be --- /dev/null +++ b/lib/utils/browser_use/model.py @@ -0,0 +1,11 @@ +from typing import List +from pydantic import BaseModel + +# 출력 모델 +class OAuth(BaseModel): + provider: str + oauth_uri: str + + +class OAuthList(BaseModel): + oauth_providers: List[OAuth] \ No newline at end of file diff --git a/lib/utils/config.py b/lib/utils/config.py new file mode 100644 index 0000000..9d1d5ac --- /dev/null +++ b/lib/utils/config.py @@ -0,0 +1,8 @@ +import os +from dotenv import load_dotenv +load_dotenv(verbose=True, override=True) + +BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:11081") +GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") +GOOGLE_MODEL = os.getenv("GOOGLE_MODEL", "gemini-2.5-flash-preview-05-20") +GOOGLE_PLANNER_MODEL = os.getenv("GOOGLE_PLANNER_MODEL", "gemini-2.5-pro-preview-06-05") \ No newline at end of file diff --git a/lib/is_html.py b/lib/utils/is_html.py similarity index 100% rename from lib/is_html.py rename to lib/utils/is_html.py diff --git a/lib/logger.py b/lib/utils/logger.py similarity index 100% rename from lib/logger.py rename to lib/utils/logger.py diff --git a/lib/read_txt.py b/lib/utils/read_txt.py similarity index 100% rename from lib/read_txt.py rename to lib/utils/read_txt.py diff --git a/main.py b/main.py index bb22a49..ccc70bf 100644 --- a/main.py +++ b/main.py @@ -3,228 +3,284 @@ import json import os import csv import argparse -import requests -from typing import List +from pathlib import Path +import signal + from dotenv import load_dotenv -from pydantic import BaseModel -from langchain_google_genai import ChatGoogleGenerativeAI -from browser_use import Agent, Browser, BrowserConfig, Controller -from browser_use.browser.context import BrowserContext, BrowserContextConfig -from lib.browser_config import browser_config_kwargs -from lib.is_html import is_html_url -from lib.read_txt import read_lines_between -from lib.prompt import extend_planner_system_message -from lib.logger import logger -load_dotenv() +from browser_use import ( + Agent, + BrowserSession, + Controller, +) +from patchright.async_api import async_playwright as async_patchright -if os.getenv("GOOGLE_API_KEY") is None: - raise ValueError("GOOGLE_API_KEY 환경변수가 설정되지 않았습니다.") -if os.getenv("GOOGLE_MODEL") is None: - raise ValueError("GOOGLE_MODEL 환경변수가 설정되지 않았습니다.") -if os.getenv("GOOGLE_PLANNER_MODEL") is None: - raise ValueError("GOOGLE_PLANNER_MODEL 환경변수가 설정되지 않았습니다.") +from lib.utils import env_cheker +from lib.utils.backend_client import notify_backend +from lib.utils.browser_use import model +from lib.utils.browser_use.clean_resources import clean_resources +from lib.utils.browser_use.func import setup_storage_state +from lib.utils.config import BACKEND_URL, GOOGLE_MODEL, GOOGLE_PLANNER_MODEL +from lib.utils.is_html import is_html_url +from lib.utils.read_txt import read_lines_between +from lib.llm.prompt import extend_planner_system_message +from lib.utils.logger import logger +import lib.utils.browser_use as browser_use +from lib.llm import CreateChatGoogleGenerativeAI -backend_url = os.getenv("BACKEND_URL", "http://localhost:11081") +load_dotenv(verbose=True, override=True) -# 출력 모델 -class OAuth(BaseModel): - provider: str - oauth_uri: str +# Exponential backoff settings +INITIAL_BACKOFF = int(os.getenv("INITIAL_BACKOFF", "60")) # seconds +MAX_BACKOFF = int(os.getenv("MAX_BACKOFF", "600")) # seconds + +# 진행 상황 추적을 위한 전역 변수 +current_progress = {"current_index": 0, "total": 0, "current_url": "", "start_line": 0} +progress_file = Path("data/scan_progress.json") + +env_cheker() +if os.getenv("LMNR_PROJECT_API_KEY"): + from lmnr import Laminar + + Laminar.initialize(project_api_key=os.getenv("LMNR_PROJECT_API_KEY")) + + +def save_progress(): + """현재 진행 상황을 파일에 저장""" + with open(progress_file, 'w', encoding='utf-8') as f: + json.dump(current_progress, f, ensure_ascii=False, indent=2) + + +def load_progress(): + """이전 진행 상황을 파일에서 불러오기""" + if os.path.exists(progress_file): + try: + with open(progress_file, 'r', encoding='utf-8') as f: + return json.load(f) + except: + return None + return None + + +def signal_handler(signum, frame): + """Ctrl+C 시그널 핸들러""" + print("\n" + "="*60) + print("🛑 스캔이 중단되었습니다!") + print(f"📊 진행 상황:") + print(f" - 전체: {current_progress['total']}개 URL") + print(f" - 완료: {current_progress['current_index']}개 URL") + print(f" - 현재 처리 중: {current_progress['current_url']}") + print(f" - domains.txt의 {current_progress['start_line'] + current_progress['current_index']}번째 줄") + print(f" - 진행률: {current_progress['current_index']}/{current_progress['total']} ({current_progress['current_index']/current_progress['total']*100:.1f}%)") + print("="*60) + save_progress() + print(f"💾 진행 상황이 {progress_file}에 저장되었습니다.") + exit(0) + + +# 시그널 핸들러 등록 +signal.signal(signal.SIGINT, signal_handler) -class OAuthList(BaseModel): - oauth_providers: List[OAuth] - -async def clean_resources(agent, context, browser): - """리소스를 정리하는 함수""" - try: - await agent.close() - except Exception as e: - print(f"⚠️ 에이전트 리소스 정리 실패: {e}") - try: - await context.close() - except Exception as e: - print(f"⚠️ 컨텍스트 리소스 정리 실패: {e}") - try: - await browser.close() - except Exception as e: - print(f"⚠️ 브라우저 리소스 정리 실패: {e}") - # ── URL별로 Browser를 새로 띄우는 함수 ── async def scan_one_url(url: str, skip_html_check: bool = False): + await setup_storage_state() target_url = url if url.startswith("http") else f"https://{url}" print(f"🚀 Starting scan for: {target_url}") - + # 1) URL이 HTML 페이지인지 확인 if not is_html_url(target_url) and not skip_html_check: print(f"❌ {target_url} 은(는) HTML이 아닙니다. 스킵합니다.") return # Backend에 스캔 시작을 알림 - try: - response = requests.post(f"{backend_url}/start", params={"url": target_url}, timeout=5) - if response.status_code == 200: - print(f"✅ Backend notified: {response.text}") - else: - print(f"⚠️ Backend notification failed: {response.status_code}") - except requests.exceptions.ConnectionError: - print(f"⚠️ Backend server not available at {backend_url}. Continuing without notification.") - except requests.exceptions.Timeout: - print(f"⚠️ Backend notification timed out. Continuing without notification.") - except Exception as e: - print(f"⚠️ Failed to notify backend: {e}") - + notify_backend(target_url) + + agent = None + session = None try_cnt = 0 while True: - # 2) Browser + Context 생성 - browser = Browser(config=BrowserConfig(**browser_config_kwargs())) - context = BrowserContext( - browser=browser, - config=BrowserContextConfig( - wait_for_network_idle_page_load_time=3.0, - window_width=1600, - window_height=900, - locale='en-US', - highlight_elements=True, - viewport_expansion=500, - keep_alive=False - ) - ) - - # 3) Agent, Controller 생성 - initial_actions = [ - {'open_tab': {'url': target_url}}, - ] - - controller = Controller(output_model=OAuthList) - agent = Agent( - browser_context=context, - browser=browser, - initial_actions=initial_actions, - task=f"Navigate to the login page, and collect the OAuth provider buttons and their login URLs. Ignore Passkey.", - llm=ChatGoogleGenerativeAI(model=os.getenv("GOOGLE_MODEL")), - planner_llm=ChatGoogleGenerativeAI(model=os.getenv("GOOGLE_PLANNER_MODEL")), - controller=controller, - extend_planner_system_message=extend_planner_system_message, - retry_delay=60, + # BrowserSession에 profile 전달 + session = BrowserSession( + playwright=(await async_patchright().start()), + browser_profile=await browser_use.GetProfile(), ) + # Agent 생성 및 실행 (단일 try-except with 백오프) + initial_actions = [{"open_tab": {"url": target_url}}] + controller = Controller(output_model=model.BaseModel) + print("🤖 LLM 모델 초기화 및 스캔 시작...") try: - # 4) 실제 스캔 실행 + agent = Agent( + browser_session=session, + initial_actions=initial_actions, + task=( + "Navigate to the login page, identify all OAuth provider buttons (excluding Passkey), " + "and for each one: click the button, follow the full OAuth login flow as far as possible " + "with a real user account (without using a fake or non-existent account), and capture the " + "final redirect URL after login. Do not stop at just collecting the initial authorization URL—" + "actually perform the login step like a real user would. " + "If the OAuth buttons do not appear immediately, wait briefly to allow the page to load completely before proceeding. " + "Always log out before starting the login process, and make sure to attempt the login again from a clean state." + ), + llm=CreateChatGoogleGenerativeAI(GOOGLE_MODEL), + planner_llm=CreateChatGoogleGenerativeAI(GOOGLE_PLANNER_MODEL), + controller=controller, + extend_planner_system_message=extend_planner_system_message(), + ) response = await agent.run() final_result = response.final_result() + if final_result is None: raise ValueError("final_result()가 None을 반환했습니다.") - - data = json.loads(final_result) - try: - oauth_entries: List[OAuth] = [OAuth(**entry) for entry in data["oauth_providers"]] - except Exception as e: - raise ValueError(f"결과 파싱 실패: {e}\n원본 결과: {final_result}") - - # 5) 결과 출력 - print("-" * 50) - print(f"🔗 Scanned URL: {url}\n") - print("🔐 Detected OAuth Providers and URLs:") - for entry in oauth_entries: - if "<" in entry.oauth_uri or "..." in entry.oauth_uri: - print(f"⚠️ WARNING: {entry.provider} URL may be masked or incomplete:\n{entry.oauth_uri}\n") - else: - print(f"- {entry.provider}: {entry.oauth_uri}") - print("-" * 50) - - # 6) CSV에 저장 (append) - csv_file = "./oauth_providers.csv" - file_exists = os.path.isfile(csv_file) - with open(csv_file, "a", newline="", encoding="utf-8") as f: - writer = csv.writer(f) - if not file_exists: - writer.writerow(["issuer", "provider", "oauth_uri"]) - for entry in oauth_entries: - writer.writerow([url, entry.provider, entry.oauth_uri]) - print(f"✅ OAuth providers saved to {csv_file}\n") - - await clean_resources(agent, context, browser) - - # 성공적으로 처리했으므로 반복문 탈출 - break - except Exception as e: - await clean_resources(agent, context, browser) - - if try_cnt >= 1: - print(f"❌ {url} 스캔에 실패했습니다. 에러: {e}") - logger(f"❌ {url} 스캔에 실패했습니다. 에러: {e}") - return + await clean_resources(agent, session) + # API 쿼터 문제인지 확인 + if "ResourceExhausted" in str(e) or "429" in str(e): + wait = min(INITIAL_BACKOFF * (2**try_cnt), MAX_BACKOFF) + print(f"⚠️ API 쿼터 에러: {e}. {wait}초 대기 후 재시도합니다...") + await asyncio.sleep(wait) + try_cnt += 1 + if try_cnt >= 3: + print(f"❌ {url} 스캔 실패: API 쿼터 문제가 지속됩니다.") + logger(f"❌ {url} 스캔 실패: API 쿼터 문제: {e}") + return + continue + # 일반 에러 처리 try_cnt += 1 + if try_cnt >= 3: + print(f"❌ {url} 스캔 실패: 에러: {e}") + logger(f"❌ {url} 스캔 실패: 에러: {e}") + return print(f"⚠️ 에러 발생: {e}. {try_cnt}번째 재시도 중...") - - - # 1분 대기 - await asyncio.sleep(5) - # 반복문을 통해 재시도 + await asyncio.sleep(30) continue -async def loop(filepath: str, start_line: int, end_line: int, skip_html_check: bool = False): + # 스캔 결과 처리 + data = json.loads(final_result) + try: + oauth_entries = [model.OAuth(**entry) for entry in data["oauth_providers"]] + except Exception as e: + raise ValueError(f"결과 파싱 실패: {e}\n원본 결과: {final_result}") + + print("-" * 50) + print(f"🔗 Scanned URL: {url}\n") + print("🔐 Detected OAuth Providers and URLs:") + for entry in oauth_entries: + if "<" in entry.oauth_uri or "..." in entry.oauth_uri: + print( + f"⚠️ WARNING: {entry.provider} URL may be masked or incomplete:\n{entry.oauth_uri}\n" + ) + else: + print(f"- {entry.provider}: {entry.oauth_uri}") + print("-" * 50) + + # CSV에 저장 (append) + csv_file = "./oauth_providers.csv" + file_exists = os.path.isfile(csv_file) + with open(csv_file, "a", newline="", encoding="utf-8") as f: + writer = csv.writer(f) + if not file_exists: + writer.writerow(["issuer", "provider", "oauth_uri"]) + for entry in oauth_entries: + writer.writerow([url, entry.provider, entry.oauth_uri]) + await clean_resources(agent, session) + break + + +async def loop( + filepath: str, start_line: int, end_line: int, skip_html_check: bool = False +): # 인자값으로 받은 파일 경로와 줄 범위를 통해 도메인 리스트 생성 target_list = read_lines_between( - filepath=filepath, - start_line=start_line, - end_line=end_line + filepath=filepath, start_line=start_line, end_line=end_line ) + # 진행 상황 초기화 + current_progress["total"] = len(target_list) + current_progress["start_line"] = start_line + current_progress["current_index"] = 0 + + # 이전 진행 상황 확인 + prev_progress = load_progress() + if prev_progress and prev_progress.get("start_line") == start_line: + print(f"📋 이전 진행 상황을 발견했습니다:") + print(f" - 이전 완료: {prev_progress['current_index']}/{prev_progress['total']}") + print(f" - 마지막 처리: {prev_progress.get('current_url', 'N/A')}") + + resume = input("이어서 진행하시겠습니까? (y/n): ").lower().strip() + if resume == 'y': + current_progress["current_index"] = prev_progress["current_index"] + target_list = target_list[current_progress["current_index"]:] + print(f"✅ {current_progress['current_index']}번째부터 재개합니다.") + # (필요하다면) 강제 설정이 필요한 경우, 아래 주석을 해제하여 target_list[0] 등을 덮어쓸 수 있습니다. # target_list[0] = "velog.io" - for url in target_list: - # scan_one_url은 외부에 정의된 비동기 함수라고 가정합니다. - # 실제로 scan_one_url이 정의된 위치를 import하거나 - # 모듈 수준에 구현해두셔야 합니다. + for i, url in enumerate(target_list): + actual_index = current_progress["current_index"] + i + current_progress["current_url"] = url + current_progress["current_index"] = actual_index + + print(f"\n🔄 Processing {actual_index + 1}/{current_progress['total']}: {url}") + print(f"📍 domains.txt의 {start_line + actual_index}번째 줄") + + # URL들 사이에 API 쿼터 회복을 위한 대기 시간 추가 + if actual_index > 0: + print("⏳ API 쿼터 보호를 위해 30초 대기 중...") + await asyncio.sleep(30) + await scan_one_url(url, skip_html_check=skip_html_check) + + # 진행 상황 저장 + current_progress["current_index"] = actual_index + 1 + save_progress() + + print(f"\n🎉 모든 스캔이 완료되었습니다! ({current_progress['total']}개 URL)") + # 완료 후 진행 상황 파일 삭제 + if os.path.exists(progress_file): + os.remove(progress_file) def main(): parser = argparse.ArgumentParser( prog="domain_scanner", - description="도메인 목록 파일에서 지정한 줄 범위를 읽어 SSO 스캔을 수행합니다." + description="도메인 목록 파일에서 지정한 줄 범위를 읽어 SSO 스캔을 수행합니다.", ) # 커맨드라인 인자로 받을 옵션들 정의 parser.add_argument( - "-f", "--file", + "-f", + "--file", type=str, required=True, - help="도메인 목록이 들어 있는 텍스트 파일 경로 (예: ./domains.txt)" + help="도메인 목록이 들어 있는 텍스트 파일 경로 (예: ./domains.txt)", ) parser.add_argument( - "-s", "--start", - type=int, - required=True, - help="읽기 시작 줄 번호 (1-based)" + "-s", "--start", type=int, required=True, help="읽기 시작 줄 번호 (1-based)" ) parser.add_argument( - "-e", "--end", - type=int, - required=True, - help="읽기 종료 줄 번호 (1-based)" + "-e", "--end", type=int, required=True, help="읽기 종료 줄 번호 (1-based)" ) parser.add_argument( - "-skh", "--skip-html-check", + "-skh", + "--skip-html-check", type=bool, default=False, - help="HTML 페이지 체크를 건너뛰고 모든 URL을 스캔합니다. (기본값: False)" + help="HTML 페이지 체크를 건너뛰고 모든 URL을 스캔합니다. (기본값: False)", ) args = parser.parse_args() # 인자값을 비동기 함수에 전달 - asyncio.run(loop( - filepath=args.file, - start_line=args.start, - end_line=args.end, - skip_html_check=args.skip_html_check - )) + asyncio.run( + loop( + filepath=args.file, + start_line=args.start, + end_line=args.end, + skip_html_check=args.skip_html_check, + ) + ) if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index f936ff0..5e8289f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,5 +5,7 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.13" dependencies = [ - "browser-use[memory]>=0.1.48", + "browser-use[memory]>=0.2.7", + "lmnr[all]>=0.6.10", + "patchright>=1.52.5", ] diff --git a/run.ps1 b/run.ps1 index 47b101e..6ccf270 100644 --- a/run.ps1 +++ b/run.ps1 @@ -4,9 +4,6 @@ $PYTHON_SCRIPT = "main.py" # 도메인 목록 파일 경로 (Python 스크립트 실행 시 -f 옵션에 전달) $DOMAIN_FILE = "./domains.txt" - -# 몇 줄씩(chunk) 나눠서 실행할지 -$CHUNK_SIZE = 10 # ───────────── # https://f.imnya.ng/.whs/tp-domains/data/domains/latest.txt @@ -26,27 +23,14 @@ $START_LINE = [int]$args[0] $END_LINE = [int]$args[1] $SKIP_HEADER = if ($args.Count -eq 3) { $args[2] } else { "False" } -# START_LINE부터 END_LINE까지 CHUNK_SIZE 만큼씩 반복 -$current = $START_LINE -while ($current -le $END_LINE) { - # 각 청크 구간의 마지막 줄 계산 - $chunk_end = $current + $CHUNK_SIZE - 1 - if ($chunk_end -gt $END_LINE) { - $chunk_end = $END_LINE - } +$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" +Write-Host "[$timestamp] Processing lines $START_LINE to $END_LINE..." - $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" - Write-Host "[$timestamp] Processing lines $current to $chunk_end..." - - # Python 스크립트 실행 - # -f DOMAIN_FILE: 도메인 목록 파일 경로 - # -s current : 읽기 시작 줄 - # -e chunk_end: 읽기 끝 줄 - # -skh SKIP_HEADER: 헤더 스킵 여부 - uv run $PYTHON_SCRIPT -f $DOMAIN_FILE -s $current -e $chunk_end -skh $SKIP_HEADER +# Python 스크립트 실행 +# -f DOMAIN_FILE: 도메인 목록 파일 경로 +# -s START_LINE : 읽기 시작 줄 +# -e END_LINE : 읽기 끝 줄 +# -skh SKIP_HEADER: 헤더 스킵 여부 +uv run $PYTHON_SCRIPT -f $DOMAIN_FILE -s $START_LINE -e $END_LINE -skh $SKIP_HEADER - # 다음 청크의 시작 값 설정 - $current = $chunk_end + 1 -} - -Write-Host "모든 청크 처리 완료." +Write-Host "처리 완료." diff --git a/run.sh b/run.sh index b78ca57..cd79cb1 100755 --- a/run.sh +++ b/run.sh @@ -3,7 +3,6 @@ # ── 설정 부분 ── PYTHON_SCRIPT="main.py" DOMAIN_FILE="./domains.txt" -CHUNK_SIZE=10 # ───────────── curl "https://f.imnya.ng/.whs/tp-domains/data/domains/latest.txt" -o $DOMAIN_FILE @@ -23,18 +22,7 @@ if [ -z "$SKH_OPTION" ]; then SKH_OPTION="False" fi -current=$START_LINE -while [ "$current" -le "$END_LINE" ]; do - chunk_end=$(( current + CHUNK_SIZE - 1 )) - if [ "$chunk_end" -gt "$END_LINE" ]; then - chunk_end=$END_LINE - fi +echo "[$(date '+%Y-%m-%d %H:%M:%S')] Processing lines ${START_LINE} to ${END_LINE}..." +uv run "$PYTHON_SCRIPT" -f "$DOMAIN_FILE" -s "$START_LINE" -e "$END_LINE" -skh $SKH_OPTION - echo "[$(date '+%Y-%m-%d %H:%M:%S')] Processing lines ${current} to ${chunk_end}..." - uv run "$PYTHON_SCRIPT" -f "$DOMAIN_FILE" -s "$current" -e "$chunk_end" -skh $SKH_OPTION - - current=$(( chunk_end + 1 )) - sleep 1 # 1초 대기 -done - -echo "모든 청크 처리 완료." +echo "처리 완료." diff --git a/uv.lock b/uv.lock index 89d6dfd..52013e7 100644 --- a/uv.lock +++ b/uv.lock @@ -2,6 +2,15 @@ version = 1 revision = 2 requires-python = ">=3.13" +[[package]] +name = "aiofiles" +version = "24.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247, upload-time = "2024-06-24T11:02:03.584Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896, upload-time = "2024-06-24T11:02:01.529Z" }, +] + [[package]] name = "annotated-types" version = "0.7.0" @@ -13,7 +22,7 @@ wheels = [ [[package]] name = "anthropic" -version = "0.51.0" +version = "0.53.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -24,9 +33,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/4a/96f99a61ae299f9e5aa3e765d7342d95ab2e2ba5b69a3ffedb00ef779651/anthropic-0.51.0.tar.gz", hash = "sha256:6f824451277992af079554430d5b2c8ff5bc059cc2c968cdc3f06824437da201", size = 219063, upload-time = "2025-05-07T15:39:22.348Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/f6/a78ff9e23981fde136c3ae5427a39b27df92ebe5e5997c6203796449f1e5/anthropic-0.53.0.tar.gz", hash = "sha256:f5d1499fc45b2e05801fcbbeae25679f72f7479763e3c706126a7a7c8de06eff", size = 307716, upload-time = "2025-06-09T16:20:31.689Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/6e/9637122c5f007103bd5a259f4250bd8f1533dd2473227670fd10a1457b62/anthropic-0.51.0-py3-none-any.whl", hash = "sha256:b8b47d482c9aa1f81b923555cebb687c2730309a20d01be554730c8302e0f62a", size = 263957, upload-time = "2025-05-07T15:39:20.82Z" }, + { url = "https://files.pythonhosted.org/packages/a9/3f/82c21f74afa3541d69d20b8265c7fdfd078a687e9eea48fda30f1838d0b7/anthropic-0.53.0-py3-none-any.whl", hash = "sha256:b3a84751885a81d96bbddef180c3ce559c9140f7f230cdd825385405bd6d312e", size = 287248, upload-time = "2025-06-09T16:20:29.98Z" }, ] [[package]] @@ -42,6 +51,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] +[[package]] +name = "argparse" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", size = 70508, upload-time = "2015-09-12T20:22:16.217Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314", size = 23000, upload-time = "2015-09-14T16:03:16.137Z" }, +] + [[package]] name = "backoff" version = "2.2.1" @@ -94,9 +112,10 @@ wheels = [ [[package]] name = "browser-use" -version = "0.1.48" +version = "0.2.7" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "aiofiles" }, { name = "anyio" }, { name = "faiss-cpu" }, { name = "google-api-core" }, @@ -111,6 +130,7 @@ dependencies = [ { name = "langchain-openai" }, { name = "markdownify" }, { name = "mem0ai" }, + { name = "patchright" }, { name = "playwright" }, { name = "posthog" }, { name = "psutil" }, @@ -121,10 +141,11 @@ dependencies = [ { name = "requests" }, { name = "screeninfo", marker = "platform_system != 'darwin'" }, { name = "typing-extensions" }, + { name = "uuid7" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/a0/8b4c08da6adc8be7bee48d216fbf829bb7f5f9cd5c06147ee9d0da11593a/browser_use-0.1.48.tar.gz", hash = "sha256:7c061c8fdea735345d6d480d7c7fd2b24557826fa92c00d8efd7f98f4d6f29c1", size = 127897, upload-time = "2025-05-15T22:47:33.031Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/86/8d25175730145a8f94715e5ceb3e050d8221fc81d7dee8c8f18ddf4206a3/browser_use-0.2.7.tar.gz", hash = "sha256:a2e0b0eb34e6fb5ef46e4e10ad0b4a42854fc2445d3e53b3ba393b9295019725", size = 155467, upload-time = "2025-06-14T08:55:54.739Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/ea/527e3c2108b78517a5b952b20039dbe46e90ca297222462989fc9bc85a51/browser_use-0.1.48-py3-none-any.whl", hash = "sha256:7848ac2cd35d0b8b0528d4b8c44dc637ce3efce73b29ca1c41f3bd1f7845de40", size = 146023, upload-time = "2025-05-15T22:47:31.901Z" }, + { url = "https://files.pythonhosted.org/packages/e7/93/2305e33ca4470abafd087be820256bd96c495ab685425582d811bb22837a/browser_use-0.2.7-py3-none-any.whl", hash = "sha256:bc534a369ef85ff3905abae05dab1d4a996676ad285a3dff9aa6c5211854872d", size = 172584, upload-time = "2025-06-14T08:55:53.355Z" }, ] [package.optional-dependencies] @@ -138,10 +159,16 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "browser-use", extra = ["memory"] }, + { name = "lmnr", extra = ["all"] }, + { name = "patchright" }, ] [package.metadata] -requires-dist = [{ name = "browser-use", extras = ["memory"], specifier = ">=0.1.48" }] +requires-dist = [ + { name = "browser-use", extras = ["memory"], specifier = ">=0.2.7" }, + { name = "lmnr", extras = ["all"], specifier = ">=0.6.10" }, + { name = "patchright", specifier = ">=1.52.5" }, +] [[package]] name = "cachetools" @@ -225,15 +252,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9f/cc/221af506254978b119a2f6769b81b16bcfe09e0fb3fc5ab66e53e536d933/cython-3.1.0-py3-none-any.whl", hash = "sha256:4e460bdf1d8742ddf4914959842f2f23ca4934df97f864be799ddf1912acd0ab", size = 1227398, upload-time = "2025-05-08T20:25:31.368Z" }, ] -[[package]] -name = "defusedxml" -version = "0.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, -] - [[package]] name = "distro" version = "1.9.0" @@ -304,7 +322,7 @@ wheels = [ [[package]] name = "google-api-core" -version = "2.24.2" +version = "2.25.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-auth" }, @@ -313,9 +331,9 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/5c/085bcb872556934bb119e5e09de54daa07873f6866b8f0303c49e72287f7/google_api_core-2.24.2.tar.gz", hash = "sha256:81718493daf06d96d6bc76a91c23874dbf2fac0adbbf542831b805ee6e974696", size = 163516, upload-time = "2025-03-10T15:55:26.201Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a2/8176b416ca08106b2ae30cd4a006c8176945f682c3a5b42f141c9173f505/google_api_core-2.25.0.tar.gz", hash = "sha256:9b548e688702f82a34ed8409fb8a6961166f0b7795032f0be8f48308dff4333a", size = 164914, upload-time = "2025-06-02T14:45:34.789Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/95/f472d85adab6e538da2025dfca9e976a0d125cc0af2301f190e77b76e51c/google_api_core-2.24.2-py3-none-any.whl", hash = "sha256:810a63ac95f3c441b7c0e43d344e372887f62ce9071ba972eacf32672e072de9", size = 160061, upload-time = "2025-03-10T15:55:24.386Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ca/149e41a277bb0855e8ded85fd7579d7747c1223e253d82c5c0f1be236875/google_api_core-2.25.0-py3-none-any.whl", hash = "sha256:1db79d1281dcf9f3d10023283299ba38f3dc9f639ec41085968fd23e5bcf512e", size = 160668, upload-time = "2025-06-02T14:45:33.272Z" }, ] [package.optional-dependencies] @@ -507,6 +525,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] +[[package]] +name = "importlib-metadata" +version = "8.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, +] + +[[package]] +name = "inflection" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/7e/691d061b7329bc8d54edbf0ec22fbfb2afe61facb681f9aaa9bff7a27d04/inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417", size = 15091, upload-time = "2020-08-22T08:16:29.139Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/91/aa6bde563e0085a02a435aa99b49ef75b0a4b062635e606dab23ce18d720/inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2", size = 9454, upload-time = "2020-08-22T08:16:27.816Z" }, +] + [[package]] name = "jinja2" version = "3.1.6" @@ -583,7 +622,7 @@ wheels = [ [[package]] name = "langchain" -version = "0.3.22" +version = "0.3.25" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, @@ -594,29 +633,28 @@ dependencies = [ { name = "requests" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/66/36ccbd6285b29473ada883b0e06fdc0973ca181431d6a0175e473160fbfb/langchain-0.3.22.tar.gz", hash = "sha256:fd7781ef02cac6f074f9c6a902236482c61976e21da96ab577874d4e5396eeda", size = 10225573, upload-time = "2025-03-31T12:38:08.521Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f9/a256609096a9fc7a1b3a6300a97000091efabdf21555a97988f93d4d9258/langchain-0.3.25.tar.gz", hash = "sha256:a1d72aa39546a23db08492d7228464af35c9ee83379945535ceef877340d2a3a", size = 10225045, upload-time = "2025-05-02T18:39:04.353Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/0e/032de736a8f9b5b5fcfec77bd92831f9f2c8a8b5072289dd1e5cc95e6edc/langchain-0.3.22-py3-none-any.whl", hash = "sha256:2e7f71a1b0280eb70af9c332c7580f6162a97fb9d5e3e87e9d579ad167f50129", size = 1011714, upload-time = "2025-03-31T12:38:05.982Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5c/5c0be747261e1f8129b875fa3bfea736bc5fe17652f9d5e15ca118571b6f/langchain-0.3.25-py3-none-any.whl", hash = "sha256:931f7d2d1eaf182f9f41c5e3272859cfe7f94fc1f7cef6b3e5a46024b4884c21", size = 1011008, upload-time = "2025-05-02T18:39:02.21Z" }, ] [[package]] name = "langchain-anthropic" -version = "0.3.3" +version = "0.3.15" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anthropic" }, - { name = "defusedxml" }, { name = "langchain-core" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5f/ad/f9f77948deeca2c33a55f262ca78cee7c2c3dfbaef849704991517443bf6/langchain_anthropic-0.3.3.tar.gz", hash = "sha256:1faf0aa0aed392a18ed34d00e816d7c748ef342523deacc131690aae08ab4f1b", size = 21003, upload-time = "2025-01-17T20:32:56.379Z" } +sdist = { url = "https://files.pythonhosted.org/packages/47/c5/c5cd0164e342812787c157a385e8a9529510a514a5fe6acb487e990e82b0/langchain_anthropic-0.3.15.tar.gz", hash = "sha256:e62de2b0175c1fcca49fc4cc1f8742a4ab2385f0b94b7df4533fd06d577efd36", size = 54218, upload-time = "2025-06-03T15:04:44.062Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/cf/466b38e46e7071e7367c452bd29d1b4de03e4023685b0c45fc2df728b616/langchain_anthropic-0.3.3-py3-none-any.whl", hash = "sha256:385e6d6d719514369f38304ed5e9b74827feca36f3391595695dcb82696ed04a", size = 22471, upload-time = "2025-01-17T20:32:54.052Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c0/9a1d58ab8718505bf25b7ad375a2a104886dfe64519d8b96442bb295637e/langchain_anthropic-0.3.15-py3-none-any.whl", hash = "sha256:894d670bc44e68e0b1f2f09e7e7f977a8f07085a596f114c79aefbb789f6d88d", size = 28054, upload-time = "2025-06-03T15:04:43.108Z" }, ] [[package]] name = "langchain-aws" -version = "0.2.19" +version = "0.2.24" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "boto3" }, @@ -624,14 +662,14 @@ dependencies = [ { name = "numpy" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/90/455226b38c48a012941d9cd9710f93a03c0a7a29a30b980443b3d54fbba3/langchain_aws-0.2.19.tar.gz", hash = "sha256:041a1f133220baa54b0c39f68c894aa450e4cb1d33c896bb18633b99ddcf1456", size = 96917, upload-time = "2025-04-10T17:44:00.624Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/65/51b38bdef5488c2f37d27ffef57d838b99de86a7b2b91fa1db4f78b27865/langchain_aws-0.2.24.tar.gz", hash = "sha256:1ef09f3b84b94e5cc816b21ade391b4c3b14aba3ad8dc75968fac50ffe6bbd1a", size = 98341, upload-time = "2025-05-27T20:57:03.065Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/ce/a8f3cf8fa510cd6a7bffd091aa5a5968f9eeb4b7a5e84657c73ff55c67b5/langchain_aws-0.2.19-py3-none-any.whl", hash = "sha256:967be6127897be77b2337d376724968cd3c8c834981607e9ab2f90d4199f7941", size = 118893, upload-time = "2025-04-10T17:43:59.229Z" }, + { url = "https://files.pythonhosted.org/packages/ee/81/315e265a8ce740959f1d358d4d93f2f13315dcd6fc70ce82b04f0548fef0/langchain_aws-0.2.24-py3-none-any.whl", hash = "sha256:464df2e6535001e5424786c493906d2e5d4a01bd1906e9e8d4da1404e13bd25c", size = 120268, upload-time = "2025-05-27T20:57:02.024Z" }, ] [[package]] name = "langchain-core" -version = "0.3.49" +version = "0.3.64" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -642,9 +680,9 @@ dependencies = [ { name = "tenacity" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/bd/db939ba59f28a4ac73fa64281e21f5011ce61fd694c03b88946a554d8442/langchain_core-0.3.49.tar.gz", hash = "sha256:d9dbff9bac0021463a986355c13864d6a68c41f8559dbbd399a68e1ebd9b04b9", size = 536469, upload-time = "2025-03-26T18:42:00.598Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/40/89a80157f495d4adc9e5e770171806e3231600647f4ca0e89bdf743702ff/langchain_core-0.3.64.tar.gz", hash = "sha256:71b51bf77003eb57e74b8fa2a84ac380e24aa7357f173b51645c5834b9fc0d62", size = 558483, upload-time = "2025-06-05T21:27:10.817Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/35/27164f5f23517be8639b518130e6235293dae52c41988790e0b50dd7ba11/langchain_core-0.3.49-py3-none-any.whl", hash = "sha256:893ee42c9af13bf2a2d8c2ec15ba00a5c73cccde21a2bd005234ee0e78a2bdf8", size = 420102, upload-time = "2025-03-26T18:41:58.854Z" }, + { url = "https://files.pythonhosted.org/packages/c3/43/94b486eeb778443887e4eb76326e704ee0c6244f5fab6a46686e09968e9a/langchain_core-0.3.64-py3-none-any.whl", hash = "sha256:e844c425329d450cb3010001d86b61fd59a6a17691641109bae39322c85e27dd", size = 438113, upload-time = "2025-06-05T21:27:07.981Z" }, ] [[package]] @@ -662,7 +700,7 @@ wheels = [ [[package]] name = "langchain-google-genai" -version = "2.1.2" +version = "2.1.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filetype" }, @@ -670,53 +708,53 @@ dependencies = [ { name = "langchain-core" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/32/aeaa30a23f495417d71a7b8d9f6a71a40500b9994424c57e89418d96fc52/langchain_google_genai-2.1.2.tar.gz", hash = "sha256:f605501b498288d32914f6f8c0b7c9cfa67432757f596dcb2dbbd8042e892963", size = 38091, upload-time = "2025-03-27T16:04:22.879Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/a5/d9b8d5afdf4a33f13e7d973f2705891cd13cc1dfb578719c9861a8d8385b/langchain_google_genai-2.1.5.tar.gz", hash = "sha256:6e71375a7707667bdecc5a7d1c86438ec10f2c7bb6dc6e3f095f5b22523c4fc9", size = 40813, upload-time = "2025-05-28T13:49:09.574Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/82/2a5d3fe54df23d6471768b9558f9a73e1a712065e6c20a228aa3254092aa/langchain_google_genai-2.1.2-py3-none-any.whl", hash = "sha256:eb9c95d551ecc0216e5baef2f2e6ae1b60897e618f273356d31b680022a1a755", size = 42030, upload-time = "2025-03-27T16:04:21.601Z" }, + { url = "https://files.pythonhosted.org/packages/5e/70/0747358eca996f713f715e2bfc2d0805804f8f705af57381fbee91bb475a/langchain_google_genai-2.1.5-py3-none-any.whl", hash = "sha256:6c8ccaf33a41f83b1d08a2398edbf47a1eebea27a7ec6930f34a0c019f309253", size = 44788, upload-time = "2025-05-28T13:49:08.22Z" }, ] [[package]] name = "langchain-ollama" -version = "0.3.0" +version = "0.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, { name = "ollama" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/61/36/0ed0173ac8d88a0f6d769fb786a5b736f4b449093b9e47aa787ba0f6b0b4/langchain_ollama-0.3.0.tar.gz", hash = "sha256:4989f79d4b2d0d51f3a95e53b4c368c95c6bb64922a9ea40a7a376b43187803b", size = 20674, upload-time = "2025-03-21T15:53:11.814Z" } +sdist = { url = "https://files.pythonhosted.org/packages/59/9f/6683f69f14b0cde3556c6b7752fb290bfce743981dc1312efa924619365f/langchain_ollama-0.3.3.tar.gz", hash = "sha256:7d6ed75bfb706751b83173fe886b72ae25bb0b1bd7f3eb2622821c4149f7807b", size = 21913, upload-time = "2025-05-15T20:27:06.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/44/a1/a7dbdc39365f2f148a91724d8d52c0028cafe7dd6f0257462bc187bc4643/langchain_ollama-0.3.0-py3-none-any.whl", hash = "sha256:33716a912419d00a17da446f1b6ec8ec45c7b9376c6a1c0b688cc0cecd4b9c39", size = 20348, upload-time = "2025-03-21T15:53:10.913Z" }, + { url = "https://files.pythonhosted.org/packages/84/6f/ab7a470522e27b95ed008eb9ef81b1ab55321f3f3aff21ca0109aae53cdf/langchain_ollama-0.3.3-py3-none-any.whl", hash = "sha256:f1c745a4b59d36bb51995c23c6b0fbc20f71956715659425ab88639a14b213cd", size = 21156, upload-time = "2025-05-15T20:27:05.159Z" }, ] [[package]] name = "langchain-openai" -version = "0.3.11" +version = "0.3.21" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, { name = "openai" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/d6/dc77062c0b7c09f18d10a94a33920a69b6bee13079905d638bfdb7300e97/langchain_openai-0.3.11.tar.gz", hash = "sha256:4de846b2770c2b15bee4ec8034af064bfecb01fa86d4c5ff3f427ee337f0e98c", size = 267476, upload-time = "2025-03-26T19:59:19.975Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/2b/92f2fe18265bea38c456ea75cb6a38ba7d0f4d1bccb4220de616771b26a1/langchain_openai-0.3.21.tar.gz", hash = "sha256:470126f54b754b55a421bd0ffcb53671355700b42f0689a80187d53df20c6759", size = 545107, upload-time = "2025-06-06T15:48:09.47Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/9f/08696493db3c3fa238c13eee9db6386dbcebe0fc164c8ce6a20afdde53a7/langchain_openai-0.3.11-py3-none-any.whl", hash = "sha256:95cf602322d43d13cb0fd05cba9bc4cffd7024b10b985d38f599fcc502d2d4d0", size = 60147, upload-time = "2025-03-26T19:59:18.734Z" }, + { url = "https://files.pythonhosted.org/packages/73/c0/bded8320fb0bbaeb3383fa8a45c287b95e153566f4ba2b749a67074090e5/langchain_openai-0.3.21-py3-none-any.whl", hash = "sha256:9d1f447af2e15d5d6b7e0c5552052e08d1dd4aa1c9b537bcde47534792a7f244", size = 65211, upload-time = "2025-06-06T15:48:08.4Z" }, ] [[package]] name = "langchain-text-splitters" -version = "0.3.7" +version = "0.3.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5a/e7/638b44a41e56c3e32cc90cab3622ac2e4c73645252485427d6b2742fcfa8/langchain_text_splitters-0.3.7.tar.gz", hash = "sha256:7dbf0fb98e10bb91792a1d33f540e2287f9cc1dc30ade45b7aedd2d5cd3dc70b", size = 42180, upload-time = "2025-03-18T19:15:42.664Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ac/b4a25c5716bb0103b1515f1f52cc69ffb1035a5a225ee5afe3aed28bf57b/langchain_text_splitters-0.3.8.tar.gz", hash = "sha256:116d4b9f2a22dda357d0b79e30acf005c5518177971c66a9f1ab0edfdb0f912e", size = 42128, upload-time = "2025-04-04T14:03:51.521Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/85/b7a34b6d34bcc89a2252f5ffea30b94077ba3d7adf72e31b9e04e68c901a/langchain_text_splitters-0.3.7-py3-none-any.whl", hash = "sha256:31ba826013e3f563359d7c7f1e99b1cdb94897f665675ee505718c116e7e20ad", size = 32513, upload-time = "2025-03-18T19:15:41.79Z" }, + { url = "https://files.pythonhosted.org/packages/8b/a3/3696ff2444658053c01b6b7443e761f28bb71217d82bb89137a978c5f66f/langchain_text_splitters-0.3.8-py3-none-any.whl", hash = "sha256:e75cc0f4ae58dcf07d9f18776400cf8ade27fadd4ff6d264df6278bb302f6f02", size = 32440, upload-time = "2025-04-04T14:03:50.6Z" }, ] [[package]] name = "langsmith" -version = "0.3.42" +version = "0.3.45" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -727,9 +765,65 @@ dependencies = [ { name = "requests-toolbelt" }, { name = "zstandard" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3a/44/fe171c0b0fb0377b191aebf0b7779e0c7b2a53693c6a01ddad737212495d/langsmith-0.3.42.tar.gz", hash = "sha256:2b5cbc450ab808b992362aac6943bb1d285579aa68a3a8be901d30a393458f25", size = 345619, upload-time = "2025-05-03T03:07:17.873Z" } +sdist = { url = "https://files.pythonhosted.org/packages/be/86/b941012013260f95af2e90a3d9415af4a76a003a28412033fc4b09f35731/langsmith-0.3.45.tar.gz", hash = "sha256:1df3c6820c73ed210b2c7bc5cdb7bfa19ddc9126cd03fdf0da54e2e171e6094d", size = 348201, upload-time = "2025-06-05T05:10:28.948Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8e/e8a58e0abaae3f3ac4702e9ca35d1fc6159711556b64ffd0e247771a3f12/langsmith-0.3.42-py3-none-any.whl", hash = "sha256:18114327f3364385dae4026ebfd57d1c1cb46d8f80931098f0f10abe533475ff", size = 360334, upload-time = "2025-05-03T03:07:15.491Z" }, + { url = "https://files.pythonhosted.org/packages/6a/f4/c206c0888f8a506404cb4f16ad89593bdc2f70cf00de26a1a0a7a76ad7a3/langsmith-0.3.45-py3-none-any.whl", hash = "sha256:5b55f0518601fa65f3bb6b1a3100379a96aa7b3ed5e9380581615ba9c65ed8ed", size = 363002, upload-time = "2025-06-05T05:10:27.228Z" }, +] + +[[package]] +name = "lmnr" +version = "0.6.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argparse" }, + { name = "grpcio" }, + { name = "httpx" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-grpc" }, + { name = "opentelemetry-exporter-otlp-proto-http" }, + { name = "opentelemetry-instrumentation-threading" }, + { name = "opentelemetry-sdk" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "tenacity" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/8e/1f200facb37693d395777e9982d4c91a8c501d9b9b580c22213e0648af19/lmnr-0.6.10.tar.gz", hash = "sha256:1dbf603dff9693c509db6a27927aff15310fef9e12fb93b320e4e28a590fd43e", size = 139620, upload-time = "2025-06-12T16:44:36.503Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/73/8ff8475baa7b01c5de401c2461cb313804f97aaa6e9e79b35842922d49a7/lmnr-0.6.10-py3-none-any.whl", hash = "sha256:823608f35c219f038933f4925b1d14e3fc49ef18ae452bb7dc53287d550b5a58", size = 161003, upload-time = "2025-06-12T16:44:34.175Z" }, +] + +[package.optional-dependencies] +all = [ + { name = "opentelemetry-instrumentation-alephalpha" }, + { name = "opentelemetry-instrumentation-anthropic" }, + { name = "opentelemetry-instrumentation-bedrock" }, + { name = "opentelemetry-instrumentation-chromadb" }, + { name = "opentelemetry-instrumentation-cohere" }, + { name = "opentelemetry-instrumentation-crewai" }, + { name = "opentelemetry-instrumentation-google-generativeai" }, + { name = "opentelemetry-instrumentation-groq" }, + { name = "opentelemetry-instrumentation-haystack" }, + { name = "opentelemetry-instrumentation-lancedb" }, + { name = "opentelemetry-instrumentation-langchain" }, + { name = "opentelemetry-instrumentation-llamaindex" }, + { name = "opentelemetry-instrumentation-marqo" }, + { name = "opentelemetry-instrumentation-mcp" }, + { name = "opentelemetry-instrumentation-milvus" }, + { name = "opentelemetry-instrumentation-mistralai" }, + { name = "opentelemetry-instrumentation-ollama" }, + { name = "opentelemetry-instrumentation-openai" }, + { name = "opentelemetry-instrumentation-pinecone" }, + { name = "opentelemetry-instrumentation-qdrant" }, + { name = "opentelemetry-instrumentation-replicate" }, + { name = "opentelemetry-instrumentation-sagemaker" }, + { name = "opentelemetry-instrumentation-together" }, + { name = "opentelemetry-instrumentation-transformers" }, + { name = "opentelemetry-instrumentation-vertexai" }, + { name = "opentelemetry-instrumentation-watsonx" }, + { name = "opentelemetry-instrumentation-weaviate" }, ] [[package]] @@ -775,20 +869,19 @@ wheels = [ [[package]] name = "mem0ai" -version = "0.1.93" +version = "0.1.106" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "openai" }, { name = "posthog" }, - { name = "psycopg2-binary" }, { name = "pydantic" }, { name = "pytz" }, { name = "qdrant-client" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/94/e5/95e920e4f74f46a8dea3f0f45fa65a2e7bce8cdbe9fc084fb03c02c9ebf3/mem0ai-0.1.93.tar.gz", hash = "sha256:0c27e8dfb10235f18bf6e1bb007801750664d4c52cafa38e984a0f36b670ec62", size = 88253, upload-time = "2025-04-21T03:56:26.414Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6e/f3/5a5bd30e452c79078ac4d85e567674089fc526d8e2e3c5d62414a91f835a/mem0ai-0.1.106.tar.gz", hash = "sha256:4a38195d7783e05d1f7a026c73440e58cd6391c282ca77221172acd3e3470c49", size = 100803, upload-time = "2025-06-09T05:25:14.125Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/e9/ead222a9e11f224f07b7037ebceddfdab6dac4014e37f5a3560f5adb269b/mem0ai-0.1.93-py3-none-any.whl", hash = "sha256:7b8a5fb692fd0db67404f093304b05821eff88f360bba245750c597ae6c72cd3", size = 136765, upload-time = "2025-04-21T03:56:24.489Z" }, + { url = "https://files.pythonhosted.org/packages/66/29/3e44b620c915b7116e2685ade8f60311307b4b349249818d1e440b11bfad/mem0ai-0.1.106-py3-none-any.whl", hash = "sha256:65751efa4752959c1565526ae63a03829a1d5166410380bd9739e5dabadcf592", size = 156712, upload-time = "2025-06-09T05:25:12.016Z" }, ] [[package]] @@ -1011,6 +1104,553 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/d2/e3992bb7c6641b765c1008e3c96e076e0b50381be2cce344e6ff177bad80/openai-1.79.0-py3-none-any.whl", hash = "sha256:d5050b92d5ef83f869cb8dcd0aca0b2291c3413412500eec40c66981b3966992", size = 683334, upload-time = "2025-05-16T19:49:57.445Z" }, ] +[[package]] +name = "opentelemetry-api" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/5e/94a8cb759e4e409022229418294e098ca7feca00eb3c467bb20cbd329bda/opentelemetry_api-1.34.1.tar.gz", hash = "sha256:64f0bd06d42824843731d05beea88d4d4b6ae59f9fe347ff7dfa2cc14233bbb3", size = 64987, upload-time = "2025-06-10T08:55:19.818Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/3a/2ba85557e8dc024c0842ad22c570418dc02c36cbd1ab4b832a93edf071b8/opentelemetry_api-1.34.1-py3-none-any.whl", hash = "sha256:b7df4cb0830d5a6c29ad0c0691dbae874d8daefa934b8b1d642de48323d32a8c", size = 65767, upload-time = "2025-06-10T08:54:56.717Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/f0/ff235936ee40db93360233b62da932d4fd9e8d103cd090c6bcb9afaf5f01/opentelemetry_exporter_otlp_proto_common-1.34.1.tar.gz", hash = "sha256:b59a20a927facd5eac06edaf87a07e49f9e4a13db487b7d8a52b37cb87710f8b", size = 20817, upload-time = "2025-06-10T08:55:22.55Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/e8/8b292a11cc8d8d87ec0c4089ae21b6a58af49ca2e51fa916435bc922fdc7/opentelemetry_exporter_otlp_proto_common-1.34.1-py3-none-any.whl", hash = "sha256:8e2019284bf24d3deebbb6c59c71e6eef3307cd88eff8c633e061abba33f7e87", size = 18834, upload-time = "2025-06-10T08:55:00.806Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/f7/bb63837a3edb9ca857aaf5760796874e7cecddc88a2571b0992865a48fb6/opentelemetry_exporter_otlp_proto_grpc-1.34.1.tar.gz", hash = "sha256:7c841b90caa3aafcfc4fee58487a6c71743c34c6dc1787089d8b0578bbd794dd", size = 22566, upload-time = "2025-06-10T08:55:23.214Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/42/0a4dd47e7ef54edf670c81fc06a83d68ea42727b82126a1df9dd0477695d/opentelemetry_exporter_otlp_proto_grpc-1.34.1-py3-none-any.whl", hash = "sha256:04bb8b732b02295be79f8a86a4ad28fae3d4ddb07307a98c7aa6f331de18cca6", size = 18615, upload-time = "2025-06-10T08:55:02.214Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/8f/954bc725961cbe425a749d55c0ba1df46832a5999eae764d1a7349ac1c29/opentelemetry_exporter_otlp_proto_http-1.34.1.tar.gz", hash = "sha256:aaac36fdce46a8191e604dcf632e1f9380c7d5b356b27b3e0edb5610d9be28ad", size = 15351, upload-time = "2025-06-10T08:55:24.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/54/b05251c04e30c1ac70cf4a7c5653c085dfcf2c8b98af71661d6a252adc39/opentelemetry_exporter_otlp_proto_http-1.34.1-py3-none-any.whl", hash = "sha256:5251f00ca85872ce50d871f6d3cc89fe203b94c3c14c964bbdc3883366c705d8", size = 17744, upload-time = "2025-06-10T08:55:03.802Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation" +version = "0.55b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "packaging" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/69/d8995f229ddf4d98b9c85dd126aeca03dd1742f6dc5d3bc0d2f6dae1535c/opentelemetry_instrumentation-0.55b1.tar.gz", hash = "sha256:2dc50aa207b9bfa16f70a1a0571e011e737a9917408934675b89ef4d5718c87b", size = 28552, upload-time = "2025-06-10T08:58:15.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/7d/8ddfda1506c2fcca137924d5688ccabffa1aed9ec0955b7d0772de02cec3/opentelemetry_instrumentation-0.55b1-py3-none-any.whl", hash = "sha256:cbb1496b42bc394e01bc63701b10e69094e8564e281de063e4328d122cc7a97e", size = 31108, upload-time = "2025-06-10T08:57:14.355Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-alephalpha" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/27/df36a3dc360971e8f1cdcd88df253f66c6844b6885a47fc1e0ccc4544006/opentelemetry_instrumentation_alephalpha-0.40.9.tar.gz", hash = "sha256:0728634a513fe78d26a6be7bfd86abc33739c2f5e571ff67389a2246b7588872", size = 3493, upload-time = "2025-06-10T09:54:38.266Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/61/fced1bfeada1de7281a430354a1f6a6e497e4d93b98edf3031b956d52bac/opentelemetry_instrumentation_alephalpha-0.40.9-py3-none-any.whl", hash = "sha256:a23d2cb48222bc317639e0a10a4b992e6d91c33cd909e69e68adff2bb260afd8", size = 5093, upload-time = "2025-06-10T09:53:54.083Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-anthropic" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/51/af89c959aadb892636ffec58ef886df1c9bb3c6b8306fd6e4a0198fa86e8/opentelemetry_instrumentation_anthropic-0.40.9.tar.gz", hash = "sha256:b679aee7b53e75dbd583cea8105ade74f578e78dbca81695db04167d61df5349", size = 8967, upload-time = "2025-06-10T09:54:39.3Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/ab/945a8f7302ae81a4d8bfc65fbed37786859d60bc2c44cfb7726e7de3f2f6/opentelemetry_instrumentation_anthropic-0.40.9-py3-none-any.whl", hash = "sha256:ddb1ee97f584abaa19035ab12ad1326a3a6097acba18478351e380e25f65942d", size = 11507, upload-time = "2025-06-10T09:53:55.846Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-bedrock" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anthropic" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, + { name = "tokenizers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/3d/fb3a391c9091f9dbe19ff2f1ce6271f4be62f7c9c7ebf6fa2d73bfd86ea1/opentelemetry_instrumentation_bedrock-0.40.9.tar.gz", hash = "sha256:157d1e22b98ff114e9426ea17747389b6df5313c071ac950592539efde185279", size = 11822, upload-time = "2025-06-10T09:54:40.765Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/19/23c847bd1e2b341e5f77545d973ad82a4bc7e1d2a92ca30bd9dc9d3ff083/opentelemetry_instrumentation_bedrock-0.40.9-py3-none-any.whl", hash = "sha256:bca48724da026222be634284ebce1ecdd5d9bf95029b4ebd601b202c44db93ae", size = 14041, upload-time = "2025-06-10T09:53:57.684Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-chromadb" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/a6/920187b0549ad5cce4b7c24fa8ff28e05649f2206d22521744aae371e2c6/opentelemetry_instrumentation_chromadb-0.40.9.tar.gz", hash = "sha256:10281d863836057a434227adcdb1d0d75e84280afe24ff43e55e32eb3b4f0e2d", size = 4385, upload-time = "2025-06-10T09:54:41.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/c5/c9fa7795c0baacfde55b4caa30bb2f08a1f35482e1dc9a83b9a6c1c78d63/opentelemetry_instrumentation_chromadb-0.40.9-py3-none-any.whl", hash = "sha256:f51e3855498eb1546fc8df797e900b41715b59c7be2efb1b2d9142924301fefb", size = 6296, upload-time = "2025-06-10T09:53:59.014Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-cohere" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/bc/d2d2f499d08e9742d3cb30a0b06358f40403c253bdd403e8bc2448d59562/opentelemetry_instrumentation_cohere-0.40.9.tar.gz", hash = "sha256:6311acd11eeb59674880bcd710fe004bdd1d88fdf40575db3ed485ba79584773", size = 4153, upload-time = "2025-06-10T09:54:42.856Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/9e/97b077117dc97477cebb5ec969de5489c3973008cb99f9b7ada652936c48/opentelemetry_instrumentation_cohere-0.40.9-py3-none-any.whl", hash = "sha256:7055c152a9b31b1e435c2ca9224a8821e9384c257038f0feff95c38e5b254f7b", size = 5635, upload-time = "2025-06-10T09:54:00.814Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-crewai" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/16/f440e117e824d77aa1f3274491096272e30a543acb4760b889fd4b7e6ef1/opentelemetry_instrumentation_crewai-0.40.9.tar.gz", hash = "sha256:8e8ab47411250f8654b9fdd57a49227ce6da9404de3cd6fb82b2eca94f16fb8b", size = 4532, upload-time = "2025-06-10T09:54:43.847Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/85/c701d4c796652a0036e8373231c8ae9266f448d3982acb3ea6cbf194d890/opentelemetry_instrumentation_crewai-0.40.9-py3-none-any.whl", hash = "sha256:e3bcea02fa2dd94f81a9622173718b9bcc20b326ecc3cf72c64eb1943d39ad5b", size = 6068, upload-time = "2025-06-10T09:54:02.153Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-google-generativeai" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/8a/8bd84c7c34cfb1c9f7fe04cef239fac712af21d1c826cf818b2cc3bdac0d/opentelemetry_instrumentation_google_generativeai-0.40.9.tar.gz", hash = "sha256:4b901794a9690229fd5ebc3ce82addbdaa4b76123d8299652306ac8dcee892fa", size = 4397, upload-time = "2025-06-10T09:54:45.298Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/16/5b27f2625febea695e22abf99c77c435a9f2fae2b005511793409bdaa033/opentelemetry_instrumentation_google_generativeai-0.40.9-py3-none-any.whl", hash = "sha256:473ffe01f617b173072f71b1b092ac1932055817aa700e3a8fdfb1ca1085040b", size = 6068, upload-time = "2025-06-10T09:54:03.792Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-groq" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/b2/83cbd0aa789ffc3c0af40ab3fb463dbf5d4a93af74fb0cbd96b596b0f8f5/opentelemetry_instrumentation_groq-0.40.9.tar.gz", hash = "sha256:1b80bef2537bfae210c5a7f60c9d9e75d2dc49abcf6665099314c14383c0aa17", size = 6172, upload-time = "2025-06-10T09:54:46.294Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/e7/28d6378b80bcc2ea9c203009339d9d0dc9f592623f2bdee5f449304124e8/opentelemetry_instrumentation_groq-0.40.9-py3-none-any.whl", hash = "sha256:dfe6dd84c9ce3db1b46fe908608ebc81b61154abdf7466e5f46e92a905ac2b25", size = 7941, upload-time = "2025-06-10T09:54:05.766Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-haystack" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/b1/028cd4c7e20b39a344102f51629a61c3e7ad105671a182e409e27ddc19e3/opentelemetry_instrumentation_haystack-0.40.9.tar.gz", hash = "sha256:ddf59cd08ce22d9be712a960498843f17bae5b1bd3e8bc7fd1788d9c516dbba7", size = 4449, upload-time = "2025-06-10T09:54:47.253Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/a1/0f96d220fcaec3495eec1280ea5cdd6c60f4a6512cc83c590cf43e21d75a/opentelemetry_instrumentation_haystack-0.40.9-py3-none-any.whl", hash = "sha256:216ea89a71f3643f56699995f7dfaaf7318c6bed5a0398e52c9557b00087ecbe", size = 7486, upload-time = "2025-06-10T09:54:07.459Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-lancedb" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/6a/348cb5702ab4a646669034fb50834c36cf07cd97ed3fd995d60d344bda24/opentelemetry_instrumentation_lancedb-0.40.9.tar.gz", hash = "sha256:cb42fff3bac16e4e2c72fa1a6e4cb34bd7dbd3e1ea00855f61a420429a23f9de", size = 2987, upload-time = "2025-06-10T09:54:48.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/ad/6e5db0ffe8c8df96aeee4e003874ca1baa89a775f136856d1f204d2a690b/opentelemetry_instrumentation_lancedb-0.40.9-py3-none-any.whl", hash = "sha256:62fbd78a90e83e47f4741da5dd4baa0360ed25fc9598cc6d03a910dc79730929", size = 4769, upload-time = "2025-06-10T09:54:09.062Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-langchain" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/b6/5bb2dc96d5477bd4c59d577df182029457f6f03064ec8cca4bed92a6d641/opentelemetry_instrumentation_langchain-0.40.9.tar.gz", hash = "sha256:65f6de67f2bf730a21d5fce52d8757133b3b5002a494e09d5cd4640fb47f9a11", size = 9398, upload-time = "2025-06-10T09:54:49.223Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/6d/770fd09a9d96cce73088f43b7363643fd88ce46207aba03d6bfa19f5410e/opentelemetry_instrumentation_langchain-0.40.9-py3-none-any.whl", hash = "sha256:f82d5013dbbb39a5c61f0a9853853318771c0cb3fbb412358ccd90e1fe9eb235", size = 10824, upload-time = "2025-06-10T09:54:10.3Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-llamaindex" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "inflection" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/65/0033574a4f1dd1a3f1f0162ebef3f952c1cbb12dfd0069dc879b9ffe537d/opentelemetry_instrumentation_llamaindex-0.40.9.tar.gz", hash = "sha256:91145265a4e172934059eaa9953a2b4b54fe78956022ca505667ef8234309af2", size = 9395, upload-time = "2025-06-10T09:54:50.535Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/82/0d7297fa12d1f7433e08a3939b128b5499f076a7acd8a4736876a24543e6/opentelemetry_instrumentation_llamaindex-0.40.9-py3-none-any.whl", hash = "sha256:ecfb5bb7124f9461e542a27b795ccb2a82c69c8d75c227aa4e01a88a5c7c245d", size = 16737, upload-time = "2025-06-10T09:54:11.582Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-marqo" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b4/99/35b7ffb4881b92260266d999d407b35c96d2eca34d8f950d47d9a703f6a6/opentelemetry_instrumentation_marqo-0.40.9.tar.gz", hash = "sha256:c9c14d73952deddf92a512736ef06d198a2d59842e9148eac50292e163835745", size = 3260, upload-time = "2025-06-10T09:54:51.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/17/2aaa70d5b859bda45387172e6898c6543847728ee1cee4fff1740545006a/opentelemetry_instrumentation_marqo-0.40.9-py3-none-any.whl", hash = "sha256:3db0970467179175d5c453042b5b4f7f8873774f4b34fcc91ae78f3e5a3f3639", size = 5071, upload-time = "2025-06-10T09:54:13.384Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-mcp" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/c6/b2f253371d7d0c4a9a9ed08c8dee7d706051411d7c0257cf7505ace28e3e/opentelemetry_instrumentation_mcp-0.40.9.tar.gz", hash = "sha256:a72b251358b442e9b6b56601deb35da729a6962d16e105ac1c0706e809496c39", size = 4576, upload-time = "2025-06-10T09:54:52.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/bb/c3d014a9896766fbce72d42af679b8285478c4a83d935f951e0b72ab732e/opentelemetry_instrumentation_mcp-0.40.9-py3-none-any.whl", hash = "sha256:7449dee98125de1f5e3f1c1203144fae1ec2379edd75ca07f3ecf213f96e1963", size = 5818, upload-time = "2025-06-10T09:54:15.066Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-milvus" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/cb/4b2b565d0c74ff0888ba8559493a9ad415a7d3bbae71dd61fb772cb67e64/opentelemetry_instrumentation_milvus-0.40.9.tar.gz", hash = "sha256:b05043cf5edffd6e9586b8c2ca806f04acb9e84c91420cd1042895a611fee655", size = 4253, upload-time = "2025-06-10T09:54:53.929Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/26/8287827fdbbbbbcd95e3e07b48d0a3ee0d16e39d7a971277303d35a27f98/opentelemetry_instrumentation_milvus-0.40.9-py3-none-any.whl", hash = "sha256:5dd21c3541f1820cb5ded60bb5e9de96b7474035a669d98d1148b4291a7cdbb5", size = 6071, upload-time = "2025-06-10T09:54:16.801Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-mistralai" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/ca/07e85d3da58419cb7996fd7922cc0544c913d71403d22c63f6a26fea2bfe/opentelemetry_instrumentation_mistralai-0.40.9.tar.gz", hash = "sha256:5ec356c8d1976543eb402d4f962be1aaef818ee568cb353e88a4713e1e47cbff", size = 4344, upload-time = "2025-06-10T09:54:54.985Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/24/a11168a21fa08726a95d1b8c1af2add0de5d96538d231afa0d5f8bfeb145/opentelemetry_instrumentation_mistralai-0.40.9-py3-none-any.whl", hash = "sha256:870cbeaba86b6aef37d1526563d175278305b641cd5f1f7df94d3210e868c867", size = 5937, upload-time = "2025-06-10T09:54:18.041Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-ollama" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/9c/640f91e984269512f1a10e6be9952cfc246504a6373c42501981154c0015/opentelemetry_instrumentation_ollama-0.40.9.tar.gz", hash = "sha256:57f1f2123b0e5920150c4bea8ac03a1dfe745732dfcaf6e40ab6d4484283e6ff", size = 5676, upload-time = "2025-06-10T09:54:55.961Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/0c/f0cb030e5461002437a39d8b3f2ab3b160b4ea847197c60521fc8dcd976c/opentelemetry_instrumentation_ollama-0.40.9-py3-none-any.whl", hash = "sha256:d1227f8b48f53ff8ed95786f96566920ae912e7954068c63d061dfa9d325bc27", size = 7186, upload-time = "2025-06-10T09:54:19.216Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-openai" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, + { name = "tiktoken" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/cb/d5856fc1277b0c3b6484270fb4df4a5e17ca1930693f05ccbfb7f8bed7e9/opentelemetry_instrumentation_openai-0.40.9.tar.gz", hash = "sha256:9effcc13a006f6585266a9c063d9f68fb20b3a5c44564df93d987519d3a3d2d1", size = 15119, upload-time = "2025-06-10T09:54:56.941Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/8e/aad8d580aeb03995dc205bbef9254d926f3f31dd8e6635edf6fd4df7e70a/opentelemetry_instrumentation_openai-0.40.9-py3-none-any.whl", hash = "sha256:e3d6c2a61f6de1b35202c3d86fde7d5f2c17169417c487d17e43dd9455414a30", size = 23121, upload-time = "2025-06-10T09:54:20.898Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-pinecone" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/b0/e1f3eea2bf7870e84cd71a285c4124ac7277177b92e08a9b300ad9bda4c8/opentelemetry_instrumentation_pinecone-0.40.9.tar.gz", hash = "sha256:8e1a562dc36fa53327dfbc203746e2d24371c76517a061c87c6420110a5a3855", size = 4484, upload-time = "2025-06-10T09:54:58.05Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/fd/823b30e2ed80720fc048d9fe72cffb9365bcaf8621730560c99b7797e34b/opentelemetry_instrumentation_pinecone-0.40.9-py3-none-any.whl", hash = "sha256:608e55e38142198c5839526e18f458291c8f65f1261fb71f66baa6440e269841", size = 6356, upload-time = "2025-06-10T09:54:25.506Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-qdrant" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/8b/106d3da7285514403a2344767f85588ef0e2250047cc1b4fab2710a79abd/opentelemetry_instrumentation_qdrant-0.40.9.tar.gz", hash = "sha256:a8efb48ea8880de7790e59eb2a2cd5a324d29eebee41ed910397c8de44c287ef", size = 3804, upload-time = "2025-06-10T09:54:59.021Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/71/1522f5baefdea4be4684ba37fc1b5542e8ecb16260e096b7e4a9a2afeb94/opentelemetry_instrumentation_qdrant-0.40.9-py3-none-any.whl", hash = "sha256:ec338f690963fa660b13ba37b07a3cd20421217837fdc7c8e802d84cd2f9cbfb", size = 6296, upload-time = "2025-06-10T09:54:27.225Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-replicate" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/83/01189e941313236ee0d46794d9b3185054198266b02c6fd86aad7b8c2ea7/opentelemetry_instrumentation_replicate-0.40.9.tar.gz", hash = "sha256:6cb2dc6fd816233f287c1af736dac7aaf332d57c0396b3a3fe273bd108525c33", size = 3563, upload-time = "2025-06-10T09:55:00.142Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/ca/c66b9941e4674c7183a15a6150da12a82110fa652606bae9f03b4361a0b5/opentelemetry_instrumentation_replicate-0.40.9-py3-none-any.whl", hash = "sha256:a82a65ab1ebba8dafb5282008f6e3fcad36654551ecc8e46f0c88262ee2ed111", size = 5167, upload-time = "2025-06-10T09:54:28.462Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-sagemaker" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b0/b7/0181f75d2e8b890794c75778798675e33b7cc923d4ea2b978ac965c4135d/opentelemetry_instrumentation_sagemaker-0.40.9.tar.gz", hash = "sha256:e36e77f317776a79246cb602d62a4d66803efc331f0508805ae3034b52a715f7", size = 4343, upload-time = "2025-06-10T09:55:01.103Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/16/af8087b7a1f0c5ac3b05dee79e2b1554af050d15082a2698b1c5d56b31b4/opentelemetry_instrumentation_sagemaker-0.40.9-py3-none-any.whl", hash = "sha256:226be56670e6dc2e1914b892cfef6963509e9c58cc9a0885cf55156906ad9349", size = 6274, upload-time = "2025-06-10T09:54:29.643Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-threading" +version = "0.55b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e6/a2/470bbc9b7060372d6b183d999080c12a63fb459fc77b9be0ca15694ecabe/opentelemetry_instrumentation_threading-0.55b1.tar.gz", hash = "sha256:4ed68502e7ed017bfc10b1f9e508cc5ccaea0e46ac1010f7f2541ab9c6eacd92", size = 8767, upload-time = "2025-06-10T08:58:46.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/c9/183ad41a7ba0374030b3eab335ec6f3eff6acca057aba2b393183e18639e/opentelemetry_instrumentation_threading-0.55b1-py3-none-any.whl", hash = "sha256:f865542b32b219c8fd01deb03b8c3c9ba2eb3f0501ae303338403fd2242962c7", size = 9313, upload-time = "2025-06-10T08:58:02.884Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-together" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/df/d8835dd99558d74951ce6af3180e04a49f3500c16ac5d9c2fc458e7cb836/opentelemetry_instrumentation_together-0.40.9.tar.gz", hash = "sha256:8b373b4dd8c2b09da972742561dc66f007920e424ba390171792bb5f4f056a3f", size = 3754, upload-time = "2025-06-10T09:55:02.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/19/1cea5b7cc6b2e2183883f10c5bf221d9750260916994cbf5be1dd2a995a8/opentelemetry_instrumentation_together-0.40.9-py3-none-any.whl", hash = "sha256:efe8cc98b0b5826d1512b0a70e2e447ddc87dca009cb826d67dc4657933933eb", size = 5310, upload-time = "2025-06-10T09:54:30.886Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-transformers" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/d5/e87f73a121b86399efd46d96ae25e727a5d23ed4e1fc25aecabb0d255e4b/opentelemetry_instrumentation_transformers-0.40.9.tar.gz", hash = "sha256:b25fb45a707f11814507abdc1720a9083a8dec6c0cf4883e9ebbdb671e4f5415", size = 3632, upload-time = "2025-06-10T09:55:03.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/02/7218342c58e1dbf714267a16f5898dd4a0730644d20797fbd39849ea43b0/opentelemetry_instrumentation_transformers-0.40.9-py3-none-any.whl", hash = "sha256:74c2400b624beb6d573398cd6714bd59a4711a3303f753368f67637ed0c290c5", size = 5237, upload-time = "2025-06-10T09:54:33.044Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-vertexai" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/98/045e5a0c65bd47aaa99b5b64fcb2bfbd53fa75e4f24cc9e075a5f08813f0/opentelemetry_instrumentation_vertexai-0.40.9.tar.gz", hash = "sha256:4b8a31c1f0337cca3d62f882e1b1162686e0fc3f2217d49f92e736e2ba073fcd", size = 4213, upload-time = "2025-06-10T09:55:04.294Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/31/39d6e667e0ec0b74597910f51b89fac265aa358260f2ec521651f28b9f72/opentelemetry_instrumentation_vertexai-0.40.9-py3-none-any.whl", hash = "sha256:7daacf6cd97d030524cb94b090a997f6458ceee96e0bcf5fb6cfc9d29e1bf73e", size = 5770, upload-time = "2025-06-10T09:54:34.572Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-watsonx" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/d2/6a03e6d830b82a5b12b46566eee1eb9f8eb0e9d9d0cdc84de3452a930f79/opentelemetry_instrumentation_watsonx-0.40.9.tar.gz", hash = "sha256:5d977560de2eee0d6fda7d55a778c45cf222ddcc24b27675f716a82e78d92bec", size = 5767, upload-time = "2025-06-10T09:55:05.266Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/6a/78e7c4d595ee12e0ee07885b9e6b0b38ba31dc96b163c9398256d4d0b058/opentelemetry_instrumentation_watsonx-0.40.9-py3-none-any.whl", hash = "sha256:9e6faea067d47bc55fa4f770c09705c4f642508a57dd2ae7f00c7bf03133ac14", size = 7438, upload-time = "2025-06-10T09:54:35.809Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-weaviate" +version = "0.40.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-semantic-conventions-ai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/87/2454190be7d2c3c3701aa0579af35a4c77dcb71a6a89a2e3117a89f2b74c/opentelemetry_instrumentation_weaviate-0.40.9.tar.gz", hash = "sha256:4ed43463bf45c53f3e5e209681a571a710b7b8f7c05bb0beb2ccb5704bcad6c8", size = 4431, upload-time = "2025-06-10T09:55:06.212Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f0/8aef2146c6aea1f30e969aa65288c14af8904faf5eefa4a30538695ba365/opentelemetry_instrumentation_weaviate-0.40.9-py3-none-any.whl", hash = "sha256:3d85714a434b6c08582d52bd1f41a4f21cd3f24b5ca471e10c7c2b696e590080", size = 6403, upload-time = "2025-06-10T09:54:37.02Z" }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/b3/c3158dd012463bb7c0eb7304a85a6f63baeeb5b4c93a53845cf89f848c7e/opentelemetry_proto-1.34.1.tar.gz", hash = "sha256:16286214e405c211fc774187f3e4bbb1351290b8dfb88e8948af209ce85b719e", size = 34344, upload-time = "2025-06-10T08:55:32.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/ab/4591bfa54e946350ce8b3f28e5c658fe9785e7cd11e9c11b1671a867822b/opentelemetry_proto-1.34.1-py3-none-any.whl", hash = "sha256:eb4bb5ac27f2562df2d6857fc557b3a481b5e298bc04f94cc68041f00cebcbd2", size = 55692, upload-time = "2025-06-10T08:55:14.904Z" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.34.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/41/fe20f9036433da8e0fcef568984da4c1d1c771fa072ecd1a4d98779dccdd/opentelemetry_sdk-1.34.1.tar.gz", hash = "sha256:8091db0d763fcd6098d4781bbc80ff0971f94e260739aa6afe6fd379cdf3aa4d", size = 159441, upload-time = "2025-06-10T08:55:33.028Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/1b/def4fe6aa73f483cabf4c748f4c25070d5f7604dcc8b52e962983491b29e/opentelemetry_sdk-1.34.1-py3-none-any.whl", hash = "sha256:308effad4059562f1d92163c61c8141df649da24ce361827812c40abb2a1e96e", size = 118477, upload-time = "2025-06-10T08:55:16.02Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.55b1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/f0/f33458486da911f47c4aa6db9bda308bb80f3236c111bf848bd870c16b16/opentelemetry_semantic_conventions-0.55b1.tar.gz", hash = "sha256:ef95b1f009159c28d7a7849f5cbc71c4c34c845bb514d66adfdf1b3fff3598b3", size = 119829, upload-time = "2025-06-10T08:55:33.881Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/89/267b0af1b1d0ba828f0e60642b6a5116ac1fd917cde7fc02821627029bd1/opentelemetry_semantic_conventions-0.55b1-py3-none-any.whl", hash = "sha256:5da81dfdf7d52e3d37f8fe88d5e771e191de924cfff5f550ab0b8f7b2409baed", size = 196223, upload-time = "2025-06-10T08:55:17.638Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions-ai" +version = "0.4.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/ba/2405abde825cf654d09ba16bfcfb8c863156bccdc47d1f2a86df6331e7bb/opentelemetry_semantic_conventions_ai-0.4.9.tar.gz", hash = "sha256:54a0b901959e2de5124384925846bac2ea0a6dab3de7e501ba6aecf5e293fe04", size = 4920, upload-time = "2025-05-16T10:20:54.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/98/f5196ba0f4105a4790cec8c6671cf676c96dfa29bfedfe3c4f112bf4e6ad/opentelemetry_semantic_conventions_ai-0.4.9-py3-none-any.whl", hash = "sha256:71149e46a72554ae17de46bca6c11ba540c19c89904bd4cc3111aac6edf10315", size = 5617, upload-time = "2025-05-16T10:20:53.062Z" }, +] + [[package]] name = "orjson" version = "3.10.18" @@ -1043,6 +1683,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] +[[package]] +name = "patchright" +version = "1.52.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet" }, + { name = "pyee" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/21/807e0d7f672ab40095b493fd648d2dc9af72cd8df5a30055a0e8d572586b/patchright-1.52.5-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:2d8d7755b55671b450e4153f0baa00bde2cf9a8edb42782c8b41f43707975314", size = 39593027, upload-time = "2025-06-05T21:53:56.685Z" }, + { url = "https://files.pythonhosted.org/packages/f3/31/6d48d2acc2641b0f120174746b18aadae85c501cac2f89d9165a2c099da9/patchright-1.52.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d862436ba5401de4263aeade9fb2d9421f0ab1442a679eff2d8995f973682b06", size = 37944754, upload-time = "2025-06-05T21:54:02.197Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a3/b20fa2714fed92d976ae04585ebf4b52f514246f32f49b0b2600a2b5d083/patchright-1.52.5-py3-none-macosx_11_0_universal2.whl", hash = "sha256:88f64aa2fd647c349055ce0897ed9e5df50f4beb1da6224dd86f6fb9a66af693", size = 39593026, upload-time = "2025-06-05T21:54:05.733Z" }, + { url = "https://files.pythonhosted.org/packages/53/0c/78323bf5628bcf82f55220447d09bed54058add39ca214cdf1f9d1a13465/patchright-1.52.5-py3-none-manylinux1_x86_64.whl", hash = "sha256:f53f6e79befbeb7ef42d00af42768a676bbb68d5674af824ae5fb2e9f0e339ec", size = 45123113, upload-time = "2025-06-05T21:54:09.203Z" }, + { url = "https://files.pythonhosted.org/packages/99/a8/8ae90d5cba61af723d321e4eed1fee065609033ad9f2596e952f5e0d09f5/patchright-1.52.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804a67ac3faf1f1c06957ac6124c1e04faf8fa72aa15ccc5baea51c6740e8704", size = 44522410, upload-time = "2025-06-05T21:54:13.562Z" }, + { url = "https://files.pythonhosted.org/packages/b4/58/7cb5211098f1665249af337843cfd1772ca3daa439cb77a042eefcb832b3/patchright-1.52.5-py3-none-win32.whl", hash = "sha256:127b70d12de28d6d70bf1033b386c7b787c58b5535750f915dfe0c6aec4a8bdf", size = 34820935, upload-time = "2025-06-05T21:54:17.143Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/e30391b7e610a6e0b536cfb92a01a6af2ca1fc2f3b37e69ad5a3982b94dc/patchright-1.52.5-py3-none-win_amd64.whl", hash = "sha256:043e25cbb69e11db002770fde27eb14c59e5751f16969b4e3d4483e452537dc1", size = 34820943, upload-time = "2025-06-05T21:54:20.105Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6a/b8f0fd8c513667b59b85d3969a5af65a5f2410ff41aff04d597ed5b872d0/patchright-1.52.5-py3-none-win_arm64.whl", hash = "sha256:f406911b5b3b21d70e3b1d1a2780b732575e31f2b012483622cc764166a31d78", size = 30670751, upload-time = "2025-06-05T21:54:23.336Z" }, +] + [[package]] name = "pillow" version = "11.2.1" @@ -1135,16 +1794,16 @@ wheels = [ [[package]] name = "protobuf" -version = "6.31.0" +version = "5.29.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/48/718c1e104a2e89970a8ff3b06d87e152834b576c570a6908f8c17ba88d65/protobuf-6.31.0.tar.gz", hash = "sha256:314fab1a6a316469dc2dd46f993cbbe95c861ea6807da910becfe7475bc26ffe", size = 441644, upload-time = "2025-05-14T17:58:27.862Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/29/d09e70352e4e88c9c7a198d5645d7277811448d76c23b00345670f7c8a38/protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84", size = 425226, upload-time = "2025-05-28T23:51:59.82Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/77/8671682038b08237c927215fa3296bc1c54e4086fe542c87017c1b626663/protobuf-6.31.0-cp310-abi3-win32.whl", hash = "sha256:10bd62802dfa0588649740a59354090eaf54b8322f772fbdcca19bc78d27f0d6", size = 423437, upload-time = "2025-05-14T17:58:16.116Z" }, - { url = "https://files.pythonhosted.org/packages/e4/07/cc9b0cbf7593f6ef8cf87fa9b0e55cd74c5cb526dd89ad84aa7d6547ef8d/protobuf-6.31.0-cp310-abi3-win_amd64.whl", hash = "sha256:3e987c99fd634be8347246a02123250f394ba20573c953de133dc8b2c107dd71", size = 435118, upload-time = "2025-05-14T17:58:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/21/46/33f884aa8bc59114dc97e0d954ca4618c556483670236008c88fbb7e834f/protobuf-6.31.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2c812f0f96ceb6b514448cefeb1df54ec06dde456783f5099c0e2f8a0f2caa89", size = 425439, upload-time = "2025-05-14T17:58:19.709Z" }, - { url = "https://files.pythonhosted.org/packages/9b/f2/9a676b50229ce37b12777d7b21de90ae7bc0f9505d07e72e2e8d47b8d165/protobuf-6.31.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:67ce50195e4e584275623b8e6bc6d3d3dfd93924bf6116b86b3b8975ab9e4571", size = 321950, upload-time = "2025-05-14T17:58:22.04Z" }, - { url = "https://files.pythonhosted.org/packages/a1/a7/243fa2d3c1b7675d54744b32dacf30356f4c27c0d3ad940ca8745a1c6b2c/protobuf-6.31.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:5353e38844168a327acd2b2aa440044411cd8d1b6774d5701008bd1dba067c79", size = 320904, upload-time = "2025-05-14T17:58:23.438Z" }, - { url = "https://files.pythonhosted.org/packages/ee/01/1ed1d482960a5718fd99c82f6d79120181947cfd4667ec3944d448ed44a3/protobuf-6.31.0-py3-none-any.whl", hash = "sha256:6ac2e82556e822c17a8d23aa1190bbc1d06efb9c261981da95c71c9da09e9e23", size = 168558, upload-time = "2025-05-14T17:58:26.923Z" }, + { url = "https://files.pythonhosted.org/packages/5f/11/6e40e9fc5bba02988a214c07cf324595789ca7820160bfd1f8be96e48539/protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079", size = 422963, upload-time = "2025-05-28T23:51:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/81/7f/73cefb093e1a2a7c3ffd839e6f9fcafb7a427d300c7f8aef9c64405d8ac6/protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc", size = 434818, upload-time = "2025-05-28T23:51:44.297Z" }, + { url = "https://files.pythonhosted.org/packages/dd/73/10e1661c21f139f2c6ad9b23040ff36fee624310dc28fba20d33fdae124c/protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671", size = 418091, upload-time = "2025-05-28T23:51:45.907Z" }, + { url = "https://files.pythonhosted.org/packages/6c/04/98f6f8cf5b07ab1294c13f34b4e69b3722bb609c5b701d6c169828f9f8aa/protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015", size = 319824, upload-time = "2025-05-28T23:51:47.545Z" }, + { url = "https://files.pythonhosted.org/packages/85/e4/07c80521879c2d15f321465ac24c70efe2381378c00bf5e56a0f4fbac8cd/protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61", size = 319942, upload-time = "2025-05-28T23:51:49.11Z" }, + { url = "https://files.pythonhosted.org/packages/7e/cc/7e77861000a0691aeea8f4566e5d3aa716f2b1dece4a24439437e41d3d25/protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5", size = 172823, upload-time = "2025-05-28T23:51:58.157Z" }, ] [[package]] @@ -1162,25 +1821,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, ] -[[package]] -name = "psycopg2-binary" -version = "2.9.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764, upload-time = "2024-10-16T11:24:58.126Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699, upload-time = "2024-10-16T11:21:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245, upload-time = "2024-10-16T11:21:51.989Z" }, - { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631, upload-time = "2024-10-16T11:21:57.584Z" }, - { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140, upload-time = "2024-10-16T11:22:02.005Z" }, - { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762, upload-time = "2024-10-16T11:22:06.412Z" }, - { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967, upload-time = "2024-10-16T11:22:11.583Z" }, - { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326, upload-time = "2024-10-16T11:22:16.406Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712, upload-time = "2024-10-16T11:22:21.366Z" }, - { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155, upload-time = "2024-10-16T11:22:25.684Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356, upload-time = "2024-10-16T11:22:30.562Z" }, - { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224, upload-time = "2025-01-04T20:09:19.234Z" }, -] - [[package]] name = "pyasn1" version = "0.6.1" @@ -1213,41 +1853,45 @@ wheels = [ [[package]] name = "pydantic" -version = "2.10.6" +version = "2.11.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, + { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681, upload-time = "2025-01-24T01:42:12.693Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102, upload-time = "2025-05-22T21:18:08.761Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696, upload-time = "2025-01-24T01:42:10.371Z" }, + { url = "https://files.pythonhosted.org/packages/b5/69/831ed22b38ff9b4b64b66569f0e5b7b97cf3638346eb95a2147fdb49ad5f/pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7", size = 444229, upload-time = "2025-05-22T21:18:06.329Z" }, ] [[package]] name = "pydantic-core" -version = "2.27.2" +version = "2.33.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" }, - { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" }, - { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" }, - { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" }, - { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" }, - { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" }, - { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" }, - { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" }, - { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" }, - { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" }, - { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" }, - { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" }, - { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, ] [[package]] @@ -4142,6 +4786,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, ] +[[package]] +name = "typing-inspection" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, +] + [[package]] name = "urllib3" version = "2.4.0" @@ -4151,6 +4807,55 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, ] +[[package]] +name = "uuid7" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/19/7472bd526591e2192926247109dbf78692e709d3e56775792fec877a7720/uuid7-0.1.0.tar.gz", hash = "sha256:8c57aa32ee7456d3cc68c95c4530bc571646defac01895cfc73545449894a63c", size = 14052, upload-time = "2021-12-29T01:38:21.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/77/8852f89a91453956582a85024d80ad96f30a41fed4c2b3dce0c9f12ecc7e/uuid7-0.1.0-py2.py3-none-any.whl", hash = "sha256:5e259bb63c8cb4aded5927ff41b444a80d0c7124e8a0ced7cf44efa1f5cccf61", size = 7477, upload-time = "2021-12-29T01:38:20.418Z" }, +] + +[[package]] +name = "wrapt" +version = "1.17.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531, upload-time = "2025-01-14T10:35:45.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", size = 53800, upload-time = "2025-01-14T10:34:21.571Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", size = 38824, upload-time = "2025-01-14T10:34:22.999Z" }, + { url = "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", size = 38920, upload-time = "2025-01-14T10:34:25.386Z" }, + { url = "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", size = 88690, upload-time = "2025-01-14T10:34:28.058Z" }, + { url = "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", size = 80861, upload-time = "2025-01-14T10:34:29.167Z" }, + { url = "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", size = 89174, upload-time = "2025-01-14T10:34:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", size = 86721, upload-time = "2025-01-14T10:34:32.91Z" }, + { url = "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", size = 79763, upload-time = "2025-01-14T10:34:34.903Z" }, + { url = "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", size = 87585, upload-time = "2025-01-14T10:34:36.13Z" }, + { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676, upload-time = "2025-01-14T10:34:37.962Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871, upload-time = "2025-01-14T10:34:39.13Z" }, + { url = "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", size = 56312, upload-time = "2025-01-14T10:34:40.604Z" }, + { url = "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", size = 40062, upload-time = "2025-01-14T10:34:45.011Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", size = 40155, upload-time = "2025-01-14T10:34:47.25Z" }, + { url = "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", size = 113471, upload-time = "2025-01-14T10:34:50.934Z" }, + { url = "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", size = 101208, upload-time = "2025-01-14T10:34:52.297Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", size = 109339, upload-time = "2025-01-14T10:34:53.489Z" }, + { url = "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", size = 110232, upload-time = "2025-01-14T10:34:55.327Z" }, + { url = "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", size = 100476, upload-time = "2025-01-14T10:34:58.055Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", size = 106377, upload-time = "2025-01-14T10:34:59.3Z" }, + { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986, upload-time = "2025-01-14T10:35:00.498Z" }, + { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750, upload-time = "2025-01-14T10:35:03.378Z" }, + { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594, upload-time = "2025-01-14T10:35:44.018Z" }, +] + +[[package]] +name = "zipp" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, +] + [[package]] name = "zstandard" version = "0.23.0"