Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions pinecone/_internal/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,22 @@ def _log_curl(
headers: dict[str, str],
body: bytes | None = None,
) -> None:
"""Log a curl-equivalent command for debugging when PINECONE_DEBUG_CURL is set."""
"""Log a curl-equivalent command for debugging when PINECONE_DEBUG_CURL is set.

Sensitive header values (see ``_SENSITIVE_HEADERS``) are redacted. The
request body is intentionally *not* logged verbatim: Pinecone request bodies
carry user vector and metadata payloads that may contain sensitive data
(e.g. PII embedded in metadata). Only the body size is emitted, and a
``--data-binary @body.json`` placeholder shows where to supply it manually.
"""
if not os.environ.get("PINECONE_DEBUG_CURL"):
return
safe_headers = _redact_headers(headers)
parts = [f"curl -X {method} '{url}'"]
for key, value in safe_headers.items():
parts.append(f"-H '{key}: {value}'")
if body is not None:
parts.append(f"-d '{body.decode('utf-8', errors='replace')}'")
parts.append(f"--data-binary @body.json # {len(body)} byte body omitted")
curl_cmd = " ".join(parts)
logger.debug("curl equivalent:\n%s", curl_cmd)

Expand Down
12 changes: 8 additions & 4 deletions tests/unit/test_debug_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ def test_curl_logging_redacts_api_key(
assert "my-secret-key-12345" not in caplog.text
assert "Api-Key: ***" in caplog.text

def test_curl_logging_includes_body(
def test_curl_logging_omits_body_contents(
self, monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture
) -> None:
# The raw request body must never be logged: it can carry user vector
# and metadata payloads (potentially PII). Only the byte count is shown.
monkeypatch.setenv("PINECONE_DEBUG_CURL", "1")
body = b'{"vectors": [{"id": "v1"}]}'
with caplog.at_level(logging.DEBUG, logger="pinecone._internal.http_client"):
Expand All @@ -94,8 +96,8 @@ def test_curl_logging_includes_body(
{"Api-Key": "test-key", "Content-Type": "application/json"},
body=body,
)
assert "-d " in caplog.text
assert '{"vectors": [{"id": "v1"}]}' in caplog.text
assert '{"vectors": [{"id": "v1"}]}' not in caplog.text
assert f"{len(body)} byte body omitted" in caplog.text

def test_curl_logging_includes_all_headers(
self, monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture
Expand Down Expand Up @@ -144,7 +146,9 @@ def test_post_logs_curl_with_body(
finally:
client.close()
assert "curl -X POST" in caplog.text
assert "-d " in caplog.text
assert "byte body omitted" in caplog.text
# Raw request payload must not appear in logs.
assert '"id": "v1"' not in caplog.text

@respx.mock
def test_no_curl_output_when_disabled(
Expand Down
Loading