Skip to content
Merged
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
6 changes: 3 additions & 3 deletions sdks/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[build-system]
requires = ["hatchling"]
requires = ["hatchling<1.27.0"]
build-backend = "hatchling.build"

[project]
name = "logwell"
version = "1.0.3"
description = "Official Python SDK for Logwell logging platform"
readme = "README.md"
license = "MIT"
license = {text = "MIT"}
authors = [{ name = "Divkix", email = "divkix@divkix.me" }]
keywords = ["logging", "logs", "observability", "logwell", "python"]
classifiers = [
Expand Down Expand Up @@ -47,7 +47,7 @@ Issues = "https://github.com/Divkix/Logwell/issues"
packages = ["src/logwell"]

[tool.mypy]
python_version = "3.9"
python_version = "3.10"
strict = true
warn_return_any = true
warn_unused_configs = true
Expand Down
4 changes: 2 additions & 2 deletions sdks/python/src/logwell/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ def _add_log(self, entry: LogEntry, skip_frames: int) -> None:

# Add source location if captured
if source_file is not None:
full_entry["source_file"] = source_file
full_entry["sourceFile"] = source_file
if line_number is not None:
full_entry["line_number"] = line_number
full_entry["lineNumber"] = line_number

self._queue.add(full_entry)

Expand Down
8 changes: 4 additions & 4 deletions sdks/python/src/logwell/queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def add(self, entry: LogEntry) -> None:
self._queue.append(entry)

# Start timer on first entry
timer_future = getattr(self, '_timer_future', None)
timer_future = getattr(self, "_timer_future", None)
if (timer_future is None or timer_future.done()) and not self._stopped:
self._start_timer()

Expand Down Expand Up @@ -276,15 +276,15 @@ def _stop_timer(self) -> None:

Note: Must be called while holding the lock.
"""
future = getattr(self, '_timer_future', None)
future = getattr(self, "_timer_future", None)
if future is not None:
if not future.done():
future.cancel()
self._timer_future = None

async def _timer_coro(self) -> None:
"""Handle timer expiration by triggering a flush."""
my_future = getattr(self, '_timer_future', None)
my_future = getattr(self, "_timer_future", None)
try:
await asyncio.sleep(self._config.flush_interval)
with self._lock:
Expand All @@ -294,5 +294,5 @@ async def _timer_coro(self) -> None:
except asyncio.CancelledError:
pass
finally:
if getattr(self, '_timer_future', None) is my_future:
if getattr(self, "_timer_future", None) is my_future:
self._timer_future = None
8 changes: 4 additions & 4 deletions sdks/python/src/logwell/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ class LogEntry(TypedDict, total=False):
timestamp: ISO8601 timestamp (auto-generated if not provided)
service: Service name for this log
metadata: Arbitrary key-value metadata
source_file: Source file path where log was called
line_number: Line number where log was called
sourceFile: Source file path where log was called
lineNumber: Line number where log was called
"""

level: Required[LogLevel]
message: Required[str]
timestamp: str
service: str
metadata: dict[str, Any]
source_file: str
line_number: int
sourceFile: str
lineNumber: int


class LogwellConfig(TypedDict, total=False):
Expand Down
4 changes: 2 additions & 2 deletions sdks/python/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,8 @@ def sample_log_entry_full() -> LogEntry:
"timestamp": datetime.now(timezone.utc).isoformat(),
"service": "test-service",
"metadata": {"user_id": "123", "request_id": "abc-def"},
"source_file": "/app/main.py",
"line_number": 42,
"sourceFile": "/app/main.py",
"lineNumber": 42,
}


Expand Down
10 changes: 5 additions & 5 deletions sdks/python/tests/integration/test_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,9 +644,9 @@ async def test_source_location_captured_when_enabled(

# Verify source location is present
body = json.loads(mock_server.calls.last.request.content)
assert "source_file" in body[0]
assert "line_number" in body[0]
assert body[0]["source_file"].endswith("test_e2e.py")
assert "sourceFile" in body[0]
assert "lineNumber" in body[0]
assert body[0]["sourceFile"].endswith("test_e2e.py")

@pytest.mark.asyncio
async def test_source_location_not_captured_when_disabled(
Expand All @@ -668,8 +668,8 @@ async def test_source_location_not_captured_when_disabled(

# Verify source location is not present
body = json.loads(mock_server.calls.last.request.content)
assert "source_file" not in body[0]
assert "line_number" not in body[0]
assert "sourceFile" not in body[0]
assert "lineNumber" not in body[0]


# =============================================================================
Expand Down
22 changes: 11 additions & 11 deletions sdks/python/tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,8 @@ def test_source_location_disabled_by_default(self, valid_config: LogwellConfig)

client.info("Test")

assert "source_file" not in captured[0]
assert "line_number" not in captured[0]
assert "sourceFile" not in captured[0]
assert "lineNumber" not in captured[0]

def test_source_location_captured_when_enabled(
self, valid_api_key: str, valid_endpoint: str
Expand All @@ -821,10 +821,10 @@ def test_source_location_captured_when_enabled(

client.info("Test")

assert "source_file" in captured[0]
assert "line_number" in captured[0]
assert isinstance(captured[0]["line_number"], int)
assert captured[0]["line_number"] > 0
assert "sourceFile" in captured[0]
assert "lineNumber" in captured[0]
assert isinstance(captured[0]["lineNumber"], int)
assert captured[0]["lineNumber"] > 0

def test_source_location_points_to_caller(
self, valid_api_key: str, valid_endpoint: str
Expand All @@ -841,7 +841,7 @@ def test_source_location_points_to_caller(
client.info("Test") # Line number should point to this line

# Source file should be this test file
assert "test_client.py" in captured[0]["source_file"]
assert "test_client.py" in captured[0]["sourceFile"]

def test_source_location_for_all_log_methods(
self, valid_api_key: str, valid_endpoint: str
Expand All @@ -862,8 +862,8 @@ def test_source_location_for_all_log_methods(
client.fatal("fatal")

for entry in captured:
assert "source_file" in entry
assert "line_number" in entry
assert "sourceFile" in entry
assert "lineNumber" in entry

def test_child_inherits_source_location_setting(
self, valid_api_key: str, valid_endpoint: str
Expand All @@ -880,8 +880,8 @@ def test_child_inherits_source_location_setting(

child.info("Child log")

assert "source_file" in captured[0]
assert "line_number" in captured[0]
assert "sourceFile" in captured[0]
assert "lineNumber" in captured[0]


# =============================================================================
Expand Down
Loading