Refactor logging implementation and remove logfire dependency
Browse files- Replaced logfire logging with standard Python logging across multiple scripts for improved consistency and maintainability.
- Updated AGENTS.md to clarify agent tracing and server logging practices.
- Removed logfire from dependencies in pyproject.toml and uv.lock, streamlining the project setup.
- Enhanced logging messages for better clarity and context in various components, including api.py, chat_service.py, and setup.py.
- AGENTS.md +1 -1
- pyproject.toml +0 -1
- scripts/api.py +6 -4
- scripts/chat_service.py +8 -6
- scripts/chroma_rag.py +4 -2
- scripts/setup.py +20 -14
- uv.lock +0 -53
AGENTS.md
CHANGED
|
@@ -29,7 +29,7 @@ ChromaDB for vectors; Cohere for embeddings/rerank; chat model is provider-confi
|
|
| 29 |
| Gradio app + renderer | `scripts/main.py`, `scripts/gradio_presenter.py` |
|
| 30 |
| Paths, models, startup downloads | `scripts/setup.py` |
|
| 31 |
| **Sources — single source of truth** | `data/scraping_scripts/source_registry.py` |
|
| 32 |
-
|
|
| 33 |
| Data pipeline / workflows (deep guide) | `data/scraping_scripts/README.md` |
|
| 34 |
| KB design + wiki maintainer workflow (deep guide) | `data/kb/MAINTAINER.md` |
|
| 35 |
|
|
|
|
| 29 |
| Gradio app + renderer | `scripts/main.py`, `scripts/gradio_presenter.py` |
|
| 30 |
| Paths, models, startup downloads | `scripts/setup.py` |
|
| 31 |
| **Sources — single source of truth** | `data/scraping_scripts/source_registry.py` |
|
| 32 |
+
| Agent tracing (LangSmith) + server logging (stdlib `logging` → stdout) | `scripts/agent_tracing.py`, `scripts/setup.py` |
|
| 33 |
| Data pipeline / workflows (deep guide) | `data/scraping_scripts/README.md` |
|
| 34 |
| KB design + wiki maintainer workflow (deep guide) | `data/kb/MAINTAINER.md` |
|
| 35 |
|
pyproject.toml
CHANGED
|
@@ -20,7 +20,6 @@ dependencies = [
|
|
| 20 |
"langchain-google-genai",
|
| 21 |
"langchain-openai",
|
| 22 |
"llama-index",
|
| 23 |
-
"logfire",
|
| 24 |
"nbconvert",
|
| 25 |
"nbformat",
|
| 26 |
"openai",
|
|
|
|
| 20 |
"langchain-google-genai",
|
| 21 |
"langchain-openai",
|
| 22 |
"llama-index",
|
|
|
|
| 23 |
"nbconvert",
|
| 24 |
"nbformat",
|
| 25 |
"openai",
|
scripts/api.py
CHANGED
|
@@ -1,13 +1,13 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import json
|
|
|
|
| 4 |
import os
|
| 5 |
from contextlib import asynccontextmanager
|
| 6 |
from pathlib import Path
|
| 7 |
from typing import Any, AsyncIterator
|
| 8 |
from uuid import uuid4
|
| 9 |
|
| 10 |
-
import logfire
|
| 11 |
import uvicorn
|
| 12 |
from fastapi import FastAPI, HTTPException
|
| 13 |
from fastapi.middleware.cors import CORSMiddleware
|
|
@@ -34,6 +34,8 @@ from .setup import (
|
|
| 34 |
SOURCE_UI_TO_KEY,
|
| 35 |
)
|
| 36 |
|
|
|
|
|
|
|
| 37 |
|
| 38 |
class ApiChatTurn(BaseModel):
|
| 39 |
role: str
|
|
@@ -486,9 +488,9 @@ if FRONTEND_OUT_DIR.is_dir():
|
|
| 486 |
name="frontend",
|
| 487 |
)
|
| 488 |
else:
|
| 489 |
-
|
| 490 |
-
"Frontend static export not found; skipping static mount.",
|
| 491 |
-
|
| 492 |
)
|
| 493 |
|
| 494 |
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import json
|
| 4 |
+
import logging
|
| 5 |
import os
|
| 6 |
from contextlib import asynccontextmanager
|
| 7 |
from pathlib import Path
|
| 8 |
from typing import Any, AsyncIterator
|
| 9 |
from uuid import uuid4
|
| 10 |
|
|
|
|
| 11 |
import uvicorn
|
| 12 |
from fastapi import FastAPI, HTTPException
|
| 13 |
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
| 34 |
SOURCE_UI_TO_KEY,
|
| 35 |
)
|
| 36 |
|
| 37 |
+
logger = logging.getLogger(__name__)
|
| 38 |
+
|
| 39 |
|
| 40 |
class ApiChatTurn(BaseModel):
|
| 41 |
role: str
|
|
|
|
| 488 |
name="frontend",
|
| 489 |
)
|
| 490 |
else:
|
| 491 |
+
logger.info(
|
| 492 |
+
"Frontend static export not found; skipping static mount. path=%s",
|
| 493 |
+
FRONTEND_OUT_DIR,
|
| 494 |
)
|
| 495 |
|
| 496 |
|
scripts/chat_service.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import json
|
|
|
|
| 4 |
import os
|
| 5 |
import shlex
|
| 6 |
from dataclasses import dataclass
|
|
@@ -9,7 +10,6 @@ from threading import Lock
|
|
| 9 |
from typing import Any, AsyncIterator
|
| 10 |
from uuid import uuid4
|
| 11 |
|
| 12 |
-
import logfire
|
| 13 |
from langchain.agents import create_agent
|
| 14 |
from langchain.agents.middleware import (
|
| 15 |
AgentMiddleware,
|
|
@@ -55,6 +55,8 @@ from .setup import (
|
|
| 55 |
ensure_local_vector_db,
|
| 56 |
)
|
| 57 |
|
|
|
|
|
|
|
| 58 |
SOURCES_HEADER = "📝 Here are the sources I used to answer your question:"
|
| 59 |
ACTIVITY_BLOCK_START = "<!-- MODEL_ACTIVITY_START -->"
|
| 60 |
ACTIVITY_BLOCK_END = "<!-- MODEL_ACTIVITY_END -->"
|
|
@@ -121,9 +123,9 @@ def warm_up_retriever() -> None:
|
|
| 121 |
try:
|
| 122 |
get_retriever()
|
| 123 |
except Exception as exc: # pragma: no cover - diagnostic logging only
|
| 124 |
-
|
| 125 |
-
"Retriever warm-up failed; first retrieval call may retry.",
|
| 126 |
-
|
| 127 |
)
|
| 128 |
|
| 129 |
|
|
@@ -201,7 +203,7 @@ def run_kb_command(
|
|
| 201 |
try:
|
| 202 |
ensure_local_vector_db()
|
| 203 |
except Exception as exc: # pragma: no cover - diagnostic only
|
| 204 |
-
|
| 205 |
try:
|
| 206 |
result = execute_kb_command(
|
| 207 |
command,
|
|
@@ -1046,7 +1048,7 @@ async def stream_chat(request: ChatRequest) -> AsyncIterator[ChatEvent]:
|
|
| 1046 |
google_search_queries: list[str] = []
|
| 1047 |
google_search_match_count = 0
|
| 1048 |
|
| 1049 |
-
|
| 1050 |
agent = build_agent(
|
| 1051 |
request.model_name,
|
| 1052 |
enabled_tools=tuple(request.enabled_tools),
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import json
|
| 4 |
+
import logging
|
| 5 |
import os
|
| 6 |
import shlex
|
| 7 |
from dataclasses import dataclass
|
|
|
|
| 10 |
from typing import Any, AsyncIterator
|
| 11 |
from uuid import uuid4
|
| 12 |
|
|
|
|
| 13 |
from langchain.agents import create_agent
|
| 14 |
from langchain.agents.middleware import (
|
| 15 |
AgentMiddleware,
|
|
|
|
| 55 |
ensure_local_vector_db,
|
| 56 |
)
|
| 57 |
|
| 58 |
+
logger = logging.getLogger(__name__)
|
| 59 |
+
|
| 60 |
SOURCES_HEADER = "📝 Here are the sources I used to answer your question:"
|
| 61 |
ACTIVITY_BLOCK_START = "<!-- MODEL_ACTIVITY_START -->"
|
| 62 |
ACTIVITY_BLOCK_END = "<!-- MODEL_ACTIVITY_END -->"
|
|
|
|
| 123 |
try:
|
| 124 |
get_retriever()
|
| 125 |
except Exception as exc: # pragma: no cover - diagnostic logging only
|
| 126 |
+
logger.warning(
|
| 127 |
+
"Retriever warm-up failed; first retrieval call may retry. error=%s",
|
| 128 |
+
exc,
|
| 129 |
)
|
| 130 |
|
| 131 |
|
|
|
|
| 203 |
try:
|
| 204 |
ensure_local_vector_db()
|
| 205 |
except Exception as exc: # pragma: no cover - diagnostic only
|
| 206 |
+
logger.warning("KB artifact download/check failed. error=%s", exc)
|
| 207 |
try:
|
| 208 |
result = execute_kb_command(
|
| 209 |
command,
|
|
|
|
| 1048 |
google_search_queries: list[str] = []
|
| 1049 |
google_search_match_count = 0
|
| 1050 |
|
| 1051 |
+
logger.info("Running query: %s", request.query)
|
| 1052 |
agent = build_agent(
|
| 1053 |
request.model_name,
|
| 1054 |
enabled_tools=tuple(request.enabled_tools),
|
scripts/chroma_rag.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import json
|
|
|
|
| 4 |
import math
|
| 5 |
import os
|
| 6 |
import pickle
|
|
@@ -16,10 +17,11 @@ from urllib.parse import unquote, urlparse
|
|
| 16 |
|
| 17 |
import chromadb
|
| 18 |
import cohere
|
| 19 |
-
import logfire
|
| 20 |
import tiktoken
|
| 21 |
from tqdm.auto import tqdm
|
| 22 |
|
|
|
|
|
|
|
| 23 |
|
| 24 |
DEFAULT_CHUNK_SIZE = 800
|
| 25 |
DEFAULT_CHUNK_OVERLAP = 100
|
|
@@ -1381,5 +1383,5 @@ def parse_tool_payload(content: str) -> list[SearchResult]:
|
|
| 1381 |
try:
|
| 1382 |
parsed.append(SearchResult(**match))
|
| 1383 |
except TypeError:
|
| 1384 |
-
|
| 1385 |
return parsed
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import json
|
| 4 |
+
import logging
|
| 5 |
import math
|
| 6 |
import os
|
| 7 |
import pickle
|
|
|
|
| 17 |
|
| 18 |
import chromadb
|
| 19 |
import cohere
|
|
|
|
| 20 |
import tiktoken
|
| 21 |
from tqdm.auto import tqdm
|
| 22 |
|
| 23 |
+
logger = logging.getLogger(__name__)
|
| 24 |
+
|
| 25 |
|
| 26 |
DEFAULT_CHUNK_SIZE = 800
|
| 27 |
DEFAULT_CHUNK_OVERLAP = 100
|
|
|
|
| 1383 |
try:
|
| 1384 |
parsed.append(SearchResult(**match))
|
| 1385 |
except TypeError:
|
| 1386 |
+
logger.warning("Skipping malformed retrieval payload entry")
|
| 1387 |
return parsed
|
scripts/setup.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
|
|
| 1 |
import os
|
| 2 |
from pathlib import Path
|
| 3 |
|
| 4 |
-
import logfire
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
|
| 7 |
from data.scraping_scripts.source_registry import (
|
|
@@ -19,15 +19,21 @@ from .utils import init_mongo_db
|
|
| 19 |
|
| 20 |
load_dotenv(override=True)
|
| 21 |
configure_langsmith_environment()
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
if langsmith_tracing_enabled():
|
| 28 |
-
|
| 29 |
-
"LangSmith tracing enabled.",
|
| 30 |
-
|
| 31 |
)
|
| 32 |
|
| 33 |
VECTOR_DB_DIR = "data/chroma-db-all_sources"
|
|
@@ -69,7 +75,7 @@ def ensure_local_vector_db() -> None:
|
|
| 69 |
and os.path.exists(KB_INDEX_PATH)
|
| 70 |
)
|
| 71 |
if needs_download:
|
| 72 |
-
|
| 73 |
"Vector database does not exist locally, downloading from Hugging Face"
|
| 74 |
)
|
| 75 |
from huggingface_hub import snapshot_download
|
|
@@ -82,11 +88,11 @@ def ensure_local_vector_db() -> None:
|
|
| 82 |
ensure_kb_agents_md()
|
| 83 |
|
| 84 |
|
| 85 |
-
|
| 86 |
-
init_mongo_db(uri=MONGODB_URI, db_name="towardsai-buster")
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
|
| 91 |
__all__ = [
|
| 92 |
"AVAILABLE_MODELS",
|
|
|
|
| 1 |
+
import logging
|
| 2 |
import os
|
| 3 |
from pathlib import Path
|
| 4 |
|
|
|
|
| 5 |
from dotenv import load_dotenv
|
| 6 |
|
| 7 |
from data.scraping_scripts.source_registry import (
|
|
|
|
| 19 |
|
| 20 |
load_dotenv(override=True)
|
| 21 |
configure_langsmith_environment()
|
| 22 |
+
|
| 23 |
+
# Operational/server logging goes to stdout (captured by the Hugging Face Space
|
| 24 |
+
# logs). This is separate from LangSmith, which traces agent runs; see
|
| 25 |
+
# scripts/agent_tracing.py. basicConfig is a no-op if logging is already
|
| 26 |
+
# configured (e.g. by a data-pipeline entry point), so it won't clobber callers.
|
| 27 |
+
logging.basicConfig(
|
| 28 |
+
level=logging.INFO,
|
| 29 |
+
format="%(asctime)s %(levelname)s [%(name)s] %(message)s",
|
| 30 |
+
)
|
| 31 |
+
logger = logging.getLogger(__name__)
|
| 32 |
|
| 33 |
if langsmith_tracing_enabled():
|
| 34 |
+
logger.info(
|
| 35 |
+
"LangSmith tracing enabled. project=%s",
|
| 36 |
+
os.getenv("LANGSMITH_PROJECT", "default"),
|
| 37 |
)
|
| 38 |
|
| 39 |
VECTOR_DB_DIR = "data/chroma-db-all_sources"
|
|
|
|
| 75 |
and os.path.exists(KB_INDEX_PATH)
|
| 76 |
)
|
| 77 |
if needs_download:
|
| 78 |
+
logger.warning(
|
| 79 |
"Vector database does not exist locally, downloading from Hugging Face"
|
| 80 |
)
|
| 81 |
from huggingface_hub import snapshot_download
|
|
|
|
| 88 |
ensure_kb_agents_md()
|
| 89 |
|
| 90 |
|
| 91 |
+
if MONGODB_URI:
|
| 92 |
+
mongo_db = init_mongo_db(uri=MONGODB_URI, db_name="towardsai-buster")
|
| 93 |
+
else:
|
| 94 |
+
logger.warning("No mongodb uri found, you will not be able to save data.")
|
| 95 |
+
mongo_db = None
|
| 96 |
|
| 97 |
__all__ = [
|
| 98 |
"AVAILABLE_MODELS",
|
uv.lock
CHANGED
|
@@ -30,7 +30,6 @@ dependencies = [
|
|
| 30 |
{ name = "langchain-google-genai" },
|
| 31 |
{ name = "langchain-openai" },
|
| 32 |
{ name = "llama-index" },
|
| 33 |
-
{ name = "logfire" },
|
| 34 |
{ name = "nbconvert" },
|
| 35 |
{ name = "nbformat" },
|
| 36 |
{ name = "openai" },
|
|
@@ -66,7 +65,6 @@ requires-dist = [
|
|
| 66 |
{ name = "langchain-google-genai" },
|
| 67 |
{ name = "langchain-openai" },
|
| 68 |
{ name = "llama-index" },
|
| 69 |
-
{ name = "logfire" },
|
| 70 |
{ name = "nbconvert" },
|
| 71 |
{ name = "nbformat" },
|
| 72 |
{ name = "openai" },
|
|
@@ -1961,24 +1959,6 @@ wheels = [
|
|
| 1961 |
{ url = "https://files.pythonhosted.org/packages/71/5f/385231406d777cb4b608fd8ebe3577dbd90962770717181e6b91b44fb1b8/llama_index_workflows-2.20.0-py3-none-any.whl", hash = "sha256:36f6b6ace77f837d9907078aea7e830251afe96a58daecff5ed090c88c55095d", size = 121238, upload-time = "2026-04-24T14:54:40.455Z" },
|
| 1962 |
]
|
| 1963 |
|
| 1964 |
-
[[package]]
|
| 1965 |
-
name = "logfire"
|
| 1966 |
-
version = "4.35.0"
|
| 1967 |
-
source = { registry = "https://pypi.org/simple" }
|
| 1968 |
-
dependencies = [
|
| 1969 |
-
{ name = "executing" },
|
| 1970 |
-
{ name = "opentelemetry-exporter-otlp-proto-http" },
|
| 1971 |
-
{ name = "opentelemetry-instrumentation" },
|
| 1972 |
-
{ name = "opentelemetry-sdk" },
|
| 1973 |
-
{ name = "protobuf" },
|
| 1974 |
-
{ name = "rich" },
|
| 1975 |
-
{ name = "typing-extensions" },
|
| 1976 |
-
]
|
| 1977 |
-
sdist = { url = "https://files.pythonhosted.org/packages/7c/20/9508c92ad4ec2ed4ad63a20d72f08427c24117273541ec97c630332855c3/logfire-4.35.0.tar.gz", hash = "sha256:6542aa4ac5e2d2369587deab57a0d1bb9cf6da49634c8cd9c5dbd7c7581f3d51", size = 1148150, upload-time = "2026-06-02T14:55:56.792Z" }
|
| 1978 |
-
wheels = [
|
| 1979 |
-
{ url = "https://files.pythonhosted.org/packages/77/37/a3631d0b7e4fcb19df4705c7c7e17164c5446e144f034723cf6277749973/logfire-4.35.0-py3-none-any.whl", hash = "sha256:9ae5c3f2dd81144ccf1ec6dba1a5de84aff5b2e2b8dd2190e53e87e47bc63711", size = 347012, upload-time = "2026-06-02T14:55:53.244Z" },
|
| 1980 |
-
]
|
| 1981 |
-
|
| 1982 |
[[package]]
|
| 1983 |
name = "markdown-it-py"
|
| 1984 |
version = "4.2.0"
|
|
@@ -2476,39 +2456,6 @@ wheels = [
|
|
| 2476 |
{ url = "https://files.pythonhosted.org/packages/89/2b/28ba5b128f47fe8c3bab541000d6feb4b5a9bd26623ca013406f01c0fb60/opentelemetry_exporter_otlp_proto_grpc-1.42.1-py3-none-any.whl", hash = "sha256:0ae1177e2038b18a929b3098215243631ef91136cba26b7e2b12790ceb7e87cc", size = 19617, upload-time = "2026-05-21T16:32:34.278Z" },
|
| 2477 |
]
|
| 2478 |
|
| 2479 |
-
[[package]]
|
| 2480 |
-
name = "opentelemetry-exporter-otlp-proto-http"
|
| 2481 |
-
version = "1.42.1"
|
| 2482 |
-
source = { registry = "https://pypi.org/simple" }
|
| 2483 |
-
dependencies = [
|
| 2484 |
-
{ name = "googleapis-common-protos" },
|
| 2485 |
-
{ name = "opentelemetry-api" },
|
| 2486 |
-
{ name = "opentelemetry-exporter-otlp-proto-common" },
|
| 2487 |
-
{ name = "opentelemetry-proto" },
|
| 2488 |
-
{ name = "opentelemetry-sdk" },
|
| 2489 |
-
{ name = "requests" },
|
| 2490 |
-
{ name = "typing-extensions" },
|
| 2491 |
-
]
|
| 2492 |
-
sdist = { url = "https://files.pythonhosted.org/packages/77/32/826bfa1d80ecea24f47808de03cd4a0d13c17ecc07712f45123f0f61e4ac/opentelemetry_exporter_otlp_proto_http-1.42.1.tar.gz", hash = "sha256:bf142a21035d7571ac3a09cb2e5639f49886f243972883cfe777ed3bf02b734d", size = 25406, upload-time = "2026-05-21T16:32:56.807Z" }
|
| 2493 |
-
wheels = [
|
| 2494 |
-
{ url = "https://files.pythonhosted.org/packages/d3/96/82cb223a1502f0787d4bbff12907f5f8d870a50731febcd5818d93ef9555/opentelemetry_exporter_otlp_proto_http-1.42.1-py3-none-any.whl", hash = "sha256:00a16da1b312a1d6c7233d600d557c91df71125af73020f3b9a7765bd699d59d", size = 21793, upload-time = "2026-05-21T16:32:35.277Z" },
|
| 2495 |
-
]
|
| 2496 |
-
|
| 2497 |
-
[[package]]
|
| 2498 |
-
name = "opentelemetry-instrumentation"
|
| 2499 |
-
version = "0.63b1"
|
| 2500 |
-
source = { registry = "https://pypi.org/simple" }
|
| 2501 |
-
dependencies = [
|
| 2502 |
-
{ name = "opentelemetry-api" },
|
| 2503 |
-
{ name = "opentelemetry-semantic-conventions" },
|
| 2504 |
-
{ name = "packaging" },
|
| 2505 |
-
{ name = "wrapt" },
|
| 2506 |
-
]
|
| 2507 |
-
sdist = { url = "https://files.pythonhosted.org/packages/da/6d/4de72d97ff54db1ed270c7a59c9b904b917c0ac7af429c086c388b824ddb/opentelemetry_instrumentation-0.63b1.tar.gz", hash = "sha256:32368d6ae52c8de20aa790a6ad86b10a76f09956092337ae37d675773990e541", size = 41081, upload-time = "2026-05-21T16:36:14.206Z" }
|
| 2508 |
-
wheels = [
|
| 2509 |
-
{ url = "https://files.pythonhosted.org/packages/35/a1/9314e621c143e4d82a5bf7a43c2ff7a745d31023506336857607c8c543cc/opentelemetry_instrumentation-0.63b1-py3-none-any.whl", hash = "sha256:f1986716d52cc316ea5f60189098726a9071d8ecc0eee96c9ed110be08bade9c", size = 35577, upload-time = "2026-05-21T16:34:56.818Z" },
|
| 2510 |
-
]
|
| 2511 |
-
|
| 2512 |
[[package]]
|
| 2513 |
name = "opentelemetry-proto"
|
| 2514 |
version = "1.42.1"
|
|
|
|
| 30 |
{ name = "langchain-google-genai" },
|
| 31 |
{ name = "langchain-openai" },
|
| 32 |
{ name = "llama-index" },
|
|
|
|
| 33 |
{ name = "nbconvert" },
|
| 34 |
{ name = "nbformat" },
|
| 35 |
{ name = "openai" },
|
|
|
|
| 65 |
{ name = "langchain-google-genai" },
|
| 66 |
{ name = "langchain-openai" },
|
| 67 |
{ name = "llama-index" },
|
|
|
|
| 68 |
{ name = "nbconvert" },
|
| 69 |
{ name = "nbformat" },
|
| 70 |
{ name = "openai" },
|
|
|
|
| 1959 |
{ url = "https://files.pythonhosted.org/packages/71/5f/385231406d777cb4b608fd8ebe3577dbd90962770717181e6b91b44fb1b8/llama_index_workflows-2.20.0-py3-none-any.whl", hash = "sha256:36f6b6ace77f837d9907078aea7e830251afe96a58daecff5ed090c88c55095d", size = 121238, upload-time = "2026-04-24T14:54:40.455Z" },
|
| 1960 |
]
|
| 1961 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1962 |
[[package]]
|
| 1963 |
name = "markdown-it-py"
|
| 1964 |
version = "4.2.0"
|
|
|
|
| 2456 |
{ url = "https://files.pythonhosted.org/packages/89/2b/28ba5b128f47fe8c3bab541000d6feb4b5a9bd26623ca013406f01c0fb60/opentelemetry_exporter_otlp_proto_grpc-1.42.1-py3-none-any.whl", hash = "sha256:0ae1177e2038b18a929b3098215243631ef91136cba26b7e2b12790ceb7e87cc", size = 19617, upload-time = "2026-05-21T16:32:34.278Z" },
|
| 2457 |
]
|
| 2458 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2459 |
[[package]]
|
| 2460 |
name = "opentelemetry-proto"
|
| 2461 |
version = "1.42.1"
|