diff --git a/litellm/constants.py b/litellm/constants.py index 8a74ca21ff9..9af40744896 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -47,18 +47,18 @@ ROUTER_SETTINGS_MANAGED_OUTSIDE_CONFIG: Final[frozenset[str]] = frozenset( DEFAULT_BATCH_SIZE: Final = int(os.getenv("DEFAULT_BATCH_SIZE", 512)) DEFAULT_FLUSH_INTERVAL_SECONDS: Final = int(os.getenv("DEFAULT_FLUSH_INTERVAL_SECONDS", 5)) # Agent tracing / ClickHouse -CLICKHOUSE_BATCH_SIZE: Final = int(os.getenv("CLICKHOUSE_BATCH_SIZE", 10_000)) -CLICKHOUSE_FLUSH_INTERVAL_SECONDS: Final = float(os.getenv("CLICKHOUSE_FLUSH_INTERVAL_SECONDS", 1.0)) -CLICKHOUSE_MAX_BUFFERED_ROWS: Final = int(os.getenv("CLICKHOUSE_MAX_BUFFERED_ROWS", 200_000)) -CLICKHOUSE_MAX_RETRIES: Final = int(os.getenv("CLICKHOUSE_MAX_RETRIES", 3)) -AGENT_TRACING_RETENTION_DAYS: Final = int(os.getenv("AGENT_TRACING_RETENTION_DAYS", 30)) -AGENT_TRACING_SPEND_LOG_RETENTION_DAYS: Final = int(os.getenv("AGENT_TRACING_SPEND_LOG_RETENTION_DAYS", 90)) -OTLP_MAX_BODY_BYTES: Final = int(os.getenv("OTLP_MAX_BODY_BYTES", 8 * 1024 * 1024)) -OTLP_MAX_ATTRIBUTE_VALUE_BYTES: Final = int(os.getenv("OTLP_MAX_ATTRIBUTE_VALUE_BYTES", 64 * 1024)) -OTLP_RETRY_AFTER_SECONDS: Final = int(os.getenv("OTLP_RETRY_AFTER_SECONDS", 2)) -OTLP_OFFLOAD_DECODE_BYTES: Final = int(os.getenv("OTLP_OFFLOAD_DECODE_BYTES", 256 * 1024)) -AGENT_TRACING_INPUT_PREVIEW_CHARS: Final = int(os.getenv("AGENT_TRACING_INPUT_PREVIEW_CHARS", 240)) -AGENT_TRACING_LIST_PAGE_SIZE: Final = int(os.getenv("AGENT_TRACING_LIST_PAGE_SIZE", 50)) +CLICKHOUSE_BATCH_SIZE: Final = get_env_int("CLICKHOUSE_BATCH_SIZE", 10_000) +CLICKHOUSE_FLUSH_INTERVAL_SECONDS: Final = float(os.getenv("CLICKHOUSE_FLUSH_INTERVAL_SECONDS", "1.0")) +CLICKHOUSE_MAX_BUFFERED_ROWS: Final = get_env_int("CLICKHOUSE_MAX_BUFFERED_ROWS", 200_000) +CLICKHOUSE_MAX_RETRIES: Final = get_env_int("CLICKHOUSE_MAX_RETRIES", 3) +AGENT_TRACING_RETENTION_DAYS: Final = get_env_int("AGENT_TRACING_RETENTION_DAYS", 30) +AGENT_TRACING_SPEND_LOG_RETENTION_DAYS: Final = get_env_int("AGENT_TRACING_SPEND_LOG_RETENTION_DAYS", 90) +OTLP_MAX_BODY_BYTES: Final = get_env_int("OTLP_MAX_BODY_BYTES", 8 * 1024 * 1024) +OTLP_MAX_ATTRIBUTE_VALUE_BYTES: Final = get_env_int("OTLP_MAX_ATTRIBUTE_VALUE_BYTES", 64 * 1024) +OTLP_RETRY_AFTER_SECONDS: Final = get_env_int("OTLP_RETRY_AFTER_SECONDS", 2) +OTLP_OFFLOAD_DECODE_BYTES: Final = get_env_int("OTLP_OFFLOAD_DECODE_BYTES", 256 * 1024) +AGENT_TRACING_INPUT_PREVIEW_CHARS: Final = get_env_int("AGENT_TRACING_INPUT_PREVIEW_CHARS", 240) +AGENT_TRACING_LIST_PAGE_SIZE: Final = get_env_int("AGENT_TRACING_LIST_PAGE_SIZE", 50) DEFAULT_S3_FLUSH_INTERVAL_SECONDS: Final = int(os.getenv("DEFAULT_S3_FLUSH_INTERVAL_SECONDS", 10)) DEFAULT_S3_BATCH_SIZE: Final = int(os.getenv("DEFAULT_S3_BATCH_SIZE", 512)) DEFAULT_S3_MAX_CONCURRENT_UPLOADS: Final = int(os.getenv("DEFAULT_S3_MAX_CONCURRENT_UPLOADS", "16")) diff --git a/litellm/integrations/clickhouse/clickhouse_batch_logger.py b/litellm/integrations/clickhouse/clickhouse_batch_logger.py index 5e53987de94..fb9088f44ff 100644 --- a/litellm/integrations/clickhouse/clickhouse_batch_logger.py +++ b/litellm/integrations/clickhouse/clickhouse_batch_logger.py @@ -33,7 +33,7 @@ def clickhouse_storage_from_env() -> TraceStorage: class ClickHouseBatchLogger(CustomBatchLogger): table: ClassVar[str] - def __init__(self, storage: TraceStorage | None = None, **kwargs: Any) -> None: + def __init__(self, storage: TraceStorage | None = None) -> None: self.storage = storage or clickhouse_storage_from_env() self.rows_written = 0 self.rows_dropped = 0 @@ -42,7 +42,6 @@ class ClickHouseBatchLogger(CustomBatchLogger): flush_lock=asyncio.Lock(), batch_size=CLICKHOUSE_BATCH_SIZE, flush_interval=CLICKHOUSE_FLUSH_INTERVAL_SECONDS, - **kwargs, ) try: asyncio.get_running_loop().create_task(self.periodic_flush()) @@ -73,7 +72,7 @@ class ClickHouseBatchLogger(CustomBatchLogger): if not await self._insert(batch): break - async def async_send_batch(self, *args: Any, **kwargs: Any) -> None: + async def async_send_batch(self) -> None: await self.flush_queue() async def _insert(self, batch: list[dict[str, Any]]) -> bool: diff --git a/litellm/proxy/tracing_endpoints.py b/litellm/proxy/tracing_endpoints.py index 198af8193df..1486c218683 100644 --- a/litellm/proxy/tracing_endpoints.py +++ b/litellm/proxy/tracing_endpoints.py @@ -8,7 +8,7 @@ GET /v1/traces/{trace_id}/spans/{span_id} SpanDetail """ import time -from typing import Final +from typing import Annotated, Final from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response @@ -71,7 +71,7 @@ async def _read_otlp_body(request: Request) -> bytes: @router.post("/v1/traces", include_in_schema=False) async def ingest_otlp_traces( request: Request, - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), + user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], ) -> Response: if user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY: raise HTTPException(status_code=403, detail="Not allowed to ingest agent traces") @@ -94,10 +94,10 @@ async def ingest_otlp_traces( @router.get("/v1/traces", response_model=None) async def list_agent_traces( - start_ms: int | None = Query(None, description="Window start, unix ms. Default: 24h ago"), - end_ms: int | None = Query(None, description="Window end, unix ms. Default: now"), - cursor: str | None = Query(None), - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), + user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], + start_ms: Annotated[int | None, Query(description="Window start, unix ms. Default: 24h ago")] = None, + end_ms: Annotated[int | None, Query(description="Window end, unix ms. Default: now")] = None, + cursor: Annotated[str | None, Query()] = None, ) -> TracePage: now_ms: Final = int(time.time() * 1000) return await get_receiver().list_traces( @@ -111,7 +111,7 @@ async def list_agent_traces( @router.get("/v1/traces/{trace_id}", response_model=None) async def get_agent_trace( trace_id: str, - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), + user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], ) -> Trace: trace: Final = await get_receiver().get_trace(trace_id, scope_for(user_api_key_dict)) if trace is None: @@ -123,7 +123,7 @@ async def get_agent_trace( async def get_agent_trace_span( trace_id: str, span_id: str, - user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), + user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], ) -> SpanDetail: span: Final = await get_receiver().get_span(trace_id, span_id, scope_for(user_api_key_dict)) if span is None: diff --git a/litellm/tracing/decode.py b/litellm/tracing/decode.py index 19336c23f16..ba13285e8bc 100644 --- a/litellm/tracing/decode.py +++ b/litellm/tracing/decode.py @@ -107,7 +107,7 @@ def _span_row(span: DecodedSpan) -> SpanRow: # ---------------------------------------------------------------- normalize -def _loads(value: str) -> Any: +def _loads(value: str) -> object: try: return json.loads(value) except (ValueError, TypeError): @@ -132,7 +132,7 @@ def _langsmith_type(row: SpanRow, attributes: Mapping[str, str]) -> SpanType: name = row["SpanName"] if not row["ParentSpanId"] or name == attributes.get("langsmith.metadata.lc_agent_name"): return "agent" - if kind == "llm" or kind == "tool": + if kind in {"llm", "tool"}: return kind if name.endswith(_FRAMEWORK_SUFFIXES): return "framework" @@ -142,8 +142,9 @@ def _langsmith_type(row: SpanRow, attributes: Mapping[str, str]) -> SpanType: def _langsmith_io(row: SpanRow, attributes: Mapping[str, str]) -> None: prompt = _loads(attributes.get("gen_ai.prompt", "")) completion = _loads(attributes.get("gen_ai.completion", "")) + prompt_payload = prompt if isinstance(prompt, dict) else {} if row["ObservationType"] == "llm" and isinstance(completion, dict): - messages = (prompt or {}).get("messages") or [[]] + messages = prompt_payload.get("messages") or [[]] batch = messages[0] if messages and isinstance(messages[0], list) else messages row["Input"] = json.dumps([_lc_message(m) for m in batch]) generation = completion["generations"][0][0]["message"]["kwargs"] diff --git a/litellm/tracing/receiver.py b/litellm/tracing/receiver.py index 196860078da..1efe52e7c73 100644 --- a/litellm/tracing/receiver.py +++ b/litellm/tracing/receiver.py @@ -42,7 +42,7 @@ class TracingPayloadTooLargeError(Exception): class Tenant: """Who sent the spans. Always taken from auth, never from span attributes.""" - def __init__(self, team_id: str, api_key_hash: str, org_id: str = ""): + def __init__(self, team_id: str, api_key_hash: str, org_id: str = "") -> None: self.team_id = team_id self.api_key_hash = api_key_hash self.org_id = org_id @@ -60,7 +60,7 @@ class Tenant: class TraceReceiver: - def __init__(self, store: ClickHouseTraceStore): + def __init__(self, store: ClickHouseTraceStore) -> None: self.store = store @classmethod diff --git a/litellm/tracing/store.py b/litellm/tracing/store.py index dff40816847..404aa3acd3b 100644 --- a/litellm/tracing/store.py +++ b/litellm/tracing/store.py @@ -222,7 +222,7 @@ def trace_from_rows(trace_id: str, rows: list[dict[str, Any]]) -> Trace | None: class ClickHouseTraceStore: """Stores spans and runs scoped trace reads.""" - def __init__(self, storage: TraceStorage): + def __init__(self, storage: TraceStorage) -> None: self.storage = storage async def insert_spans(self, rows: list[SpanRow]) -> None: diff --git a/ui/litellm-dashboard/package-lock.json b/ui/litellm-dashboard/package-lock.json index 03e29c02021..1cb1951d96a 100644 --- a/ui/litellm-dashboard/package-lock.json +++ b/ui/litellm-dashboard/package-lock.json @@ -25,7 +25,7 @@ "jwt-decode": "4.0.0", "lucide-react": "0.513.0", "moment": "2.31.0", - "next": "16.3.3", + "next": "16.3.6", "next-themes": "^0.4.6", "nuqs": "^2.9.4", "openai": "4.104.0", @@ -2061,9 +2061,9 @@ } }, "node_modules/@next/env": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.3.tgz", - "integrity": "sha512-U2eYQRwXj+dsqxV79zFqExDdatnNY/ZWc2nsJU1p/OgT7fd3dXwlF6OjYaFQCfMoeTA19PWq+wVmYgimVA+V+g==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.6.tgz", + "integrity": "sha512-x9Vblze1EbtltQYnNH38xCPWU3TVfBd1eXqA3+w9+BTpedkkdNpAaltXlGQ/nsc1+E0mVTNrtcbX3GoO09zeLQ==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -2078,9 +2078,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.3.tgz", - "integrity": "sha512-8Hiv32QJPwdV6KYJ8meR9SBA061tQqnIKTJDocvOXlEQqib0xMFpzArosuffFUUc0sslbh7QQ8a3Yey1QV8EIw==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.6.tgz", + "integrity": "sha512-E/7GEqaUkt8mk/T8v9lAnrhzR06kdq1ZBkC12F8tAMkdIadwNp3H1KqHynDHrpcTlGCUdq/qu6vUL2aYVyYBdw==", "cpu": [ "arm64" ], @@ -2094,9 +2094,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.3.tgz", - "integrity": "sha512-A1lgKgwVchRYmSe467zdwhxT9040dd8lH+o65sL5Jet8fjB4kegw/rDyPIpYVRb6jAqwXFOJpjIXJLxQKLiE3A==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.6.tgz", + "integrity": "sha512-yBE893/nDWTlaiBD1p+qgt7NUen4U5R6FXyH0s67Npq1S3E0cVSef1WIXC2xBRgQvwAvJq6DnS6Y6PrY0cy4Ew==", "cpu": [ "x64" ], @@ -2110,9 +2110,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.3.tgz", - "integrity": "sha512-bf0FIssMFueU2dm7vQEWWxk0c8UjKTdW0yzuh0sQsD8pf1+KCLDdaqhYZNMYGmXwEOiHAUzgBKudovIlcvvBjg==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.6.tgz", + "integrity": "sha512-KJDpjBqBPYlvkivmyrp+Qys6k/7ksbqGQvRVc6ZEGfR+cjQxx+nUkJaWmNZJsmoOrqYNbaXByF8wa0lBwDhB3Q==", "cpu": [ "arm64" ], @@ -2129,9 +2129,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.3.tgz", - "integrity": "sha512-W7viwCk9JY/cAkdz/A273rd5bb3RgT/IHwR7Upv90tunjBWNtAAhGhoecHh+teRNRSinuAFmE+l7fwZ4YKkrXg==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.6.tgz", + "integrity": "sha512-mqNg2K+hvWskSRb/QM+Ix412DvBsuSF0XV+frTSw5vmoucNnIlynFwKYew8D01bfATErMOM7Bujrf0BA5DRKFA==", "cpu": [ "arm64" ], @@ -2148,9 +2148,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.3.tgz", - "integrity": "sha512-0W46zw1N3ODpI6n0GeivHvvob1pooozgZVqy65k0mh4/7vr+FbY9+WpHzNVXjHipJf/A3FDheBG19H1s5A25rA==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.6.tgz", + "integrity": "sha512-nFncBNGAYouRHjRVaITs9beZRfhX4ssVwpnvPIAbkZVH6LtGoAVlH4bJ8Cnf9SOo9bsXgPFer/GdHtEE3JNOkw==", "cpu": [ "x64" ], @@ -2167,9 +2167,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.3.tgz", - "integrity": "sha512-H4mBso8ZTMBPtdT0PN0pBx2ayTvQuTuvS6qT13d77yVFJXAPCxkyIhLTmdMaGTJs0krQYI/qpzdHijCeihXhbg==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.6.tgz", + "integrity": "sha512-5Mf3cHDGR/Iz0ng2Bj3zUR3p5QS9YK3Hn2QiAfavFmyF48zwThAjpFoiTKNIcOHLYS4zEk+gzyJ/9deQ2ZB8yQ==", "cpu": [ "x64" ], @@ -2186,9 +2186,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.3.tgz", - "integrity": "sha512-cTMUJpcEGmeywofCUfhR+rSsoE33+rVPnPEYNTNdLNlsOeEg/vktOsKUSTb28vUGqD2jkm4Zaskcwn7OCI6FQg==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.6.tgz", + "integrity": "sha512-0jkJy0C2kbrJWTk4YLa3xk80pVBpx8FCHJym7CnUfDAXe/FWv5qT7SQJbR0KuemyxaEDlEx5WT4VQJoTW+/9Qw==", "cpu": [ "arm64" ], @@ -2202,9 +2202,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.3.tgz", - "integrity": "sha512-2VR4cTBzHXaBjnGsuH6GyJjENzQOmHeAh11uY1iUhjm3j5dEUrVJuUj+VL78jaGi/Dik8xS76zEj18BsFhlVZQ==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.6.tgz", + "integrity": "sha512-/YXjI1e5OXcZ7YpxRwgP/1jAV/SBKTzeVKqN2mk7mLpcICsyn3Gl5+dIfDTJp70M0ccMhyMMRso4v6mPDCGepg==", "cpu": [ "x64" ], @@ -9712,12 +9712,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/next/-/next-16.3.3.tgz", - "integrity": "sha512-tuRTx1nQ/yVw83cwJBo9F+njGUgMn3UHQycreWHB8XsStvvAh1AthbI8/4IpKnFaF58F+iSiHejYOlMQ/eq83g==", + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/next/-/next-16.3.6.tgz", + "integrity": "sha512-L+otWM/aQbYTx98aZhgEoMb4bZAXx1YVW4UMA/vuCyCoWG5HJyZUili8QAkqzrcC+5///tsz3s0M+SlyB5bLMw==", "license": "MIT", "dependencies": { - "@next/env": "16.3.3", + "@next/env": "16.3.6", "@swc/helpers": "0.5.23", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", @@ -9731,15 +9731,15 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.3.3", - "@next/swc-darwin-x64": "16.3.3", - "@next/swc-linux-arm64-gnu": "16.3.3", - "@next/swc-linux-arm64-musl": "16.3.3", - "@next/swc-linux-x64-gnu": "16.3.3", - "@next/swc-linux-x64-musl": "16.3.3", - "@next/swc-win32-arm64-msvc": "16.3.3", - "@next/swc-win32-x64-msvc": "16.3.3", - "sharp": "^0.35.3" + "@next/swc-darwin-arm64": "16.3.6", + "@next/swc-darwin-x64": "16.3.6", + "@next/swc-linux-arm64-gnu": "16.3.6", + "@next/swc-linux-arm64-musl": "16.3.6", + "@next/swc-linux-x64-gnu": "16.3.6", + "@next/swc-linux-x64-musl": "16.3.6", + "@next/swc-win32-arm64-msvc": "16.3.6", + "@next/swc-win32-x64-msvc": "16.3.6", + "sharp": "^0.35.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", diff --git a/ui/litellm-dashboard/package.json b/ui/litellm-dashboard/package.json index 3bf32d37faf..0830e233bbe 100644 --- a/ui/litellm-dashboard/package.json +++ b/ui/litellm-dashboard/package.json @@ -41,7 +41,7 @@ "jwt-decode": "4.0.0", "lucide-react": "0.513.0", "moment": "2.31.0", - "next": "16.3.3", + "next": "16.3.6", "next-themes": "^0.4.6", "nuqs": "^2.9.4", "openai": "4.104.0", diff --git a/uv.lock b/uv.lock index 4b9dbaba39b..2d31641a5e3 100644 --- a/uv.lock +++ b/uv.lock @@ -7857,14 +7857,14 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.14.0" +version = "2.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/af/c3/8a3b59c25070cc61dc517fbdfa5dc0904670c96f605cc69759dc09166b99/pyjwt-2.14.0.tar.gz", hash = "sha256:77283c83fb56ecf566a886c757a714bc83668e38156de2cce8263302f42e0b86", size = 113177, upload-time = "2026-09-11T13:11:54.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/02/a5/5197bfd06417837ac079921c66fa6393f1dea3557272a263cebfef69e432/pyjwt-2.15.0.tar.gz", hash = "sha256:b11c5f9791d7bf51c2b39a81ed669f6b2dbbd669df2942f6c60167e9e3d1abe4", size = 120513, upload-time = "2026-09-23T16:56:00.689Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/97/672cb32ce0dfea44b740cb7b4f97038463b9cf7c0ead1aacf595572851d6/pyjwt-2.14.0-py3-none-any.whl", hash = "sha256:ad0cef71c756a56e74863c2919cf0985f72decbcfcb550ee2f422e7c62b5eedc", size = 32896, upload-time = "2026-09-11T13:11:53.409Z" }, + { url = "https://files.pythonhosted.org/packages/e8/55/40e45bf052ee8ee12a4dfd785519660f8effa7b065442b91646ec6828619/pyjwt-2.15.0-py3-none-any.whl", hash = "sha256:7a3742debf6b879e912dbb9819ceec1594be812452b78c5f2e2dfc56564954f8", size = 33680, upload-time = "2026-09-23T16:55:59.241Z" }, ] [package.optional-dependencies] @@ -10196,11 +10196,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.7.0" +version = "2.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, + { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" }, ] [[package]]