Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ For comprehensive guides and API reference, visit our [full documentation](https

## Requirements

- Python 3.12+
- Python 3.9+

Tusk Drift currently supports the following packages and versions:

Expand Down
5 changes: 4 additions & 1 deletion drift/core/resilience.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from enum import Enum
from typing import TypeVar

T = TypeVar("T")

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -51,7 +54,7 @@ def calculate_backoff_delay(
return delay


async def retry_async[T](
async def retry_async(
operation: Callable[[], Awaitable[T]],
config: RetryConfig | None = None,
retryable_exceptions: tuple[type[Exception], ...] = (Exception,),
Expand Down
4 changes: 2 additions & 2 deletions drift/core/span_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from datetime import UTC, datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Any

from betterproto.lib.google.protobuf import Struct as ProtoStruct
Expand Down Expand Up @@ -114,7 +114,7 @@ def clean_span_to_proto(span: CleanSpanData) -> ProtoSpan:
is_root_span=span.is_root_span,
timestamp=datetime.fromtimestamp(
span.timestamp.seconds + span.timestamp.nanos / 1_000_000_000,
tz=UTC,
tz=timezone.utc,
),
duration=timedelta(
seconds=span.duration.seconds,
Expand Down
8 changes: 5 additions & 3 deletions drift/core/tracing/adapters/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import gzip
import logging
from dataclasses import dataclass
from datetime import UTC, datetime, timedelta
from typing import TYPE_CHECKING, Any, override
from datetime import datetime, timedelta, timezone
from typing import TYPE_CHECKING, Any

from typing_extensions import override

from ...resilience import (
CircuitBreaker,
Expand Down Expand Up @@ -270,7 +272,7 @@ def _transform_span_to_protobuf(self, clean_span: CleanSpanData) -> Any:

timestamp = datetime.fromtimestamp(
clean_span.timestamp.seconds + clean_span.timestamp.nanos / 1_000_000_000,
tz=UTC,
tz=timezone.utc,
)

duration = timedelta(
Expand Down
8 changes: 5 additions & 3 deletions drift/core/tracing/adapters/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import logging
from collections import OrderedDict
from dataclasses import asdict
from datetime import UTC, datetime
from datetime import datetime, timezone
from pathlib import Path
from typing import TYPE_CHECKING, Any, override
from typing import TYPE_CHECKING, Any

from typing_extensions import override

from .base import ExportResult, SpanExportAdapter

Expand Down Expand Up @@ -63,7 +65,7 @@ def _get_or_create_file_path(self, trace_id: str) -> Path:
return self._trace_file_map[trace_id]

# Create new file with timestamp prefix
iso_timestamp = datetime.now(UTC).isoformat().replace(":", "-").replace(".", "-")
iso_timestamp = datetime.now(timezone.utc).isoformat().replace(":", "-").replace(".", "-")
file_path = self._base_directory / f"{iso_timestamp}_trace_{trace_id}.jsonl"
self._trace_file_map[trace_id] = file_path

Expand Down
4 changes: 3 additions & 1 deletion drift/core/tracing/adapters/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

from __future__ import annotations

from typing import TYPE_CHECKING, override
from typing import TYPE_CHECKING

from typing_extensions import override

from .base import ExportResult, SpanExportAdapter

Expand Down
4 changes: 2 additions & 2 deletions drift/instrumentation/datetime/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from __future__ import annotations

import logging
from datetime import UTC, datetime
from datetime import datetime, timezone

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -45,7 +45,7 @@ def start_time_travel(timestamp: datetime | str | int | float, trace_id: str | N

# Parse timestamp to datetime if needed
if isinstance(timestamp, (int, float)):
dt = datetime.fromtimestamp(timestamp, tz=UTC)
dt = datetime.fromtimestamp(timestamp, tz=timezone.utc)
elif isinstance(timestamp, str):
ts = timestamp.replace("Z", "+00:00")
dt = datetime.fromisoformat(ts)
Expand Down
4 changes: 3 additions & 1 deletion drift/instrumentation/django/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import logging
from types import ModuleType
from typing import TYPE_CHECKING, Any, override
from typing import TYPE_CHECKING, Any

from typing_extensions import override

logger = logging.getLogger(__name__)

Expand Down
4 changes: 3 additions & 1 deletion drift/instrumentation/fastapi/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from collections.abc import Callable
from functools import wraps
from types import ModuleType
from typing import TYPE_CHECKING, Any, override
from typing import TYPE_CHECKING, Any

from typing_extensions import override

logger = logging.getLogger(__name__)

Expand Down
4 changes: 3 additions & 1 deletion drift/instrumentation/flask/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import logging
from collections.abc import Iterable
from types import ModuleType
from typing import TYPE_CHECKING, Any, override
from typing import TYPE_CHECKING, Any

from typing_extensions import override

logger = logging.getLogger(__name__)

Expand Down
6 changes: 3 additions & 3 deletions drift/instrumentation/psycopg2/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import logging
import time
from types import ModuleType
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Union

if TYPE_CHECKING:
from psycopg2.extensions import cursor as BaseCursorType
from psycopg2.sql import Composable

QueryType = str | bytes | Composable
QueryType = Union[str, bytes, Composable]

from opentelemetry import trace
from opentelemetry.trace import SpanKind as OTelSpanKind
Expand Down Expand Up @@ -843,7 +843,7 @@ def _mock_execute_with_data(self, cursor: Any, mock_data: dict[str, Any]) -> Non
# If it's a dict cursor and we have description, convert rows to dicts
if is_dict_cursor and description_data:
column_names = [col["name"] for col in description_data]
mock_rows = [dict(zip(column_names, row, strict=True)) for row in mock_rows]
mock_rows = [dict(zip(column_names, row)) for row in mock_rows]
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated

cursor._mock_rows = mock_rows # pyright: ignore[reportAttributeAccessIssue]
cursor._mock_index = 0 # pyright: ignore[reportAttributeAccessIssue]
Expand Down
5 changes: 4 additions & 1 deletion drift/instrumentation/registry.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from __future__ import annotations

import importlib.abc
import importlib.machinery
import sys
from collections.abc import Callable, Sequence
from types import ModuleType
from typing import override

from typing_extensions import override

PatchFn = Callable[[ModuleType], None]

Expand Down
4 changes: 3 additions & 1 deletion drift/instrumentation/wsgi/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

import logging
from types import ModuleType
from typing import TYPE_CHECKING, Any, override
from typing import TYPE_CHECKING, Any

from typing_extensions import override

if TYPE_CHECKING:
from _typeshed.wsgi import WSGIApplication
Expand Down
13 changes: 9 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "tusk-drift-python-sdk"
version = "0.1.9"
description = "Python SDK for Tusk Drift instrumentation and replay"
readme = "README.md"
requires-python = ">=3.12"
requires-python = ">=3.9"
license = {text = "MIT"}
authors = [
{name = "Tusk", email = "support@usetusk.ai"}
Expand All @@ -18,7 +18,11 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Testing",
"Topic :: Software Development :: Libraries :: Python Modules",
]
Expand All @@ -33,12 +37,13 @@ dependencies = [
"opentelemetry-api>=1.20.0",
"opentelemetry-sdk>=1.20.0",
"time-machine>=2.10.0",
"typing_extensions>=4.4.0",
]

[project.optional-dependencies]
flask = ["Flask>=3.1.2"]
fastapi = ["fastapi>=0.115.6", "uvicorn>=0.34.2", "starlette<0.42.0"]
django = ["Django>=5.0"]
django = ["Django>=4.2"]
dev = [
"Flask>=3.1.2",
"fastapi>=0.115.6",
Expand Down Expand Up @@ -66,7 +71,7 @@ drift = ["py.typed"]
prerelease = "allow"

[tool.ruff]
target-version = "py312"
target-version = "py39"
line-length = 120

[tool.ruff.lint]
Expand Down Expand Up @@ -110,7 +115,7 @@ skip-magic-trailing-comma = false
line-ending = "auto"

[tool.ty.environment]
python-version = "3.12"
python-version = "3.9"

[tool.ty.src]
# Exclude e2e-tests directories from type checking
Expand Down
Loading